From d59786d4157f8c4c3ef859fff5ab2d7ac7764096 Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Thu, 12 Sep 2019 17:58:39 +0200 Subject: [PATCH] Removed the dependency from ckan-util-library --- pom.xml | 9 + .../org/gcube/gcat/oldutils/Validator.java | 16 +- .../org/gcube/gcat/persistence/ckan/CKAN.java | 18 +- .../gcat/persistence/ckan/CKANGroup.java | 29 +++ .../gcat/persistence/ckan/CKANInstance.java | 186 ++++++++++++++++++ .../gcat/persistence/ckan/CKANUtility.java | 19 +- .../org/gcube/gcat/social/SocialPost.java | 10 +- .../org/gcube/gcat/utils/URIResolver.java | 11 +- 8 files changed, 239 insertions(+), 59 deletions(-) create mode 100644 src/main/java/org/gcube/gcat/persistence/ckan/CKANInstance.java diff --git a/pom.xml b/pom.xml index f2eb65e..18c4dc9 100644 --- a/pom.xml +++ b/pom.xml @@ -87,11 +87,15 @@ + + + org.glassfish.jersey.containers jersey-container-servlet @@ -206,6 +210,11 @@ commons-lang 2.3 + + commons-io + commons-io + 2.6 + diff --git a/src/main/java/org/gcube/gcat/oldutils/Validator.java b/src/main/java/org/gcube/gcat/oldutils/Validator.java index abe6728..360a1fc 100644 --- a/src/main/java/org/gcube/gcat/oldutils/Validator.java +++ b/src/main/java/org/gcube/gcat/oldutils/Validator.java @@ -18,14 +18,12 @@ import javax.ws.rs.core.Response.Status; import org.apache.commons.lang.math.NumberUtils; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.DataType; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataField; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataFormat; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataGrouping; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataTagging; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.NamespaceCategory; -import org.gcube.gcat.persistence.ckan.CKAN; import org.gcube.gcat.persistence.ckan.CKANGroup; import org.gcube.gcat.persistence.ckan.CKANPackage; import org.gcube.gcat.persistence.ckan.CKANUser; @@ -41,8 +39,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import eu.trentorise.opendata.jackan.model.CkanGroup; - /** * Validate creation item requests utilities. * @author Costantino Perciante (ISTI - CNR) @@ -615,15 +611,9 @@ public class Validator { * @throws Exception */ public static List getGroupHierarchyNames(String groupName) throws Exception { - List toReturn = new ArrayList(); - String apiKey = CKANUtility.getApiKey(); - List ckanGroups = CKAN.getCatalogue().getParentGroups(groupName, apiKey); - if(ckanGroups != null && !ckanGroups.isEmpty()) { - for(CkanGroup ckanGroup : ckanGroups) { - toReturn.add(ckanGroup.getName()); - } - } - return toReturn; + CKANGroup ckanGroup = new CKANGroup(); + ckanGroup.setName(groupName); + return ckanGroup.getGroups(); } } diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java index 880e2be..01c2917 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKAN.java @@ -15,9 +15,6 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.UriInfo; import org.gcube.common.gxhttp.request.GXHTTPStringRequest; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory; -import org.gcube.gcat.utils.ContextUtility; import org.gcube.gcat.utils.HTTPUtility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,7 +67,6 @@ public abstract class CKAN { protected String PURGE; protected final ObjectMapper mapper; - protected final DataCatalogue dataCatalogue; protected String name; protected String apiKey; @@ -119,7 +115,6 @@ public abstract class CKAN { protected CKAN() { try { this.mapper = new ObjectMapper(); - this.dataCatalogue = getCatalogue(); this.nameRegex = CKAN.NAME_REGEX; } catch(Exception e) { throw new InternalServerErrorException(e); @@ -134,17 +129,6 @@ public abstract class CKAN { } } - /** - * Retrieve an instance of the library for the current scope - * @return - * @throws Exception - */ - public static DataCatalogue getCatalogue() throws Exception { - String context = ContextUtility.getCurrentContext(); - logger.debug("Discovering ckan instance in context {}", context); - return DataCatalogueFactory.getFactory().getUtilsPerScope(context); - } - /** * Validate the CKAN response and return the * @param json @@ -246,7 +230,7 @@ public abstract class CKAN { protected GXHTTPStringRequest getGXHTTPStringRequest(String path, boolean post) throws UnsupportedEncodingException { - String catalogueURL = dataCatalogue.getCatalogueUrl(); + String catalogueURL = CKANInstance.getInstance().getCKANURL(); GXHTTPStringRequest gxhttpStringRequest = HTTPUtility.createGXHTTPStringRequest(catalogueURL, path, post); gxhttpStringRequest.isExternalCall(true); diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKANGroup.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKANGroup.java index e5d9c36..e6c3ebc 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKANGroup.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKANGroup.java @@ -1,8 +1,14 @@ package org.gcube.gcat.persistence.ckan; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.WebApplicationException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; /** @@ -25,6 +31,9 @@ public class CKANGroup extends CKAN { // see http://docs.ckan.org/en/latest/api/#ckan.logic.action.delete.group_purge public static final String GROUP_PURGE = CKAN.CKAN_API_PATH + "group_purge"; + public static final String GROUPS_KEY = "groups"; + + public CKANGroup() { super(); LIST = GROUP_LIST; @@ -70,4 +79,24 @@ public class CKANGroup extends CKAN { throw new InternalServerErrorException(e); } } + + public List getGroups() { + if(result==null) { + read(); + } + List groups = new ArrayList(); + if(result.has(GROUPS_KEY)) { + JsonNode jsonNode = result.get(GROUPS_KEY); + if(jsonNode.isArray()) { + ArrayNode arrayNode = (ArrayNode) jsonNode; + if(arrayNode.size()>0) { + Iterator iterator = arrayNode.iterator(); + while(iterator.hasNext()) { + groups.add(iterator.next().asText()); + } + } + } + } + return groups; + } } diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKANInstance.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKANInstance.java new file mode 100644 index 0000000..2cb237b --- /dev/null +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKANInstance.java @@ -0,0 +1,186 @@ +package org.gcube.gcat.persistence.ckan; + +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.InternalServerErrorException; +import javax.ws.rs.WebApplicationException; + +import org.gcube.common.encryption.encrypter.StringEncrypter; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.Property; +import org.gcube.gcat.utils.ContextUtility; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class CKANInstance { + + private static final Logger logger = LoggerFactory.getLogger(CKANInstance.class); + + // CKAN Instance info + private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue"; + private final static String PLATFORM_CATALOGUE_NAME = "Tomcat"; + + // property to retrieve the master service endpoint into the /root scope + private final static String IS_MASTER_ROOT_KEY_PROPERTY = "IS_ROOT_MASTER"; // true, false.. missing means false as well + + private final static String API_KEY_PROPERTY = "API_KEY"; + private final static String SOCIAL_POST = "SOCIAL_POST"; + private final static String ALERT_USERS_ON_POST_CREATION = "ALERT_USERS_ON_POST_CREATION"; + private final static String URL_RESOLVER = "URL_RESOLVER"; + + private static final Map ckanInstancePerScope; + + protected String ckanURL; + protected String sysAdminToken; + protected boolean socialPostEnabled; + protected boolean notificationToUsersEnabled; + protected String uriResolverURL; + + static { + ckanInstancePerScope = new HashMap(); + } + + public static CKANInstance getInstance() { + CKANInstance ckanInstance = ckanInstancePerScope.get(ContextUtility.getCurrentContext()); + if(ckanInstance == null) { + ckanInstance = new CKANInstance(); + ckanInstance.getConfigurationFromIS(); + ckanInstancePerScope.put(ContextUtility.getCurrentContext(), ckanInstance); + } + return ckanInstance; + } + + /** + * Retrieve endpoints information from IS for DataCatalogue URL + * @return list of endpoints for ckan data catalogue + * @throws Exception + */ + private static List getServiceEndpoints() { + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/text() eq '" + RUNTIME_CATALOGUE_RESOURCE_NAME + "'"); + query.addCondition("$resource/Profile/Platform/Name/text() eq '" + PLATFORM_CATALOGUE_NAME + "'"); + DiscoveryClient client = clientFor(ServiceEndpoint.class); + List serviceEndpoints = client.submit(query); + if(serviceEndpoints.size() == 0) { + logger.error("There is no {} having name {} and Platform {} in this context.", + ServiceEndpoint.class.getSimpleName(), RUNTIME_CATALOGUE_RESOURCE_NAME, PLATFORM_CATALOGUE_NAME); + throw new InternalServerErrorException("No CKAN configuration on IS"); + } + return serviceEndpoints; + } + + private void getConfigurationFromIS() { + try { + List serviceEndpoints = getServiceEndpoints(); + ServiceEndpoint serviceEndpoint = null; + + if(serviceEndpoints.size() > 1) { + logger.info("Too many {} having name {} in this context. Looking for the one that has the property {}", + ServiceEndpoint.class.getSimpleName(), RUNTIME_CATALOGUE_RESOURCE_NAME, + IS_MASTER_ROOT_KEY_PROPERTY); + + for(ServiceEndpoint se : serviceEndpoints) { + Iterator accessPointIterator = se.profile().accessPoints().iterator(); + while(accessPointIterator.hasNext()) { + ServiceEndpoint.AccessPoint accessPoint = accessPointIterator.next(); + + // get the is master property + Property entry = accessPoint.propertyMap().get(IS_MASTER_ROOT_KEY_PROPERTY); + String isMaster = entry != null ? entry.value() : null; + + if(isMaster == null || !isMaster.equals("true")) { + continue; + } + + // set this variable + serviceEndpoint = se; + break; + } + } + + // if none of them was master, throw an exception + if(serviceEndpoint == null) { + throw new InternalServerErrorException( + "Too many CKAN configuration on IS and no one with MASTER property"); + } + + } else { + serviceEndpoint = serviceEndpoints.get(0); + } + + + Iterator accessPointIterator = serviceEndpoint.profile().accessPoints().iterator(); + while(accessPointIterator.hasNext()) { + AccessPoint accessPoint = accessPointIterator.next(); + + // add this host + ckanURL = accessPoint.address(); + + // retrieve sys admin token + sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value(); + sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken); + + // retrieve option to check if the social post has to be made + socialPostEnabled = true; // default is true + if(accessPoint.propertyMap().containsKey(SOCIAL_POST)) { + if(accessPoint.propertyMap().get(SOCIAL_POST).value().trim().equalsIgnoreCase("false")) { + socialPostEnabled = false; + } + } + + // retrieve option for user alert + notificationToUsersEnabled = false; + if(accessPoint.propertyMap().containsKey(ALERT_USERS_ON_POST_CREATION)) { + if(accessPoint.propertyMap().get(ALERT_USERS_ON_POST_CREATION).value().trim().equalsIgnoreCase("true")) { + notificationToUsersEnabled = true; + } + } + + // retrieve URL_RESOLVER + if(accessPoint.propertyMap().containsKey(URL_RESOLVER)) { + uriResolverURL = accessPoint.propertyMap().get(URL_RESOLVER).value(); + } + + } + + } catch (WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException("Error while getting configuration on IS", e); + } + + } + + public String getUriResolverURL() throws Exception { + return uriResolverURL; + } + + public String getCKANURL() { + return ckanURL; + } + + public boolean isSocialPostEnabled() throws Exception { + return socialPostEnabled; + } + + public boolean isNotificationToUsersEnabled() throws Exception { + return notificationToUsersEnabled; + } + + public String getSysAdminToken() throws Exception { + return sysAdminToken; + } + +} diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKANUtility.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKANUtility.java index 6c5cb66..021ceb4 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKANUtility.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKANUtility.java @@ -2,31 +2,14 @@ package org.gcube.gcat.persistence.ckan; import javax.ws.rs.InternalServerErrorException; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster; -import org.gcube.gcat.utils.ContextUtility; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * @author Luca Frosini (ISTI - CNR) */ public class CKANUtility { - private static final Logger logger = LoggerFactory.getLogger(CKANUtility.class); - - public static DataCatalogue getCatalogue() throws Exception { - String context = ContextUtility.getCurrentContext(); - logger.debug("Discovering ckan instance in context {}", context); - return DataCatalogueFactory.getFactory().getUtilsPerScope(context); - } - public static String getSysAdminAPI() { try { - DataCatalogueRunningCluster catalogueRunningInstance = new DataCatalogueRunningCluster( - ContextUtility.getCurrentContext()); - return catalogueRunningInstance.getSysAdminToken(); + return CKANInstance.getInstance().getSysAdminToken(); } catch(Exception e) { throw new InternalServerErrorException(e); } diff --git a/src/main/java/org/gcube/gcat/social/SocialPost.java b/src/main/java/org/gcube/gcat/social/SocialPost.java index b671df1..bb95300 100644 --- a/src/main/java/org/gcube/gcat/social/SocialPost.java +++ b/src/main/java/org/gcube/gcat/social/SocialPost.java @@ -9,8 +9,7 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import org.gcube.common.gxhttp.request.GXHTTPStringRequest; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; -import org.gcube.gcat.persistence.ckan.CKAN; +import org.gcube.gcat.persistence.ckan.CKANInstance; import org.gcube.gcat.persistence.ckan.CKANUser; import org.gcube.gcat.utils.Constants; import org.gcube.gcat.utils.ContextUtility; @@ -108,15 +107,16 @@ public class SocialPost extends Thread { public void run() { try { - DataCatalogue dataCatalogue = CKAN.getCatalogue(); - if(!dataCatalogue.isSocialPostEnabled()) { + CKANInstance instance = CKANInstance.getInstance(); + + if(!instance.isSocialPostEnabled()) { logger.info("Social Post are disabled in the context {}", ContextUtility.getCurrentContext()); return; } logger.info("Going to send Social Post about the Item {} available at {}", itemID, itemURL); - boolean notifyUsers = dataCatalogue.isNotificationToUsersEnabled(); + boolean notifyUsers = instance.isNotificationToUsersEnabled(); // write notification post sendSocialPost(notifyUsers); diff --git a/src/main/java/org/gcube/gcat/utils/URIResolver.java b/src/main/java/org/gcube/gcat/utils/URIResolver.java index 26709ed..48e42c2 100644 --- a/src/main/java/org/gcube/gcat/utils/URIResolver.java +++ b/src/main/java/org/gcube/gcat/utils/URIResolver.java @@ -12,9 +12,7 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import org.gcube.common.gxhttp.request.GXHTTPStringRequest; -import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.server.utils.url.EntityContext; -import org.gcube.gcat.persistence.ckan.CKAN; +import org.gcube.gcat.persistence.ckan.CKANInstance; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -25,6 +23,8 @@ public class URIResolver { private static final String ENTITY_TYPE = "entity_context"; private static final String ENTITY_NAME = "entity_name"; + private static final String DATASET = "dataset"; + protected ObjectMapper mapper; public URIResolver() { @@ -44,13 +44,12 @@ public class URIResolver { public String getCatalogueItemURL(String name) { try { - DataCatalogue dataCatalogue = CKAN.getCatalogue(); - String uriResolverURL = dataCatalogue.getUriResolverUrl(); + String uriResolverURL = CKANInstance.getInstance().getUriResolverURL(); ObjectNode requestContent = mapper.createObjectNode(); requestContent.put(CATALOGUE_CONTEXT, ContextUtility.getCurrentContext()); - requestContent.put(ENTITY_TYPE, EntityContext.DATASET.toString()); + requestContent.put(ENTITY_TYPE, DATASET); requestContent.put(ENTITY_NAME, name); GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(uriResolverURL);