Added the possibility to list items by specifying query parameters (used
for direct query on Slr via Ckan package_search API)
This commit is contained in:
parent
9779afe1e5
commit
78a54707ec
|
@ -4,6 +4,8 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.ws.rs.BadRequestException;
|
import javax.ws.rs.BadRequestException;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
|
@ -63,8 +65,15 @@ public class CKANPackage extends CKAN {
|
||||||
// offset in https://docs.ckan.org/en/latest/api/index.html#ckan.logic.action.get.package_search
|
// offset in https://docs.ckan.org/en/latest/api/index.html#ckan.logic.action.get.package_search
|
||||||
protected static final String START_KEY = "start";
|
protected static final String START_KEY = "start";
|
||||||
|
|
||||||
protected static final String Q_KEY = "q";
|
protected static final String ORGANIZATION_FILTER_TEMPLATE = GCatConstants.ORGANIZATION_PARAMETER + ":%s";
|
||||||
protected static final String ORGANIZATION_FILTER_TEMPLATE = "organization:%s";
|
|
||||||
|
protected static final String ORGANIZATION_REGEX = GCatConstants.ORGANIZATION_PARAMETER + ":[a-zA-Z_\"]*";
|
||||||
|
|
||||||
|
protected static final Pattern ORGANIZATION_REGEX_PATTERN;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ORGANIZATION_REGEX_PATTERN = Pattern.compile(ORGANIZATION_REGEX);
|
||||||
|
}
|
||||||
|
|
||||||
protected static final String LICENSE_KEY = "license_id";
|
protected static final String LICENSE_KEY = "license_id";
|
||||||
|
|
||||||
|
@ -88,8 +97,6 @@ public class CKANPackage extends CKAN {
|
||||||
protected static final String SEARCHABLE_KEY = "searchable";
|
protected static final String SEARCHABLE_KEY = "searchable";
|
||||||
protected static final String CAPACITY_KEY = "capacity";
|
protected static final String CAPACITY_KEY = "capacity";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// protected static final String INCLUDE_PRIVATE_KEY = "include_private";
|
// protected static final String INCLUDE_PRIVATE_KEY = "include_private";
|
||||||
// protected static final String INCLUDE_DRAFTS_KEY = "include_drafts";
|
// protected static final String INCLUDE_DRAFTS_KEY = "include_drafts";
|
||||||
|
|
||||||
|
@ -251,31 +258,88 @@ public class CKANPackage extends CKAN {
|
||||||
}
|
}
|
||||||
parameters.put(START_KEY, String.valueOf(offset * limit));
|
parameters.put(START_KEY, String.valueOf(offset * limit));
|
||||||
|
|
||||||
|
if(uriInfo!=null) {
|
||||||
|
MultivaluedMap<String,String> queryParameters = uriInfo.getQueryParameters();
|
||||||
|
parameters = checkListParameters(queryParameters, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkOrganizationFilter(String q) {
|
||||||
|
Matcher m = ORGANIZATION_REGEX_PATTERN.matcher(q);
|
||||||
|
|
||||||
|
List<String> matches = new ArrayList<>();
|
||||||
|
while(m.find()) {
|
||||||
|
matches.add(q.substring(m.start(), m.end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(matches.size()>0) {
|
||||||
|
StringBuilder error = new StringBuilder();
|
||||||
|
error.append("Organization filters is constrained to VRE. ");
|
||||||
|
if(matches.size()>1) {
|
||||||
|
error.append("Remove these filters ");
|
||||||
|
}else {
|
||||||
|
error.append("Remove this filter ");
|
||||||
|
}
|
||||||
|
boolean first = true;
|
||||||
|
for(String match : matches) {
|
||||||
|
if(!first) {
|
||||||
|
error.append(", ");
|
||||||
|
}else {
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
error.append("[");
|
||||||
|
error.append(match);
|
||||||
|
error.append("]");
|
||||||
|
}
|
||||||
|
throw new BadRequestException(error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String,String> checkListParameters(MultivaluedMap<String,String> queryParameters,
|
||||||
|
Map<String,String> parameters) {
|
||||||
|
|
||||||
String organizationName = getOrganizationName();
|
String organizationName = getOrganizationName();
|
||||||
ScopeBean scopeBean = new ScopeBean(ContextUtility.getCurrentContext());
|
ScopeBean scopeBean = new ScopeBean(ContextUtility.getCurrentContext());
|
||||||
|
|
||||||
|
String q = null;
|
||||||
|
if(queryParameters.containsKey(GCatConstants.Q_KEY)) {
|
||||||
|
q = queryParameters.getFirst(GCatConstants.Q_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List is filter per organization only is the request arriving in a VRE.
|
* List is filter per organization only is the request arriving in a VRE.
|
||||||
* If the request arrive form a VO or from ROOT the request return the item in all organizations
|
* If the request arrive form a VO or from ROOT the request return the item in all organizations
|
||||||
* in the catalog.
|
* in the catalog.
|
||||||
*/
|
*/
|
||||||
String organizationQueryString = null;
|
|
||||||
if(scopeBean.is(Type.VRE)) {
|
if(scopeBean.is(Type.VRE)) {
|
||||||
organizationQueryString = String.format(ORGANIZATION_FILTER_TEMPLATE, organizationName);
|
if(q != null) {
|
||||||
|
checkOrganizationFilter(q);
|
||||||
|
|
||||||
|
// Adding organization filter to q
|
||||||
|
parameters.put(GCatConstants.Q_KEY,
|
||||||
|
String.format("%s:%s AND %s", GCatConstants.ORGANIZATION_PARAMETER, organizationName, q));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
parameters.put(GCatConstants.Q_KEY,
|
||||||
* We provide the possibility for the client to get the list of an item in an organization
|
String.format(GCatConstants.ORGANIZATION_FILTER_TEMPLATE, organizationName));
|
||||||
* if the request arrives from a VO o from the ROOT
|
|
||||||
*/
|
|
||||||
MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();
|
|
||||||
if(queryParameters!=null && queryParameters.containsKey(GCatConstants.ORGANIZATION_PARAMETER)) {
|
|
||||||
String org = queryParameters.getFirst(GCatConstants.ORGANIZATION_PARAMETER);
|
|
||||||
organizationQueryString = String.format(ORGANIZATION_FILTER_TEMPLATE, org);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(organizationQueryString!=null) {
|
} else {
|
||||||
parameters.put(Q_KEY, organizationQueryString);
|
// We are in VO or in ROOT.
|
||||||
|
// The organization filtering is allowed for the client which must provide q parameter in the form:
|
||||||
|
// q=organization:nextnext
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String key : queryParameters.keySet()) {
|
||||||
|
// if 'rows' and 'start' are provided they replace the values imposed by caller
|
||||||
|
// provided limit and offset parameter which are the gCat interface are not passed to CKAN
|
||||||
|
if(key.compareTo(GCatConstants.LIMIT_PARAMETER) == 0
|
||||||
|
|| key.compareTo(GCatConstants.OFFSET_PARAMETER) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parameters.put(key, queryParameters.getFirst(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// parameters.put(INCLUDE_PRIVATE_KEY, String.valueOf(true));
|
// parameters.put(INCLUDE_PRIVATE_KEY, String.valueOf(true));
|
||||||
|
@ -283,6 +347,11 @@ public class CKANPackage extends CKAN {
|
||||||
// By default not including draft
|
// By default not including draft
|
||||||
// parameters.put(INCLUDE_DRAFTS_KEY, String.valueOf(false));
|
// parameters.put(INCLUDE_DRAFTS_KEY, String.valueOf(false));
|
||||||
|
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String list(Map<String,String> parameters) {
|
||||||
|
|
||||||
sendGetRequest(LIST, parameters);
|
sendGetRequest(LIST, parameters);
|
||||||
|
|
||||||
ArrayNode results = (ArrayNode) result.get(RESULTS_KEY);
|
ArrayNode results = (ArrayNode) result.get(RESULTS_KEY);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.gcube.gcat.rest;
|
package org.gcube.gcat.rest;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.DefaultValue;
|
import javax.ws.rs.DefaultValue;
|
||||||
|
@ -30,6 +32,15 @@ public class Item extends REST<CKANPackage> implements org.gcube.gcat.api.interf
|
||||||
super(ITEMS, ITEM_ID_PARAMETER, CKANPackage.class);
|
super(ITEMS, ITEM_ID_PARAMETER, CKANPackage.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not used as REST method, implemented to respect {@link org.gcube.gcat.api.interfaces.Item} interface
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String list(Map<String,String> parameters) throws WebServiceException {
|
||||||
|
CKANPackage ckan = getInstance();
|
||||||
|
return ckan.list(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
|
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,7 +3,12 @@ package org.gcube.gcat.persistence.ckan;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.ws.rs.BadRequestException;
|
||||||
|
import javax.ws.rs.core.MultivaluedHashMap;
|
||||||
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
|
||||||
import org.gcube.gcat.ContextTest;
|
import org.gcube.gcat.ContextTest;
|
||||||
|
import org.gcube.gcat.api.GCatConstants;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -33,12 +38,50 @@ public class CKANPackageTest extends ContextTest {
|
||||||
public void list() throws Exception {
|
public void list() throws Exception {
|
||||||
CKANPackage ckanPackage = new CKANPackage();
|
CKANPackage ckanPackage = new CKANPackage();
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
String ret = ckanPackage.list(-1, 0);
|
String ret = ckanPackage.list(10, 0);
|
||||||
JsonNode gotList = mapper.readTree(ret);
|
JsonNode gotList = mapper.readTree(ret);
|
||||||
Assert.assertTrue(gotList instanceof ArrayNode);
|
Assert.assertTrue(gotList instanceof ArrayNode);
|
||||||
logger.debug("List :\n{}", mapper.writeValueAsString(gotList));
|
logger.debug("List :\n{}", mapper.writeValueAsString(gotList));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listWithParameters() throws Exception {
|
||||||
|
CKANPackage ckanPackage = new CKANPackage();
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
parameters.put(GCatConstants.Q_KEY, "organization:ckand4scienceharvest OR organization:dorne");
|
||||||
|
// parameters.put(GCatConstants.Q_KEY, "organization:ckand4scienceharvest");
|
||||||
|
// parameters.put(GCatConstants.Q_KEY, "organization:dorne");
|
||||||
|
parameters.put(CKANPackage.ROWS_KEY, String.valueOf(10));
|
||||||
|
parameters.put(CKANPackage.START_KEY, String.valueOf(0));
|
||||||
|
//parameters.put("","");
|
||||||
|
|
||||||
|
String ret = ckanPackage.list(parameters);
|
||||||
|
JsonNode gotList = mapper.readTree(ret);
|
||||||
|
Assert.assertTrue(gotList instanceof ArrayNode);
|
||||||
|
|
||||||
|
logger.debug("List :\n{}", mapper.writeValueAsString(gotList));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected=BadRequestException.class)
|
||||||
|
public void checkParameter() throws Exception {
|
||||||
|
|
||||||
|
Map<String, String> parameters = new HashMap<>();
|
||||||
|
|
||||||
|
CKANPackage ckanPackage = new CKANPackage();
|
||||||
|
|
||||||
|
MultivaluedMap<String,String> queryParameters = new MultivaluedHashMap<>();
|
||||||
|
queryParameters.add(GCatConstants.Q_KEY, "organization:nextnext OR organization:devsec");
|
||||||
|
|
||||||
|
parameters = ckanPackage.checkListParameters(queryParameters, parameters);
|
||||||
|
|
||||||
|
logger.debug("{}", parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PRE
|
* PRE
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue