diff --git a/src/main/java/org/gcube/datatransfer/resolver/caches/LoadingMapOfDetachedVRE.java b/src/main/java/org/gcube/datatransfer/resolver/caches/LoadingMapOfDetachedVRE.java index 6d6e71d..a5474e5 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/caches/LoadingMapOfDetachedVRE.java +++ b/src/main/java/org/gcube/datatransfer/resolver/caches/LoadingMapOfDetachedVRE.java @@ -4,9 +4,11 @@ package org.gcube.datatransfer.resolver.caches; import java.util.Map; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datatransfer.resolver.init.UriResolverSmartGearManagerInit; import org.gcube.infrastructure.detachedres.detachedreslibrary.server.DetachedREsClient; @@ -14,6 +16,8 @@ import org.gcube.infrastructure.detachedres.detachedreslibrary.shared.re.Detache import org.gcube.infrastructure.detachedres.detachedreslibrary.shared.re.Gateway; import org.gcube.infrastructure.detachedres.detachedreslibrary.shared.re.VO; import org.gcube.infrastructure.detachedres.detachedreslibrary.shared.re.VRE; +import org.gcube.smartgears.ContextProvider; +import org.gcube.smartgears.context.application.ApplicationContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -81,10 +85,24 @@ public class LoadingMapOfDetachedVRE { */ private static void populateTheCache(){ + String authorizationToken = null; + try{ //Populating the cache by using the detachedres-library LOG.info("Trying to pre-populate the detached VREs cache with mapping (VRE Name, VRE Obj)"); ScopeProvider.instance.set(UriResolverSmartGearManagerInit.getRootContextScope()); + + authorizationToken = SecurityTokenProvider.instance.get(); + + if(authorizationToken==null) { + LOG.info("No token found into {} to instance the {}, so reading it from SG configurations", + SecurityTokenProvider.class.getSimpleName(), DetachedREsClient.class.getSimpleName()); + + authorizationToken = UriResolverSmartGearManagerInit.getRootTokenFromSGConfiguration(); + if(authorizationToken!=null) + SecurityTokenProvider.instance.set(authorizationToken); + } + DetachedREsClient detachedREsClient = new DetachedREsClient(); DetachedREs detachedREs = detachedREsClient.getDetachedREs(); @@ -134,7 +152,11 @@ public class LoadingMapOfDetachedVRE { }catch(Exception e){ //SILENT }finally{ - + if(authorizationToken!=null) { + LOG.info("resetting security token provider"); + SecurityTokenProvider.instance.reset(); + } + } } diff --git a/src/main/java/org/gcube/datatransfer/resolver/init/UriResolverSmartGearManagerInit.java b/src/main/java/org/gcube/datatransfer/resolver/init/UriResolverSmartGearManagerInit.java index aa8b8c8..cc37a89 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/init/UriResolverSmartGearManagerInit.java +++ b/src/main/java/org/gcube/datatransfer/resolver/init/UriResolverSmartGearManagerInit.java @@ -8,10 +8,12 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; +import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; @@ -22,6 +24,8 @@ import org.gcube.datatransfer.resolver.caches.LoadingMapOfScopeCache; import org.gcube.datatransfer.resolver.gis.property.ApplicationProfilePropertyReader; import org.gcube.datatransfer.resolver.gis.property.PropertyFileNotFoundException; import org.gcube.smartgears.ApplicationManager; +import org.gcube.smartgears.ContextProvider; +import org.gcube.smartgears.context.application.ApplicationContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -90,7 +94,7 @@ public class UriResolverSmartGearManagerInit implements ApplicationManager { //JUST ONCE AND TO BE SURE WITH THE ROOT SCOPE INITIALIZED if(initRootContextPerformed && gisViewerProfile!=null && geoExplorerProfile!=null){ log.info("Pre-Loading caches... using rootContextScope: "+rootContextScope); - + //init the caches new LoadingGeonetworkInstanceCache(); new LoadingGisViewerApplicationURLCache(); @@ -231,4 +235,30 @@ public class UriResolverSmartGearManagerInit implements ApplicationManager { public static void setRootContextScope(String rootContextScope) { UriResolverSmartGearManagerInit.rootContextScope = rootContextScope; } + + + /** + * Gets the root token from SG configurations. + * + * @return the root token from SG configurations + */ + public static String getRootTokenFromSGConfiguration() { + + try { + ApplicationContext ctx = ContextProvider.get(); + Set tokens = ctx.configuration().startTokens(); + for (String token : tokens) { + //I'm using the first token, + //it should be a token of root because of URI-Resolver works at root level + log.info("Token read from SG configuration is {}-MASKED-TOKEN",token.substring(0,10)); + return token; + } + log.warn("Token not found by reading the SG configurations!!! Returning null"); + return null; + } catch (Exception e) { + log.error("Error on reading the start tokens from SG configuration",e); + return null; + } + + } } diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java b/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java index c8a652d..5b95422 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/CatalogueResolver.java @@ -1,6 +1,9 @@ package org.gcube.datatransfer.resolver.services; +import java.net.URI; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ExecutionException; import javax.servlet.http.HttpServletRequest; @@ -20,15 +23,18 @@ import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; import org.gcube.datatransfer.resolver.ConstantsResolver; +import org.gcube.datatransfer.resolver.caches.LoadingMapOfDetachedVRE; import org.gcube.datatransfer.resolver.caches.LoadingMapOfScopeCache; import org.gcube.datatransfer.resolver.catalogue.CatalogueRequest; import org.gcube.datatransfer.resolver.catalogue.ItemCatalogueURLs; import org.gcube.datatransfer.resolver.catalogue.ResourceCatalogueCodes; +import org.gcube.datatransfer.resolver.catalogue.resource.CatalogueStaticConfigurations; import org.gcube.datatransfer.resolver.catalogue.resource.CkanCatalogueConfigurationsReader; import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueReference; import org.gcube.datatransfer.resolver.catalogue.resource.GetAllInfrastructureScopes; import org.gcube.datatransfer.resolver.services.error.ExceptionManager; import org.gcube.datatransfer.resolver.util.Util; +import org.gcube.infrastructure.detachedres.detachedreslibrary.shared.re.VRE; import org.gcube.smartgears.utils.InnerMethodName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,6 +55,7 @@ public class CatalogueResolver { private static Logger logger = LoggerFactory.getLogger(CatalogueResolver.class); private static String helpURI = "https://wiki.gcube-system.org/gcube/URI_Resolver#CATALOGUE_Resolver"; + private static enum SCOPE_STATUS {ACTIVE, DETACHED} /** * Resolve catalogue. @@ -184,11 +191,29 @@ public class CatalogueResolver { try { String entityContextValue = ResourceCatalogueCodes.valueOfCodeId(entityContext).getValue(); ScopeBean scopeBean = null; + SCOPE_STATUS scopeStatus = SCOPE_STATUS.ACTIVE; + VRE vreDetached = null; try{ scopeBean = LoadingMapOfScopeCache.get(scopeName); }catch(ExecutionException | InvalidCacheLoadException e){ - logger.error("Error on getting the fullscope from cache for scopeName "+scopeName, e); - throw ExceptionManager.wrongParameterException(req, "Error on getting full scope for the scope name '"+scopeName+"'. Is it registered as a valid Scope in the D4Science Infrastructure System?", CatalogueResolver.class, helpURI); + logger.error("Error on getting the fullscope from cache for scopeName {}. Tryng to load it from ",scopeName); + + boolean isScopeDetached = false; + try { + vreDetached = LoadingMapOfDetachedVRE.get(scopeName); + scopeBean = new ScopeBean(vreDetached.getScope()); + scopeStatus = SCOPE_STATUS.DETACHED; + logger.info("I loaded a valid VRE obj for scope name {}", scopeName); + isScopeDetached = true; + }catch (Exception e1) { + logger.warn("I was not able to load a detached VRE for vreName {}. Going to error for wrong scope",scopeName); + } + + //If is not a cas of scope detached, going to error for wrong scope + if(!isScopeDetached) { + logger.error("Error on getting the fullscope from cache for scopeName "+scopeName, e); + throw ExceptionManager.wrongParameterException(req, "Error on getting full scope for the scope name '"+scopeName+"'. Is it registered as a valid Scope in the D4Science Infrastructure System?", CatalogueResolver.class, helpURI); + } } String fullScope = scopeBean.toString(); @@ -203,8 +228,37 @@ public class CatalogueResolver { } ScopeProvider.instance.set(fullScope); - GatewayCKANCatalogueReference ckanCatalogueReference = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints(); + GatewayCKANCatalogueReference ckanCatalogueReference = null; + logger.info("Managing scope status: {}",scopeStatus); + + switch (scopeStatus) { + case DETACHED: + + String privatePortletURL = vreDetached.getCatalogPortletURL(); + //The private portlet URL + Map mapAccessURLToCatalogue = new HashMap(3); + mapAccessURLToCatalogue.put(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PRIVATE_VRE,privatePortletURL); + + //Building the gateway catalogue public URL from private VRE Portlet URL + URI toURL = new URI(privatePortletURL); + String publicURL = privatePortletURL.startsWith("https://")?"https://"+toURL.getHost():"http://"+toURL.getHost(); + //It returns the string "catalogue" + CatalogueStaticConfigurations staticConf = new CatalogueStaticConfigurations(); + //Replacing for example "ckan-bb" with "[PREFIXES-TO-CATALOGUE-URL]-bb" (e.g catalogue-bb) + String relativeURLWithCatalogueName = staticConf.buildRelativeURLToPublicCatalogueGateway(vreDetached.getCatalogUrl()); + String toGatewayPortletURL = String.format("%s/%s", publicURL, relativeURLWithCatalogueName); + mapAccessURLToCatalogue.put(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PUBLIC_GATEWAY,toGatewayPortletURL); + + ckanCatalogueReference = new GatewayCKANCatalogueReference(fullScope, vreDetached.getCatalogUrl(), mapAccessURLToCatalogue); + break; + case ACTIVE: + default: + + ckanCatalogueReference = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints(); + break; + } + logger.info("For scope "+fullScope+" loaded end points: "+ckanCatalogueReference); //IS THE PRODUCT PLUBLIC OR PRIVATE? diff --git a/src/test/java/CatalogueResolverTest.java b/src/test/java/CatalogueResolverTest.java index 123b132..66aaef4 100644 --- a/src/test/java/CatalogueResolverTest.java +++ b/src/test/java/CatalogueResolverTest.java @@ -1,6 +1,11 @@ +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datatransfer.resolver.catalogue.resource.CkanCatalogueConfigurationsReader; import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueReference; +import org.gcube.datatransfer.resolver.init.UriResolverSmartGearManagerInit; +import org.gcube.datatransfer.resolver.services.CatalogueResolver; +import org.junit.Before; +import org.junit.Test; /** @@ -12,18 +17,33 @@ import org.gcube.datatransfer.resolver.catalogue.resource.GatewayCKANCatalogueRe */ public class CatalogueResolverTest { + private static String entityName = "using_e-infrastructures_for_biodiversity_conservation"; + private static String entityContext = "ctlg"; + private static String vreName = "BlueBridgeProject"; + + private String rootContextScope = "/gcube"; + private String authorizationToken = ""; + + //@Before + public void init() { - /** - * The main method. - * - * @param args - * the arguments - */ - public static void main(String[] args) { + UriResolverSmartGearManagerInit.setRootContextScope(rootContextScope); + } + + + //@Test + public void testCatalogueResolver() { + SecurityTokenProvider.instance.set(authorizationToken); + CatalogueResolver catalogRes = new CatalogueResolver(); + catalogRes.resolveCatalogue(null, entityName, vreName, entityContext); + + } + + //@Test + public void testCatalogueLoadEndPoints() { try { - ScopeProvider.instance.set("/d4science.research-infrastructures.eu/gCubeApps/BiodiversityLab"); //ScopeProvider.instance.set("/d4science.research-infrastructures.eu"); GatewayCKANCatalogueReference ckanCatalogueReference = CkanCatalogueConfigurationsReader.loadCatalogueEndPoints(); System.out.println(ckanCatalogueReference.toString());