diff --git a/pom.xml b/pom.xml
index 2cd8fb5..2a36fe1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,6 +9,8 @@
distro
+
+
diff --git a/src/main/java/org/gcube/common/resources/gcore/ResourceMediator.java b/src/main/java/org/gcube/common/resources/gcore/ResourceMediator.java
index d9a61c0..d306766 100644
--- a/src/main/java/org/gcube/common/resources/gcore/ResourceMediator.java
+++ b/src/main/java/org/gcube/common/resources/gcore/ResourceMediator.java
@@ -1,6 +1,9 @@
package org.gcube.common.resources.gcore;
+import java.util.ArrayList;
+import java.util.List;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,4 +23,21 @@ public class ResourceMediator {
resource.scopes().remove(scope);
}
+ public static Resource cleanAllScopes(Resource resource){
+ log.debug("removing scopes from resource: "+resource.id());
+ List toRemove= new ArrayList();
+ int count=0;
+ for (String scope :resource.scopes()){
+ System.out.println("found scope "+scope+" ");
+ toRemove.add(scope);
+
+ }
+ for(String scope: toRemove){
+ log.debug("removing scope "+scope+" ");
+ resource.removeScope(scope);
+ count++;
+ }
+ log.debug("removed "+count+" scopes");
+ return resource;
+ }
}
diff --git a/src/main/java/org/gcube/informationsystem/publisher/RegistryPublisherImpl.java b/src/main/java/org/gcube/informationsystem/publisher/RegistryPublisherImpl.java
index fe00f3e..0a30ce5 100644
--- a/src/main/java/org/gcube/informationsystem/publisher/RegistryPublisherImpl.java
+++ b/src/main/java/org/gcube/informationsystem/publisher/RegistryPublisherImpl.java
@@ -1,6 +1,8 @@
package org.gcube.informationsystem.publisher;
import java.io.StringWriter;
+import java.util.Date;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
@@ -25,6 +27,7 @@ import org.gcube.informationsystem.publisher.stubs.registry.faults.InvalidResour
import org.gcube.informationsystem.publisher.stubs.registry.faults.ResourceNotAcceptedException;
import org.gcube.informationsystem.publisher.stubs.registry.faults.UpdateException;
import org.gcube.informationsystem.publisher.utils.RegistryStubs;
+import org.gcube.informationsystem.publisher.utils.Utils;
import org.gcube.informationsystem.publisher.utils.ValidationUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,7 +70,15 @@ public class RegistryPublisherImpl implements RegistryPublisher {
return res;
}
+ /**
+ * From version 1.3, during a create operation an exception is thrown only if it occurs in the VO where the creation is invoked.
+ * In the previous versions the exception was always thrown
+ * @param resource
+ * @param scopes
+ * @return
+ */
private < T extends Resource> T internalVosCreate(T resource, List scopes){
+ log.trace("internalVosCreate method");
String currentScope=ScopeProvider.instance.get();
ValidationUtils.valid("resource", resource);// helper that throws an IllegalArgumentException if resource are null
ValidationUtils.valid("scopes", scopes);// helper that throws an IllegalArgumentException if scopes are null
@@ -77,32 +88,44 @@ public class RegistryPublisherImpl implements RegistryPublisher {
log.debug("id generated: "+id);
ResourceMediator.setId(resource, id);
}
-
- HashSet vosScopes = new HashSet();
+ HashSet vosScopes = updateResourceScopes(resource);
+ // add the new scopes
for(String scope: scopes){
- ScopeBean scopeBean = new ScopeBean(scope);
- if(scopeBean.is(Type.VRE))
- vosScopes.add(scopeBean.enclosingScope().toString());
- else vosScopes.add(scope);
- log.debug("[VOCREATE] scope found {}",scope);
+ log.debug("[VOCREATE] new scope added {}",scope);
ResourceMediator.setScope(resource, scope);
}
+ // validating the resource
try {
Resources.validate(resource);
} catch (Exception e) {
log.error("the resource is not valid", e);
throw new IllegalArgumentException("the resource is not valid ", e.getCause());
}
-
try{
+
+ // checking the current scope: if the operation fails in the current VO it will give an exception, if it fails in another VO no exception will be given
+ String currentVO = Utils.getCurrentVO(currentScope);
+ if (currentVO != null){
+ RegistryStub stub = getRegistryStub();
+ createResource(resource, currentVO, stub);
+ vosScopes.remove(currentVO);
+ }
+ // update the resource for each VO
for (String voScope: vosScopes){
// if update is calling on create operation and the scope is not equal to create operation scope or if is a simple update operation, try to update it
log.trace("[VOCREATE] resource "+resource.id()+" update in scope {} with scopes {} ",voScope, resource.scopes().asCollection());
ScopeProvider.instance.set(voScope);
- //retrieve registry stub
- RegistryStub stub = getRegistryStub();
- createResource(resource, voScope, stub);
+ // 20190902: added the try/catch inside the for in order to update the scope in all the reachable VOs and no stop the update if a VO is not reachable
+ try{
+ //retrieve registry stub
+ RegistryStub stub = getRegistryStub();
+ createResource(resource, voScope, stub);
+ }catch(Exception e){
+ log.error("resource update problem on scope: "+voScope+ " try the next scope if any");
+ }finally{
+ ScopeProvider.instance.set(currentScope);
+ }
}
}finally{
ScopeProvider.instance.set(currentScope);
@@ -130,15 +153,6 @@ public class RegistryPublisherImpl implements RegistryPublisher {
ResourceMediator.setScope(resource, scope);
// check if the scope is compatible with the scopes defined in the resources
ValidatorProvider.getValidator(resource).checkScopeCompatibility(resource, Arrays.asList(scope));
- // add enclosing scopes to the resource with filtering on GenericResource, RunningIstance, and Service resources
- String type=resource.type().toString();
-
- /*
- if((!type.equalsIgnoreCase("GenericResource")) && (!(type.equalsIgnoreCase("RunningInstance"))) && (!(type.equalsIgnoreCase("Service")))){
- ValidationUtils.addEnclosingScopesOnResource(resource, scope);
- }else{
- log.debug(" Resource type: "+type+": for this type of resource there isn't scope promotion");
- }*/
try {
Resources.validate(resource);
} catch (Exception e) {
@@ -210,28 +224,31 @@ public class RegistryPublisherImpl implements RegistryPublisher {
log.error("the resource is not valid", e);
throw new IllegalArgumentException("the resource is not valid", e);
}
-
- HashSet vosScopes = new HashSet();
- int tries=0;
- for(String scope: resource.scopes().asCollection()){
- ScopeBean scopeBean = new ScopeBean(scope);
- if(scopeBean.is(Type.VRE))
- vosScopes.add(scopeBean.enclosingScope().toString());
- else vosScopes.add(scope);
- log.debug("[VOUPDATE] scope found {}",scope);
- }
-
- log.debug("[VOUPDATE] scopes in resources {}",resource.scopes().asCollection());
-
+ HashSet vosScopes = Utils.getInternalVOScopes(resource);
try{
+ // checking the current scope: if the operation fail in the current VO it will give an exception, if it fails in another VO no exception will be given
+ String currentVO = Utils.getCurrentVO(currentScope);
+ if (currentVO != null){
+ ScopeProvider.instance.set(currentVO);
+ registryUpdate(resource, 0);
+ vosScopes.remove(currentVO);
+ }
+ int tries=0;
for (String voScope: vosScopes){
log.debug("[VOUPDATE] check update operation on scope {} ",voScope);
// if update is calling on create operation and the scope is not equal to create operation scope or if is a simple update operation, try to update it
if((scopeCreated == null) || ((scopeCreated!=null) && (!scopeCreated.equals(voScope)))){
log.trace("[VOUPDATE] resource "+resource.id()+" update in scope {} with scopes {} ",voScope, resource.scopes().asCollection());
- ScopeProvider.instance.set(voScope);
- registryUpdate(resource, tries);
- tries=0;
+ try{
+ ScopeProvider.instance.set(voScope);
+ registryUpdate(resource, tries);
+ tries=0;
+ }catch(Exception e){
+ log.error("resource update problem on scope: "+voScope+ " try the next scope if any");
+ }finally{
+ scopeCreated=null;
+ ScopeProvider.instance.set(currentScope);
+ }
}else{
log.trace("[VOUPDATE] skip updating on scope {}",scopeCreated);
}
@@ -258,6 +275,9 @@ public class RegistryPublisherImpl implements RegistryPublisher {
ValidationUtils.valid("resource", resource);// helper that throws an IllegalArgumentException if resource are null
ValidationUtils.valid("scopes", currentScope);// helper that throws an IllegalArgumentException if scopes are null
validateScope(resource);
+// the returned voScopes list is not used yet. it should be used if the update/remove operation will be done at VO level
+// HashSet vosScopes = updateResourceScopes(resource);
+ updateResourceScopes(resource);
try {
Resources.validate(resource);
} catch (Exception e) {
@@ -325,10 +345,12 @@ public class RegistryPublisherImpl implements RegistryPublisher {
*/
private void updateResourceRemoveOperation(T resource, String currentScope) {
if(!isRemoveNeeded(resource, currentScope)){
- updateResource(resource, currentScope);
+// updateResource(resource, currentScope);
+// v 1.3 (20190902) try to update the resource just at vo level
+ vosUpdate(resource);
}else{ // remove the profile from IC
log.info("the resource have only the "+currentScope+" scope defined. Remove the resource "+resource.id()+" from IC");
- // if the resource not have any scope, the resource will be removed
+ // if the resource hasn't any scope, the resource will be removed
try {
log.debug("remove from IS scope "+currentScope);
registry.getStubs().remove(resource.id(), resource.type().toString());
@@ -336,16 +358,6 @@ public class RegistryPublisherImpl implements RegistryPublisher {
log.error("the resource can't be removed ", e);
throw new IllegalArgumentException("the resource can't be removed from scope "+currentScope, e);
}
- // ScopeBean currentScopeBean=new ScopeBean(currentScope);
- // if(currentScopeBean.is(Type.VRE)){
- // log.debug("remove from resource scope "+currentScopeBean.enclosingScope().toString());
- // ResourceMediator.removeScope(resource, currentScopeBean.enclosingScope().toString());
- // log.debug("remove from resource scope "+currentScope);
- // ResourceMediator.removeScope(resource, currentScope);
- // }else if(currentScopeBean.is(Type.VO)){
- // log.debug("remove from resource scope "+currentScope);
- // ResourceMediator.removeScope(resource, currentScope);
- // }
updateResource(resource, currentScope);
}
}
@@ -393,15 +405,57 @@ public class RegistryPublisherImpl implements RegistryPublisher {
private void updateResource(T resource, String currentScope) {
ScopeGroup scopes=resource.scopes();
int tries=0;
- for(Iterator it=scopes.iterator();it.hasNext();){
- String scope=(String)it.next();
- ScopeProvider.instance.set(scope);
- registryUpdate(resource, tries);
-
+ try{
+ for(Iterator it=scopes.iterator();it.hasNext();){
+ String scope=(String)it.next();
+ ScopeProvider.instance.set(scope);
+ registryUpdate(resource, tries);
+ }
+ }finally{
+ // reset the scope
+ ScopeProvider.instance.set(currentScope);
+ }
+ }
+
+
+ private void updateResourceVOLevel(T resource, List voScopes, String currentScope) {
+ int tries=0;
+ try{
+ for(String scope: voScopes){
+ ScopeProvider.instance.set(scope);
+ registryUpdate(resource, tries);
+ }
+ }finally{
+ // reset the scope
+ ScopeProvider.instance.set(currentScope);
}
- // reset the scope
- ScopeProvider.instance.set(currentScope);
}
-
+ private HashSet updateResourceScopes(T resource) {
+ HashSet vosScopes = Utils.getInternalVOScopes(resource);
+ //extract the scopes from the more recent resource found at vo level
+ List latestScopesFound= Utils.setLatestInternalScopes(resource, vosScopes);
+ log.debug("latest scope found are "+latestScopesFound);
+ if((latestScopesFound == null) || (latestScopesFound.isEmpty())){
+ // if it is a new resource the latestScopesFound should be null, in this case the more recent scopes are the new scopes
+ latestScopesFound= new ArrayList(vosScopes.size());
+ for (String scope: vosScopes){
+ latestScopesFound.add(scope);
+ }
+ }else{
+ // remove all the scope from the resource
+ ResourceMediator.cleanAllScopes(resource);
+ // add the scope found on the resource more recent at vo level
+ for (String scope: latestScopesFound){
+ log.debug("[VOCREATE] scope added {}",scope);
+ ResourceMediator.setScope(resource, scope);
+ ScopeBean scopeBean = new ScopeBean(scope);
+ // check if the scope was already present inside the resource, if not, it will be added to the voScopes
+ if((!scopeBean.is(Type.VRE)) && (!vosScopes.contains(scope))){
+ vosScopes.add(scope);
+ }
+ }
+ }
+ return vosScopes;
+ }
}
diff --git a/src/main/java/org/gcube/informationsystem/publisher/utils/Utils.java b/src/main/java/org/gcube/informationsystem/publisher/utils/Utils.java
new file mode 100644
index 0000000..ea63116
--- /dev/null
+++ b/src/main/java/org/gcube/informationsystem/publisher/utils/Utils.java
@@ -0,0 +1,211 @@
+/**
+ *
+ */
+package org.gcube.informationsystem.publisher.utils;
+
+
+import static org.gcube.resources.discovery.icclient.ICFactory.client;
+import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
+import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import org.gcube.common.resources.gcore.GCoreEndpoint;
+import org.gcube.common.resources.gcore.GenericResource;
+import org.gcube.common.resources.gcore.HostingNode;
+import org.gcube.common.resources.gcore.Resource;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.common.scope.impl.ScopeBean;
+import org.gcube.common.scope.impl.ScopeBean.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.gcube.resources.discovery.client.api.DiscoveryClient;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+import org.gcube.resources.discovery.client.queries.impl.XQuery;
+
+/**
+ * @author Roberto Cirillo (ISTI-CNR) 2019
+ *
+ */
+public class Utils {
+
+ private static final Logger log = LoggerFactory.getLogger(Utils.class);
+
+ /**
+ * Given a scope, returns the related VO. If it is a root-VO scope, returns null
+ * @param currentScope
+ * @return
+ */
+ public static String getCurrentVO(String currentScope) {
+ ScopeBean scopeBean = new ScopeBean(currentScope);
+ String currentVO=null;
+ if(scopeBean.is(Type.VRE))
+ currentVO=scopeBean.enclosingScope().toString();
+ else if (scopeBean.is(Type.VO))
+ currentVO= currentScope;
+ else return null;
+ return currentVO;
+ }
+
+ /**
+ * Returns all the VOs involved. If just a VRE scope is present in the resource, the enclosed VO will be returned.
+ * if present, the root-VO is returned yet
+ * @param resource the gCube resource
+ * @return the VO scopes
+ */
+ public static HashSet getInternalVOScopes(T resource) {
+ HashSet vosScopes = new HashSet();
+ log.debug("checking and collect the internal VO scopes");
+ for(String scope: resource.scopes()){
+ log.debug("processing scope: "+scope);
+ ScopeBean scopeBean = new ScopeBean(scope);
+ if(scopeBean.is(Type.VRE))
+ vosScopes.add(scopeBean.enclosingScope().toString());
+// else if(scopeBean.is(Type.VO))
+ vosScopes.add(scope);
+ }
+ return vosScopes;
+ }
+
+ public static GenericResource getGenericResourceByID(String id, String latestVO) {
+ List resources;
+ String currentScope= ScopeProvider.instance.get();
+ try{
+ ScopeProvider.instance.set(latestVO);
+ SimpleQuery query = queryFor(GenericResource.class);
+ query.addCondition("$resource/ID/text() eq '"+id+"'");
+ DiscoveryClient client = clientFor(GenericResource.class);
+ resources = client.submit(query);
+ }finally{
+ ScopeProvider.instance.set(currentScope);
+ }
+ if (( resources !=null) && (!resources.isEmpty()))
+ return resources.get(0);
+ else{
+ log.info(" No resource found with id "+id+" in scope "+latestVO);
+ return null;
+ }
+ }
+
+ public static ServiceEndpoint getServiceEndpointByID(String id, String latestVO) {
+ List resources;
+ String currentScope= ScopeProvider.instance.get();
+ try{
+ ScopeProvider.instance.set(latestVO);
+ SimpleQuery query = queryFor(ServiceEndpoint.class);
+ query.addCondition("$resource/ID/text() eq '"+id+"'");
+ DiscoveryClient client = clientFor(ServiceEndpoint.class);
+ resources = client.submit(query);
+ }finally{
+ ScopeProvider.instance.set(currentScope);
+ }
+ if (( resources !=null) && (!resources.isEmpty()))
+ return resources.get(0);
+ else{
+ log.info(" No resource found with id "+id+" in scope "+latestVO);
+ return null;
+ }
+ }
+
+ public static List getTimestamps(T resource) {
+ XQuery query = getSpecificXQuery(resource);
+ query.addCondition("$resource/ID/text() eq '"+resource.id()+"'");
+ query.setResult("$resource/../../../../Document/LastUpdateMs/text()");
+ DiscoveryClient client = client();
+ List timestamps= client.submit(query);
+ return timestamps;
+ }
+
+ public static XQuery getSpecificXQuery(T resource) {
+ XQuery query = null;
+ if(resource.type().toString().equalsIgnoreCase("RuntimeResource")){
+ query = queryFor(ServiceEndpoint.class);
+ }else if(resource.type().toString().equalsIgnoreCase("GenericResource")){
+ query = queryFor(GenericResource.class);
+ }else if(resource.type().toString().equalsIgnoreCase("RunningInstance")){
+ query = queryFor(GCoreEndpoint.class);
+ }else if(resource.type().toString().equalsIgnoreCase("GHN")){
+ query = queryFor(HostingNode.class);
+ }else{
+ throw new RuntimeException("The following resource type is not managed: "+resource);
+ }
+ return query;
+ }
+
+
+ /**
+ * Returns the scope list found on the more recent resource (with the same id) found at VO level
+ * @param resource
+ * @param vosScopes
+ * @return
+ */
+ public static < T extends Resource> List setLatestInternalScopes( T resource, HashSet vosScopes){
+ log.trace("setLatestInternalScopes method, voscopes "+vosScopes+", resource id: "+resource.id());
+ String latestVO= getMoreRecentResourceVO(resource, vosScopes);
+ if (latestVO != null)
+ return extractInternalScopes(resource, latestVO);
+ else return null;
+ }
+
+
+ private static List extractInternalScopes(T resource, String latestVO) {
+ T extractedResource=null;
+ if(resource.type().toString().equalsIgnoreCase("RuntimeResource")){
+ extractedResource= (T)getServiceEndpointByID(resource.id(), latestVO);
+ }else if(resource.type().toString().equalsIgnoreCase("GenericResource")){
+ extractedResource = (T)getGenericResourceByID(resource.id(), latestVO);
+ }else{
+ throw new RuntimeException("The following resource type is not managed: "+resource);
+ }
+ if(extractedResource.scopes().size() > 0){
+ List scopesExtracted = new ArrayList (extractedResource.scopes().size());
+ for(String scope: extractedResource.scopes())
+ scopesExtracted.add(scope);
+ return scopesExtracted;
+ }
+ return null;
+ }
+
+
+
+ /**
+ * Returns the VO where the resource is the more recent resource found in the VOs
+ * @param resource
+ * @param vosScopes
+ * @return
+ */
+ private static < T extends Resource> String getMoreRecentResourceVO(T resource, HashSet vosScopes){
+ String currentScope= ScopeProvider.instance.get();
+ long timestamp=0;
+ long latestTimestamp=0;
+ String latestVO=null;
+ try{
+ for (String voScope: vosScopes){
+ ScopeProvider.instance.set(voScope);
+ log.debug("checking scope in "+voScope);
+ List timestamps = Utils.getTimestamps(resource);
+ if (!timestamps.isEmpty()){
+ timestamp=Long.parseLong(timestamps.get(0).toString());
+ log.debug("checking "+voScope+" timestamp: "+timestamp+", with the more recent timestamp: "+latestTimestamp);
+ if ( timestamp > latestTimestamp){
+ latestTimestamp=timestamp;
+ latestVO=voScope;
+ log.debug("new timestamp is "+timestamp);
+ }
+ }
+ }
+ }finally{
+ // reset scope
+ ScopeProvider.instance.set(currentScope);
+ }
+ log.debug("the vo with latest timestamp is " +latestVO);
+ log.debug("timestamp is " +latestTimestamp);
+ return latestVO;
+ }
+
+
+}
diff --git a/src/main/java/org/gcube/informationsystem/publisher/utils/ValidationUtils.java b/src/main/java/org/gcube/informationsystem/publisher/utils/ValidationUtils.java
index c079ba2..0310951 100644
--- a/src/main/java/org/gcube/informationsystem/publisher/utils/ValidationUtils.java
+++ b/src/main/java/org/gcube/informationsystem/publisher/utils/ValidationUtils.java
@@ -1,13 +1,29 @@
package org.gcube.informationsystem.publisher.utils;
-import java.util.Iterator;
+import static org.gcube.resources.discovery.icclient.ICFactory.client;
+import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
+import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.gcube.common.resources.gcore.GCoreEndpoint;
+import org.gcube.common.resources.gcore.GenericResource;
+import org.gcube.common.resources.gcore.HostingNode;
import org.gcube.common.resources.gcore.Resource;
import org.gcube.common.resources.gcore.ResourceMediator;
import org.gcube.common.resources.gcore.ScopeGroup;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.informationsystem.publisher.RegistryPublisher;
+import org.gcube.resources.discovery.client.api.DiscoveryClient;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+import org.gcube.resources.discovery.client.queries.impl.XQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -70,11 +86,11 @@ public class ValidationUtils {
}else if(new ScopeBean(scope).is(Type.VO)){
log.debug(" "+scope+" is a VO scope");
if(anotherSonVREOnResource(resource, scope)){
- return false; //throw new IllegalArgumentException("the resource "+resource.id()+" have another scope defined in the same VO. The VO is "+scope);
+ throw new IllegalArgumentException("the resource "+resource.id()+" have another scope defined in the same VO. The VO is "+scope);
}else return true;
}else{ // is a INFRA scope
if(anotherInfraScopeOnResource(resource, scope)){
- return false;//throw new IllegalArgumentException("the resource "+resource.id()+" have another scope defined in the same INFRA. The INFRA is "+scope);
+ throw new IllegalArgumentException("the resource "+resource.id()+" have another scope defined in the same INFRA. The INFRA is "+scope);
}else return true;
}
}
@@ -136,6 +152,179 @@ public class ValidationUtils {
return false;
}
+// /**
+// * Given a scope, returns the related VO. If it is a root-VO scope, returns null
+// * @param currentScope
+// * @return
+// */
+// public static String getCurrentVO(String currentScope) {
+// ScopeBean scopeBean = new ScopeBean(currentScope);
+// String currentVO=null;
+// if(scopeBean.is(Type.VRE))
+// currentVO=scopeBean.enclosingScope().toString();
+// else if (scopeBean.is(Type.VO))
+// currentVO= currentScope;
+// else return null;
+// return currentVO;
+// }
+//
+// /**
+// * Returns all the VOs involved. If just a VRE scope is present in the resource, the enclosed VO will be returned.
+// * if present, the root-VO is returned yet
+// * @param resource the gCube resource
+// * @return the VO scopes
+// */
+// public static HashSet getInternalVOScopes(T resource) {
+// HashSet vosScopes = new HashSet();
+// log.debug("checking and collect the internal VO scopes");
+// for(String scope: resource.scopes()){
+// log.debug("processing scope: "+scope);
+// ScopeBean scopeBean = new ScopeBean(scope);
+// if(scopeBean.is(Type.VRE))
+// vosScopes.add(scopeBean.enclosingScope().toString());
+//// else if(scopeBean.is(Type.VO))
+// vosScopes.add(scope);
+// }
+// return vosScopes;
+// }
+//
+// public static GenericResource getGenericResourceByID(String id, String latestVO) {
+// List resources;
+// String currentScope= ScopeProvider.instance.get();
+// try{
+// ScopeProvider.instance.set(latestVO);
+// SimpleQuery query = queryFor(GenericResource.class);
+// query.addCondition("$resource/ID/text() eq '"+id+"'");
+// DiscoveryClient client = clientFor(GenericResource.class);
+// resources = client.submit(query);
+// }finally{
+// ScopeProvider.instance.set(currentScope);
+// }
+// if (( resources !=null) && (!resources.isEmpty()))
+// return resources.get(0);
+// else{
+// log.info(" No resource found with id "+id+" in scope "+latestVO);
+// return null;
+// }
+// }
+//
+// public static ServiceEndpoint getServiceEndpointByID(String id, String latestVO) {
+// List resources;
+// String currentScope= ScopeProvider.instance.get();
+// try{
+// ScopeProvider.instance.set(latestVO);
+// SimpleQuery query = queryFor(ServiceEndpoint.class);
+// query.addCondition("$resource/ID/text() eq '"+id+"'");
+// DiscoveryClient client = clientFor(ServiceEndpoint.class);
+// resources = client.submit(query);
+// }finally{
+// ScopeProvider.instance.set(currentScope);
+// }
+// if (( resources !=null) && (!resources.isEmpty()))
+// return resources.get(0);
+// else{
+// log.info(" No resource found with id "+id+" in scope "+latestVO);
+// return null;
+// }
+// }
+//
+// public static List getTimestamps(T resource) {
+// XQuery query = getSpecificXQuery(resource);
+// query.addCondition("$resource/ID/text() eq '"+resource.id()+"'");
+// query.setResult("$resource/../../../../Document/LastUpdateMs/text()");
+// DiscoveryClient client = client();
+// List timestamps= client.submit(query);
+// return timestamps;
+// }
+//
+// public static XQuery getSpecificXQuery(T resource) {
+// XQuery query = null;
+// if(resource.type().toString().equalsIgnoreCase("RuntimeResource")){
+// query = queryFor(ServiceEndpoint.class);
+// }else if(resource.type().toString().equalsIgnoreCase("GenericResource")){
+// query = queryFor(GenericResource.class);
+// }else if(resource.type().toString().equalsIgnoreCase("RunningInstance")){
+// query = queryFor(GCoreEndpoint.class);
+// }else if(resource.type().toString().equalsIgnoreCase("GHN")){
+// query = queryFor(HostingNode.class);
+// }else{
+// throw new RuntimeException("The following resource type is not managed: "+resource);
+// }
+// return query;
+// }
+//
+//
+// /**
+// * Returns the scope list found on the more recent resource (with the same id) found at VO level
+// * @param resource
+// * @param vosScopes
+// * @return
+// */
+// public static < T extends Resource> List setLatestInternalScopes( T resource, HashSet vosScopes){
+// log.trace("setLatestInternalScopes method, voscopes "+vosScopes+", resource id: "+resource.id());
+// String latestVO= getMoreRecentResourceVO(resource, vosScopes);
+// if (latestVO != null)
+// return extractInternalScopes(resource, latestVO);
+// else return null;
+// }
+//
+//
+// private static List extractInternalScopes(T resource, String latestVO) {
+// T extractedResource=null;
+// if(resource.type().toString().equalsIgnoreCase("RuntimeResource")){
+// extractedResource= (T)ValidationUtils.getServiceEndpointByID(resource.id(), latestVO);
+// }else if(resource.type().toString().equalsIgnoreCase("GenericResource")){
+// extractedResource = (T)ValidationUtils.getGenericResourceByID(resource.id(), latestVO);
+// }else{
+// throw new RuntimeException("The following resource type is not managed: "+resource);
+// }
+// if(extractedResource.scopes().size() > 0){
+// List scopesExtracted = new ArrayList (extractedResource.scopes().size());
+// for(String scope: extractedResource.scopes())
+// scopesExtracted.add(scope);
+// return scopesExtracted;
+// }
+// return null;
+// }
+//
+//
+//
+// /**
+// * Returns the VO where the resource is the more recent resource found in the VOs
+// * @param resource
+// * @param vosScopes
+// * @return
+// */
+// private static < T extends Resource> String getMoreRecentResourceVO(T resource, HashSet vosScopes){
+// String currentScope= ScopeProvider.instance.get();
+// long timestamp=0;
+// long latestTimestamp=0;
+// String latestVO=null;
+// try{
+// for (String voScope: vosScopes){
+// ScopeProvider.instance.set(voScope);
+// log.debug("checking scope in "+voScope);
+// List timestamps = ValidationUtils.getTimestamps(resource);
+// if (!timestamps.isEmpty()){
+// timestamp=Long.parseLong(timestamps.get(0).toString());
+// log.debug("checking "+voScope+" timestamp: "+timestamp+", with the more recent timestamp: "+latestTimestamp);
+// Date date = new Date(timestamp);
+// log.debug(voScope+" timestamp conversion: "+date);
+// if ( timestamp > latestTimestamp){
+// latestTimestamp=timestamp;
+// latestVO=voScope;
+// log.debug("new timestamp is "+timestamp+ " date: "+date);
+// }
+// }
+// }
+// }finally{
+// // reset scope
+// ScopeProvider.instance.set(currentScope);
+// }
+// log.debug("the vo with latest timestamp is " +latestVO);
+// log.debug("timestamp is " +latestTimestamp);
+// return latestVO;
+// }
}