diff --git a/CHANGELOG.md b/CHANGELOG.md index 0656754..59bc61a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [v6.34.2-SNAPSHOT] - 2022-03-08 +## [v6.34.3-SNAPSHOT] - 2022-03-23 #### Enhancements +- [#23020] Reinforce the (ApplicationProfile-)Workspace-Explorer-App discovery - [#22923] Migrate to maven-portal-bom 3.7.0[-SNAPSHOT] ## [v6.34.1] - 2021-12-20 diff --git a/pom.xml b/pom.xml index 316b754..ca7d4a7 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.gcube.portlets.user workspace-tree-widget - 6.34.2-SNAPSHOT + 6.34.3-SNAPSHOT gCube Workspace Tree Widget gCube Workspace Tree Widget is a widget to navigate and interact with gCube Workspace diff --git a/src/main/java/org/gcube/portlets/user/workspace/server/reader/ApplicationProfileReader.java b/src/main/java/org/gcube/portlets/user/workspace/server/reader/ApplicationProfileReader.java index 856d2eb..6d3fd00 100644 --- a/src/main/java/org/gcube/portlets/user/workspace/server/reader/ApplicationProfileReader.java +++ b/src/main/java/org/gcube/portlets/user/workspace/server/reader/ApplicationProfileReader.java @@ -10,7 +10,8 @@ import javax.xml.parsers.DocumentBuilderFactory; import org.gcube.common.resources.gcore.utils.XPathHelper; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.portlets.user.workspace.server.util.WsUtil; +import org.gcube.common.scope.impl.ScopeBean; +import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.Query; import org.gcube.resources.discovery.client.queries.impl.QueryBox; @@ -19,12 +20,11 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.xml.sax.InputSource; - /** * The Class ApplicationProfileReader. * * @author Francesco Mangiacrapa francesco.mangiacrapa{@literal @}isti.cnr.it - * Sep 14, 2016 + * Sep 14, 2016 */ public class ApplicationProfileReader { @@ -48,12 +48,26 @@ public class ApplicationProfileReader { private String resourceName; private String appID; + public enum APPLICATION_PROFILE_ITEM { + + SCOPE("/Scope/text()"), URL("/URL/text()"); + + private String xPath; + + APPLICATION_PROFILE_ITEM(String xpath) { + this.xPath = xpath; + } + + public String getXPath() { + return xPath; + } + } /** * Instantiates a new application profile reader. * * @param resourceName the resource name - * @param appID the app id + * @param appID the app id * @throws Exception the exception */ public ApplicationProfileReader(String resourceName, String appID) throws Exception { @@ -64,150 +78,167 @@ public class ApplicationProfileReader { this.scope = ScopeProvider.instance.get(); } - /** - * this method looks up the generic resource among the ones available in the infrastructure using scope provider {@link ScopeProvider.instance.get()} - * resource name {@value #WORKSPACE_EXPLORER_APP_NAME} and secondaryType {@value #SECONDARY_TYPE} + * this method looks up the generic resource among the ones available in the + * infrastructure using scope provider {@link ScopeProvider.instance.get()} + * resource name {@value #WORKSPACE_EXPLORER_APP_NAME} and secondaryType + * {@value #SECONDARY_TYPE} * * @return the applicationProfile profile */ /** - * this method looks up the applicationProfile profile among the ones available in the infrastructure. + * this method looks up the applicationProfile profile among the ones available + * in the infrastructure. * * @return the applicationProfile profile */ public ApplicationProfile readProfileFromInfrastrucure() { - ApplicationProfile appProf = new ApplicationProfile(); - String queryString = getGcubeGenericQueryString(secondaryType, appID); - - try { - - if(scope==null) - throw new Exception("Scope is null, set scope into ScopeProvider"); - - logger.info("Trying to fetch ApplicationProfile in the scope: "+scope+", SecondaryType: " + secondaryType + ", AppId: " + appID); - Query q = new QueryBox(queryString); - DiscoveryClient client = client(); - List appProfile = client.submit(q); - - if (appProfile == null || appProfile.size() == 0) - throw new ApplicationProfileNotFoundException("ApplicationProfile with SecondaryType: " + secondaryType + ", AppId: " + appID +" is not registered in the scope: "+scope); - else { - String elem = appProfile.get(0); - DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement(); - XPathHelper helper = new XPathHelper(node); - - List currValue = null; - currValue = helper.evaluate(RESOURCE_PROFILE_NAME_TEXT); - if (currValue != null && currValue.size() > 0) { - appProf.setName(currValue.get(0)); - } - else throw new ApplicationProfileNotFoundException("Your applicationProfile NAME was not found in the profile"); - - currValue = helper.evaluate(RESOURCE_PROFILE_DESCRIPTION_TEXT); - if (currValue != null && currValue.size() > 0) { - appProf.setDescription(currValue.get(0)); - } - else logger.warn("No Description exists for " + appProf.getName()); - - currValue = helper.evaluate(RESOURCE_PROFILE_BODY_APP_ID_TEXT); - if (currValue != null && currValue.size() > 0) { - appProf.setKey(currValue.get(0)); - } - else throw new ApplicationProfileNotFoundException("Your applicationProfile ID n was not found in the profile, consider adding element in "); - - currValue = helper.evaluate(RESOURCE_PROFILE_BODY_THUMBNAIL_URL_TEXT); - if (currValue != null && currValue.size() > 0) { - appProf.setImageUrl(currValue.get(0)); - } - else{ - logger.warn("Null or empty element in " + appProf.getName()); - } - - currValue = helper.evaluate("/Resource/Profile/Body/EndPoint[Scope='"+scope.toString()+"']/Scope/text()"); - - if (currValue != null && currValue.size() > 0) { - List scopes = currValue; - String currentScope = scopes.get(0); - - //int slashCount = StringUtils.countMatches(currentScope, "/"); - - boolean isVRE = WsUtil.isVRE(currentScope); - - //if(slashCount < 3){//CASE not VRE - set session scope - if(!isVRE){//CASE not VRE - set session scope - logger.info("Scope "+ scope.toString() + " is not a VRE"); - - List listSessionScope = helper.evaluate("/Resource/Profile/Body/EndPoint[Scope='"+scope.toString()+"']/Sessionscope/text()"); //get session scope of i+1-mo scope - logger.debug("ListSessionScope is: "+ listSessionScope.toString()); - - if(listSessionScope!=null && listSessionScope.size()>0){ //If sessions scope exists - - logger.debug("setting session scope "+ listSessionScope.get(0)); - appProf.setScope(listSessionScope.get(0)); - } - else{ - logger.trace("session scope not exists setting scope "+ scope.toString()); - appProf.setScope(scope.toString()); - } - } - else{ //CASE IS A VRE - logger.info("Scope "+ scope.toString() + " is a VRE"); - appProf.setScope(scope.toString()); - - } - - //RETRIEVE URL - currValue = helper.evaluate("/Resource/Profile/Body/EndPoint[Scope='"+scope.toString()+"']/URL/text()"); - - if (currValue != null && currValue.size() > 0) { - String url = currValue.get(0); - // System.out.println("URL "+url); - if(url!=null) - appProf.setUrl(url); - else - throw new ApplicationProfileNotFoundException("Your applicationProfile URL was not found in the profile for Scope: " + scope.toString()); - } - else throw new ApplicationProfileNotFoundException("Your applicationProfile URL was not found in the profile for Scope: " + scope.toString()); - - } - else throw new ApplicationProfileNotFoundException("Your applicationProfile with scope "+scope.toString()+" was not found in the profile, consider adding element in "); - - logger.debug("returning: "+appProf); + ApplicationProfile appProf = new ApplicationProfile(); + String queryString = getGcubeGenericQueryString(secondaryType, appID); + + try { + + if (scope == null) + throw new Exception("Scope is null, set scope into ScopeProvider"); + + logger.info("Trying to fetch " + SECONDARY_TYPE + " in the scope: " + scope + ", SecondaryType: " + + secondaryType + ", AppId: " + appID); + Query q = new QueryBox(queryString); + DiscoveryClient client = client(); + List appProfile = client.submit(q); + + if (appProfile == null || appProfile.size() == 0) + throw new ApplicationProfileNotFoundException("Generic Resource with SecondaryType: " + secondaryType + + ", AppId: " + appID + " is not registered in the scope: " + scope); + else { + String elem = appProfile.get(0); + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement(); + XPathHelper helper = new XPathHelper(node); + + List currValue = null; + currValue = helper.evaluate(RESOURCE_PROFILE_NAME_TEXT); + if (currValue != null && currValue.size() > 0) { + appProf.setName(currValue.get(0)); + } else + throw new ApplicationProfileNotFoundException( + "Your " + SECONDARY_TYPE + " NAME was not found in the generic resource"); + + currValue = helper.evaluate(RESOURCE_PROFILE_DESCRIPTION_TEXT); + if (currValue != null && currValue.size() > 0) { + appProf.setDescription(currValue.get(0)); + } else + logger.warn("No Description exists for " + appProf.getName()); + + currValue = helper.evaluate(RESOURCE_PROFILE_BODY_APP_ID_TEXT); + if (currValue != null && currValue.size() > 0) { + appProf.setKey(currValue.get(0)); + } else + throw new ApplicationProfileNotFoundException("Your " + SECONDARY_TYPE + + " ID was not found in the generic resource, consider adding element in "); + + currValue = helper.evaluate(RESOURCE_PROFILE_BODY_THUMBNAIL_URL_TEXT); + if (currValue != null && currValue.size() > 0) { + appProf.setImageUrl(currValue.get(0)); + } else { + logger.warn("Null or empty element in of " + appProf.getName()); + } + + currValue = helper + .evaluate("/Resource/Profile/Body/EndPoint[Scope='" + scope.toString() + "']/Scope/text()"); + + appProf = readEndPointForScopeWithRetry(helper, scope, APPLICATION_PROFILE_ITEM.SCOPE, appProf); + + appProf = readEndPointForScopeWithRetry(helper, scope, APPLICATION_PROFILE_ITEM.URL, appProf); + + logger.debug("returning: " + appProf); return appProf; } } catch (Exception e) { logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e); return null; - }finally{ + } finally { /* - if(originalScope!=null && !originalScope.isEmpty()){ - ScopeProvider.instance.set(originalScope); - logger.info("scope provider setted to orginal scope: "+originalScope); - }else{ - ScopeProvider.instance.reset(); - logger.info("scope provider reset"); - }*/ + * if(originalScope!=null && !originalScope.isEmpty()){ + * ScopeProvider.instance.set(originalScope); + * logger.info("scope provider setted to orginal scope: "+originalScope); }else{ + * ScopeProvider.instance.reset(); logger.info("scope provider reset"); } + */ + } + + } + + private ApplicationProfile readEndPointForScopeWithRetry(XPathHelper helper, String scope, + APPLICATION_PROFILE_ITEM searchItem, ApplicationProfile appProf) + throws ApplicationProfileNotFoundException { + + String xPathToQuery = "/Resource/Profile/Body/EndPoint[Scope='" + scope + "']" + searchItem.getXPath(); + logger.debug("Identifying path with current scope: " + xPathToQuery); + List currValue = helper.evaluate(xPathToQuery); + + String queryResult = null; + + if (currValue == null || currValue.isEmpty()) { + logger.warn("In the " + SECONDARY_TYPE + " with name " + appProf.getName() + " the xPath " + xPathToQuery + + " returned with no results"); + + ScopeBean scopeBean = new ScopeBean(scope); + if (scopeBean.is(Type.VRE) || scopeBean.is(Type.VO)) { + String pathSeparator = "/"; + String[] components = scope.split(pathSeparator); + scope = pathSeparator + components[1]; + logger.info("The scope "+scopeBean.toString()+" is of kind " + Type.VRE + " or " + Type.VO + + ". Retry in action - going to search the default with the root scope: " + scope); + + xPathToQuery = "/Resource/Profile/Body/EndPoint[Scope='" + scope + "']" + searchItem.getXPath(); + logger.debug("Identifying path with root scope: " + xPathToQuery); + currValue = helper.evaluate(xPathToQuery); + + if (currValue == null || currValue.isEmpty()) { + logger.warn("In the " + SECONDARY_TYPE + " with name " + appProf.getName() + " the xPath " + xPathToQuery + + " returned with no results"); + } + + } } + if (currValue == null || currValue.isEmpty()) { + throw new ApplicationProfileNotFoundException("Your ApplicationProfile in the scope " + scope + + " have not an accessible, consider adding element in "); + } + + queryResult = currValue.get(0); + logger.info("The xPath: " + xPathToQuery + " returned with the result: " + queryResult); + + switch (searchItem) { + case SCOPE: + appProf.setScope(currValue.get(0)); + break; + case URL: + appProf.setUrl(currValue.get(0)); + break; + default: + break; + } + + return appProf; + } /** - * Gets the gcube generic query string. + * Gets the gcube generic xPath string. * * @param secondaryType the secondary type - * @param appId the app id - * @return the gcube generic query string + * @param appId the app id + * @return the gcube generic xPath string */ - public static String getGcubeGenericQueryString(String secondaryType, String appId){ + public static String getGcubeGenericQueryString(String secondaryType, String appId) { - return "for $profile in collection('/db/Profiles/GenericResource')//Resource " + - "where $profile/Profile/SecondaryType/string() eq '"+secondaryType+"' and $profile/Profile/Body/AppId/string() " + - " eq '" + appId + "'" + - "return $profile"; + return "for $profile in collection('/db/Profiles/GenericResource')//Resource " + + "where $profile/Profile/SecondaryType/string() eq '" + secondaryType + + "' and $profile/Profile/Body/AppId/string() " + " eq '" + appId + "'" + "return $profile"; } /** @@ -219,7 +250,6 @@ public class ApplicationProfileReader { return secondaryType; } - /** * Gets the scope. * @@ -238,8 +268,9 @@ public class ApplicationProfileReader { return resourceName; } - - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see java.lang.Object#toString() */ @Override diff --git a/src/test/java/org/gcube/portlets/user/workspace/TestProperties.java b/src/test/java/org/gcube/portlets/user/workspace/TestProperties.java index 945901f..e91fac5 100644 --- a/src/test/java/org/gcube/portlets/user/workspace/TestProperties.java +++ b/src/test/java/org/gcube/portlets/user/workspace/TestProperties.java @@ -1,12 +1,5 @@ package org.gcube.portlets.user.workspace; -import java.io.IOException; -import java.util.Properties; - -import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.portlets.user.workspace.server.GWTWorkspaceServiceImpl; -import org.gcube.portlets.user.workspace.server.reader.ApplicationProfileReader; - public class TestProperties { // public static void main(String[] args) { @@ -27,20 +20,6 @@ public class TestProperties { // } // // } - - public static void main(String[] args) { - - try { - ScopeProvider.instance.set("/d4science.research-infrastructures.eu/D4Research/Limnodata"); - ApplicationProfileReader ap = new ApplicationProfileReader("Workspace-Explorer-App", "org.gcube.portlets.user.workspaceexplorerapp.server.WorkspaceExplorerAppServiceImpl"); - System.out.println(ap.readProfileFromInfrastrucure()); - } - catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } } diff --git a/src/test/java/org/gcube/portlets/user/workspace/junit/WEA_AP_Reader.java b/src/test/java/org/gcube/portlets/user/workspace/junit/WEA_AP_Reader.java new file mode 100644 index 0000000..ff3dce6 --- /dev/null +++ b/src/test/java/org/gcube/portlets/user/workspace/junit/WEA_AP_Reader.java @@ -0,0 +1,28 @@ +package org.gcube.portlets.user.workspace.junit; + +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.portlets.user.workspace.server.reader.ApplicationProfileReader; +import org.junit.Test; + +public class WEA_AP_Reader { + + String scope = "/gcube/devsec/devVRE"; + String resourceName = "Workspace-Explorer-App"; + String appID = "org.gcube.portlets.user.workspaceexplorerapp.server.WorkspaceExplorerAppServiceImpl"; + + @Test + public void readAP() { + + try { + // ScopeProvider.instance.set("/d4science.research-infrastructures.eu/D4Research/Limnodata"); + ScopeProvider.instance.set(scope); + ApplicationProfileReader ap = new ApplicationProfileReader(resourceName, appID); + System.out.println("ApplicationProfile found: "+ap.readProfileFromInfrastrucure()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +}