added code to discover the uri resolver, create an url given the dataset id and generate it

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/ckan-util-library@139732 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-12-06 18:01:21 +00:00
parent 0f993230d6
commit 305b470532
5 changed files with 127 additions and 29 deletions

View File

@ -174,13 +174,12 @@ public interface DataCatalogue {
List<String> tags, Map<String, List<String>> customFields, List<ResourceBean> resources, boolean setPublic);
/**
* Given the id or the name of the dataset it returns its current url (e.g., http://ckan-catalogue-address.org/dataset/dataset-name)
* @param apiKey
* Given the id or the name of the dataset it returns its current url by contacting the uri resolver.
* If no uri resolver is available, an url that is not guaranteed to be long term valid will be generated.
* @param datasetId
* @param withoutHost if the host part is not needed (e.g. it returns only /dataset/dataset-name)
* @return The url of the dataset on success, null otherwise
*/
String getUrlFromDatasetIdOrName(String apiKey, String datasetIdOrName, boolean withoutHost);
String getUrlFromDatasetIdOrName(String datasetIdOrName);
/**
* Check if this user is a sysadmin. The api key is used to authorize this call.
@ -449,4 +448,10 @@ public interface DataCatalogue {
* @return a list of datasets in a group
*/
List<CkanDataset> getProductsInGroup(String groupName);
/**
* Retrieve the url of the uri resolver for this catalogue instance/scope
* @return
*/
String getUriResolverUrl();
}

View File

@ -6,6 +6,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
@ -33,6 +34,7 @@ import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean;
import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg;
import org.gcube.datacatalogue.ckanutillibrary.models.State;
import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods;
import org.gcube.datacatalogue.ckanutillibrary.utils.url.EntityContext;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
@ -79,7 +81,9 @@ public class DataCatalogueImpl implements DataCatalogue{
private Integer CKAN_DB_PORT;
private String PORTLET_URL_FOR_SCOPE;
private String CKAN_TOKEN_SYS;
private String URI_RESOLVER_URL;
private boolean MANAGE_PRODUCT_BUTTON;
private String validForContext;
// ckan client
private CkanClient client;
@ -119,6 +123,7 @@ public class DataCatalogueImpl implements DataCatalogue{
CKAN_CATALOGUE_URL = runningInstance.getDataCatalogueUrl().get(0).trim();
PORTLET_URL_FOR_SCOPE = runningInstance.getPortletUrl().trim();
MANAGE_PRODUCT_BUTTON = runningInstance.isManageProductEnabled();
URI_RESOLVER_URL = runningInstance.getUrlResolver();
logger.debug("Plain sys admin token first 3 chars are " + CKAN_TOKEN_SYS.substring(0, 3));
logger.debug("Plain db password first 3 chars are " + CKAN_DB_PASSWORD.substring(0, 3));
@ -128,9 +133,28 @@ public class DataCatalogueImpl implements DataCatalogue{
// init map
apiKeysMap = new ConcurrentHashMap<String, CKANTokenBean>();
// save the context
validForContext = scope;
}
@Override
public String getCatalogueUrl() {
return CKAN_CATALOGUE_URL;
}
@Override
public String getPortletUrl() {
return PORTLET_URL_FOR_SCOPE;
}
@Override
public String getUriResolverUrl() {
return URI_RESOLVER_URL;
}
/**
* Retrieve connection from the pool
* @return a connection available within the pool
@ -451,17 +475,6 @@ public class DataCatalogueImpl implements DataCatalogue{
return toReturn;
}
@Override
public String getCatalogueUrl() {
return CKAN_CATALOGUE_URL;
}
@Override
public String getPortletUrl() {
return PORTLET_URL_FOR_SCOPE;
}
@Override
public List<String> getOrganizationsNamesByUser(String username) {
@ -883,35 +896,75 @@ public class DataCatalogueImpl implements DataCatalogue{
}
@Override
public String getUrlFromDatasetIdOrName(String apiKey, String datasetIdOrName, boolean withoutHost) {
public String getUrlFromDatasetIdOrName(String datasetIdOrName) {
logger.debug("Request coming for dataset url of dataset with name/id " + datasetIdOrName);
logger.debug("Request coming for getting dataset url of dataset with name/id " + datasetIdOrName);
// checks
checkNotNull(apiKey);
checkNotNull(datasetIdOrName);
checkArgument(!apiKey.isEmpty());
checkArgument(!datasetIdOrName.isEmpty());
// the url of the dataset looks like "getCatalogueUrl() + /dataset/ + dataset name"
try{
// get the dataset from name
CheckedCkanClient client = new CheckedCkanClient(CKAN_CATALOGUE_URL, apiKey);
CheckedCkanClient client = new CheckedCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS);
CkanDataset dataset = client.getDataset(datasetIdOrName);
String name = dataset.getName();
if(dataset != null){
if(withoutHost)
return "/dataset/" + dataset.getName();
else
return CKAN_CATALOGUE_URL + "/dataset/" + dataset.getName();
String url = null;
if(getUriResolverUrl() != null)
url = getUrlForProduct(validForContext, EntityContext.DATASET, name);
if(url == null)
return getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + name, "UTF-8");
}
}catch(Exception e){
logger.error("Error while retrieving dataset with id/name=" + datasetIdOrName, e);
}
return null;
}
/**
* Retrieve an url for the tuple scope, entity, entity name
* @param context
* @param entityContext
* @param entityName
* @return the url for the product
*/
private String getUrlForProduct(String context, EntityContext entityContext, String entityName){
String toReturn = null;
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpPost httpPostRequest = new HttpPost(getUriResolverUrl());
JSONObject requestEntity = new JSONObject();
requestEntity.put("gcube_scope", context);
requestEntity.put("entity_context", entityContext.toString());
requestEntity.put("entity_name", entityName);
StringEntity params = new StringEntity(requestEntity.toJSONString(), ContentType.APPLICATION_JSON);
httpPostRequest.setEntity(params);
HttpResponse response = httpClient.execute(httpPostRequest);
if(response.getStatusLine().getStatusCode() != 200)
throw new Exception("There was an error while creating an url " + response.getStatusLine());
String result = EntityUtils.toString(response.getEntity());
logger.debug("Result is " + result);
}catch(Exception e){
logger.error("Failed to get an url for this product", e);
}
return toReturn;
}
@Override
public boolean checkRoleIntoOrganization(String username, String organizationName,

View File

@ -56,6 +56,9 @@ public class DataCatalogueRunningCluster {
private final static String IS_MASTER_ROOT_KEY_PROPERTY = "IS_ROOT_MASTER"; // true, false.. missing means false as well
private final static String IS_MANAGE_PRODUCT_ENABLED = "IS_MANAGE_PRODUCT_ENABLED"; // true, false.. missing means false as well (for GRSF records)
// url of the http uri for this scope
private final static String URL_RESOLVER = "URL_RESOLVER";
// retrieved data
private List<String> datacatalogueUrls = new ArrayList<String>();
private List<String> hostsDB = new ArrayList<String>();
@ -65,6 +68,7 @@ public class DataCatalogueRunningCluster {
private String passwordDB;
private String portletUrl;
private boolean manageProductEnabled;
private String urlResolver;
// this token is needed in order to assign roles to user
private String sysAdminToken;
@ -207,6 +211,9 @@ public class DataCatalogueRunningCluster {
// retrieve sys admin token
sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value();
sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken);
// retrieve URL_RESOLVER
urlResolver = accessPoint.propertyMap().get(URL_RESOLVER).value();
// break now
break;
@ -241,6 +248,9 @@ public class DataCatalogueRunningCluster {
logger.info("Manage product is enabled in this scope");
manageProductEnabled = true;
}
// retrieve URL_RESOLVER
urlResolver = accessPoint.propertyMap().get(URL_RESOLVER).value();
}
}
}
@ -404,5 +414,13 @@ public class DataCatalogueRunningCluster {
public boolean isManageProductEnabled() {
return manageProductEnabled;
}
/**
* Get the url of the uri resolver for this instance/scope
* @return
*/
public String getUrlResolver() {
return urlResolver;
}
}

View File

@ -0,0 +1,24 @@
package org.gcube.datacatalogue.ckanutillibrary.utils.url;
/**
* Entity context for uri resolver
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public enum EntityContext {
DATASET("dataset"),
GROUP("group"),
ORGANIZATION("organization");
private String entityAsString;
private EntityContext(String entityAsString) {
this.entityAsString = entityAsString;
}
@Override
public String toString() {
return this.entityAsString;
}
}

View File

@ -15,8 +15,6 @@ import org.gcube.datacatalogue.ckanutillibrary.models.CkanDatasetRelationship;
import org.gcube.datacatalogue.ckanutillibrary.models.DatasetRelationships;
import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg;
import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import eu.trentorise.opendata.jackan.CheckedCkanClient;