patchDataset method now performs differently: if a custom field with a given key is present its values won't be replaced, but merged with the new values.

Added a removeCustomField method too: it accepts a key and a value.

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/ckan-util-library@139806 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-12-07 17:32:07 +00:00
parent 5d8ec1875a
commit a6cde11d39
3 changed files with 111 additions and 23 deletions

View File

@ -403,13 +403,20 @@ public interface DataCatalogue {
/**
* Patch a product with product id productId by using the couples in toChange.
* NOTE: only the specified custom fields will be changed..
* NOTE: only the specified custom fields will be changed. If a custom field with a given key
* already exists, the new values are added at the end of the list.
* @param productId
* @param apiKey
* @param toChange
* @return true on success, false otherwise
*/
boolean patchProductCustomFields(String productId, String apiKey, Map<String, List<String>> customFieldsToChange);
/**
* Remove a custom field in the product that has a given key and value. If more than ones are present, the first one is removed.
* @return true on success, false otherwise.
*/
boolean removeCustomField(String productId, String key, String value, String apiKey);
/**
* Remove a tag from a product

View File

@ -135,7 +135,7 @@ public class DataCatalogueImpl implements DataCatalogue{
// init map
apiKeysMap = new ConcurrentHashMap<String, CKANTokenBean>();
// save the context
validForContext = scope;
@ -823,12 +823,12 @@ public class DataCatalogueImpl implements DataCatalogue{
// sort them
Collections.sort(extras, new Comparator<CkanPair>() {
@Override public int compare(CkanPair b1, CkanPair b2) {
return b1.getKey().compareTo(b2.getKey());
}
@Override public int compare(CkanPair b1, CkanPair b2) {
return b1.getKey().compareTo(b2.getKey());
}
});
});
dataset.setExtras(extras);
}
@ -922,20 +922,20 @@ public class DataCatalogueImpl implements DataCatalogue{
String name = dataset.getName();
if(dataset != null){
if(getUriResolverUrl() != null)
url = getUrlForProduct(validForContext, EntityContext.DATASET, name);
if(url == null || url.isEmpty())
url = getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + name, "UTF-8");
}
}catch(Exception e){
logger.error("Error while retrieving dataset with id/name=" + datasetIdOrName, e);
}
return url;
}
/**
* Retrieve an url for the tuple scope, entity, entity name
* @param context
@ -950,7 +950,7 @@ public class DataCatalogueImpl implements DataCatalogue{
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());
@ -960,10 +960,10 @@ public class DataCatalogueImpl implements DataCatalogue{
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());
toReturn = EntityUtils.toString(response.getEntity());
logger.debug("Result is " + toReturn);
@ -1974,7 +1974,15 @@ public class DataCatalogueImpl implements DataCatalogue{
String key = entry.getKey();
List<String> newValues = entry.getValue();
fromCKANCustomFields.put(key, newValues);
// get the unique set of values
Set<String> uniqueValues = new HashSet<String>();
if(fromCKANCustomFields.containsKey(key))
uniqueValues.addAll(fromCKANCustomFields.get(key));
uniqueValues.addAll(newValues);
fromCKANCustomFields.put(key, new ArrayList<String>(uniqueValues));
}
logger.info("After merging it is " + fromCKANCustomFields);
@ -2031,6 +2039,80 @@ public class DataCatalogueImpl implements DataCatalogue{
return false;
}
@Override
public boolean removeCustomField(String productId, String key,
String value, String apiKey) {
// checks
checkNotNull(productId);
checkNotNull(apiKey);
checkNotNull(value);
checkNotNull(key);
logger.info("Going to change product with id " + productId +"."
+ " Request comes from user with key " + apiKey.substring(0, 5) + "****************");
logger.info("The couple key/value to remove from custom fields is [" + key + "," + value +"]");
CheckedCkanClient client = new CheckedCkanClient(CKAN_CATALOGUE_URL, apiKey);
List<CkanPair> extras = client.getDataset(productId).getExtras();
Iterator<CkanPair> iterator = extras.iterator();
while (iterator.hasNext()) {
CkanPair ckanPair = (CkanPair) iterator.next();
if(ckanPair.getKey().equals(key) && ckanPair.getValue().equals(value)){
logger.info("Removed from the ckan pairs list");
iterator.remove();
break;
}
}
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
String apiRequestUrl = CKAN_CATALOGUE_URL + "/api/3/action/package_patch";
HttpPost httpPostRequest = new HttpPost(apiRequestUrl);
httpPostRequest.setHeader("Authorization", apiKey);
// Request parameters to be replaced
JSONObject jsonRequest = new JSONObject();
// build the json array for the "extras" field.. each object looks like {"key": ..., "value": ...}
JSONArray extrasObject = new JSONArray();
for(CkanPair extra: extras){
JSONObject obj = new JSONObject();
obj.put("value", extra.getValue());
obj.put("key", extra.getKey());
extrasObject.add(obj);
}
// perform the request
jsonRequest.put("id", productId);
jsonRequest.put("extras", extrasObject);
logger.debug("Request param is going to be " + jsonRequest);
StringEntity params = new StringEntity(jsonRequest.toJSONString(), ContentType.APPLICATION_JSON);
httpPostRequest.setEntity(params);
HttpResponse response = httpClient.execute(httpPostRequest);
if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() >= 300) {
throw new RuntimeException("failed to patch the product. response status line from "
+ apiRequestUrl + " was: " + response.getStatusLine());
}
return true;
}catch(Exception e){
logger.error("Failed to remove the custom field for this product ", e);
}
return false;
}
@Override
public boolean removeTag(String productId, String apiKey, String tagToRemove) {
@ -2258,7 +2340,7 @@ public class DataCatalogueImpl implements DataCatalogue{
toReturn = new ArrayList<CkanDataset>();
JSONObject result = (JSONObject)parsedJson.get("result");
JSONArray packages = (JSONArray)result.get("packages");
logger.debug("Packages looks like " + packages);
for (int i = 0, size = packages.size(); i < size; i++){

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;
@ -39,20 +37,21 @@ public class TestDataCatalogueLib {
String subjectId = "aa_father4";
String objectId = "bb_son4";
@Before
// @Before
public void before() throws Exception{
factory = DataCatalogueFactory.getFactory();
}
@Test
// @Test
public void testManageProduct() throws Exception{
DataCatalogueImpl catalogue = factory.getUtilsPerScope(scope);
logger.debug("Manage product is " + catalogue.isManageProductEnabled());
String url = catalogue.getUrlFromDatasetIdOrName("test_with_duplicated_keys");
logger.debug("Url is " + url);
String apiKey = catalogue.getApiKeyFromUsername("costantino_perciante");
//Map<String, List<String>> map = new HashMap<String, List<String>>();
//map.put("a new custom field", Arrays.asList("a new custom field 2"));
//catalogue.patchProductCustomFields("test-searchable-504043", apiKey, map);
catalogue.removeCustomField("test-searchable-504043", "a new custom field", "a new custom field", apiKey);
}
//@Test