/** * */ 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); if(scopeBean.is(Type.VRE)) return scopeBean.enclosingScope().toString(); else if (scopeBean.is(Type.VO)) return currentScope; else return null; } /** * 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 the scope is a root-vo scope, it will be added to the vosScope array 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; log.debug("checking resource "+resource.id()+" type: "+resource.type()); 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; } }