Merged from private branch

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/gcat@176439 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Luca Frosini 2019-01-10 11:29:47 +00:00
parent 42badcda3e
commit f21a714851
46 changed files with 968 additions and 1607 deletions

View File

@ -21,7 +21,6 @@ Authors
--------------------------------------------------
* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
* Costantino Perciante (costantino.perciante@isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
Maintainers
-----------

View File

@ -1,31 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<ReleaseNotes>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-4-0" date="${buildDate}">
<Change></Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-3-0" date="2018-10-10">
<Change>Complete refactoring of code</Change>
<Change>Item Port type is now RESTful (old methods are still allowed)</Change>
<Change>Added update support for Item #11516</Change>
<Change>Changed caching mechanism from ehcache API to JSR-107. Ehcache is still used as runtime library.</Change>
<Change>Solved random NullPointer Exception on catalogue-ws related to old caching mechanism #11466</Change>
<Change>Fixed normalization of the organization name #12506</Change>
<Change>Added the possibility to deny social post on catalogue-ws #12514</Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-1-1"
date="2018-01-11">
<Change>Item purge method enhanced</Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-1-0"
date="2017-06-20">
<Change>Minor fixes while checking user's permissions</Change>
<Change>Namespaces are no longer transparently managed</Change>
<Change>Fixed 'default' value for metadata</Change>
<Change>Improved exception handling</Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-0-0"
date="2017-05-01">
<Changeset component="org.gcube.data-publishing.gcat.1-0-0" date="${buildDate}">
<Change>First Release</Change>
</Changeset>
</ReleaseNotes>

30
pom.xml
View File

@ -34,11 +34,6 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>gxRest</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -52,9 +47,9 @@
</properties>
<scm>
<connection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/${project.artifactId}</connection>
<developerConnection>scm:https://svn.d4science.research-infrastructures.eu/gcube//trunk/data-catalogue/${project.artifactId}</developerConnection>
<url>https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/${project.artifactId}</url>
<connection>scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId}</connection>
<developerConnection>scm:https://svn.d4science.research-infrastructures.eu/gcube//trunk/data-publishing/${project.artifactId}</developerConnection>
<url>https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-publishing/${project.artifactId}</url>
</scm>
@ -144,6 +139,14 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>gxRest</artifactId>
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
</dependency>
<!-- Libraries explicitly forced to provided -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
@ -233,15 +236,14 @@
<version>20140107</version>
</dependency>
<dependency>
<groupId>org.gcube.data-publishing</groupId>
<artifactId>storagehub-application-persistence</artifactId>
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
</dependency>
<!-- Test libraries -->
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${version.jersey}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@ -8,37 +8,36 @@ import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.spi.CachingProvider;
import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader;
// import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Handle caches via Ehcache stuff.
* @author Costantino Perciante (ISTI - CNR)
* @author Luca Frosini (ISTI - CNR)
*/
public class CachesManager {
// the following caches are declared within the ehcache.xml (no default is available, so pay attention)
public static final String PROFILES_READERS_CACHE = "profile_readers";
// public static final String PROFILES_READERS_CACHE = "profile_readers";
public static final String PROFILES_USERS_CACHE = "profile_users";
private static final CacheManager cacheManager;
private static final Cache<String, DataCalogueMetadataFormatReader> readerCache;
// private static final Cache<String, DataCalogueMetadataFormatReader> readerCache;
private static final Cache<String, JsonNode> userCache;
static {
CachingProvider provider = Caching.getCachingProvider();
cacheManager = provider.getCacheManager();
/*
MutableConfiguration<String, DataCalogueMetadataFormatReader> readerConfiguration =
new MutableConfiguration<String, DataCalogueMetadataFormatReader>()
.setTypes(String.class, DataCalogueMetadataFormatReader.class)
.setStoreByValue(false)
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.ONE_MINUTE));
readerCache = cacheManager.createCache(PROFILES_READERS_CACHE, readerConfiguration);
*/
MutableConfiguration<String, JsonNode> userConfiguration =
new MutableConfiguration<String, JsonNode>()
@ -50,9 +49,11 @@ public class CachesManager {
private CachesManager() {}
/*
public static Cache<String, DataCalogueMetadataFormatReader> getReaderCache() {
return readerCache;
}
*/
public static Cache<String, JsonNode> getUserCache() {
return userCache;

View File

@ -16,8 +16,6 @@ import javax.ws.rs.BadRequestException;
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.DataCalogueMetadataFormatReader;
import org.gcube.datacatalogue.metadatadiscovery.bean.MetadataProfile;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.DataType;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataField;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataFormat;
@ -27,8 +25,7 @@ import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.NamespaceCategory;
import org.gcube.gcat.persistence.ckan.CKAN;
import org.gcube.gcat.persistence.ckan.CKANPackage;
import org.gcube.gcat.persistence.ckan.CKANUtility;
import org.gcube.gcat.rest.Namespace;
import org.gcube.gcat.rest.Profile;
import org.gcube.gcat.profile.MetadataUtility;
import org.gcube.gcat.social.SocialService;
import org.geojson.GeoJsonObject;
import org.json.simple.JSONArray;
@ -66,12 +63,11 @@ public class Validator {
return jsonObject;
}
public static void validateAgainstProfile(String json, List<String> profiles) throws Exception {
public static void validateAgainstProfile(String json) throws Exception {
JSONObject jsonObject = getJSONObject(json);
validateAgainstProfile(jsonObject, profiles);
validateAgainstProfile(jsonObject);
}
/**
* This method validate the incoming json dataset wrt a metadata profile
* @param json
@ -80,14 +76,14 @@ public class Validator {
* @return
* @throws Exception
*/
public static void validateAgainstProfile(JSONObject obj, List<String> profiles) throws Exception {
public static void validateAgainstProfile(JSONObject obj) throws Exception {
JSONArray extrasArrayOriginal = (JSONArray) obj.get(CKANPackage.EXTRA_TYPES_KEY);
JSONArray groupsArrayOriginal = (JSONArray) obj.get(CKANPackage.GROUPS_KEY);
JSONArray tagsArrayOriginal = (JSONArray) obj.get(CKANPackage.TAGS_KEY);
if(extrasArrayOriginal == null || extrasArrayOriginal.isEmpty()) {
throw new Exception("'extras' field is missing in context where metadata profile(s) are defined!");
throw new BadRequestException("'extras' field is missing in context where metadata profile(s) are defined!");
}
if(groupsArrayOriginal == null) {
@ -115,26 +111,18 @@ public class Validator {
}
if(metadataTypeCF == null) {
throw new Exception("'" + CKANPackage.EXTRA_TYPES_KEY_VALUE_SYSTEM_TYPE
throw new BadRequestException("'" + CKANPackage.EXTRA_TYPES_KEY_VALUE_SYSTEM_TYPE
+ "' extra field is missing in context where metadata profile(s) are defined!");
}
String profileName = metadataTypeCF.getValue();
// fetch the profile by metadata type specified above
MetadataFormat profile = null;
for(String profileName : profiles) {
profile = Validator.getMetadataProfile(profileName);
if(profile.getType().equals(metadataTypeCF.getValue())) {
break;
} else {
profile = null;
}
}
MetadataUtility metadataUtility = MetadataUtility.getInstance();
MetadataFormat profile = metadataUtility.getMetadataFormat(profileName);
if(profile == null) {
throw new Exception("'" + CKANPackage.EXTRA_TYPES_KEY_VALUE_SYSTEM_TYPE
+ "' extra field's value ('" + metadataTypeCF.getValue() +
"') specified as custom field doesn't match any of the profiles defined in this context!");
throw new BadRequestException("'" + CKANPackage.EXTRA_TYPES_KEY_VALUE_SYSTEM_TYPE + "' extra field's value ('"
+ profileName
+ "') specified as custom field doesn't match any of the profiles defined in this context!");
} else {
JSONArray extrasArrayUpdated = null;
List<MetadataField> metadataFields = profile.getMetadataFields();
@ -144,7 +132,7 @@ public class Validator {
} else {
extrasArrayUpdated = new JSONArray();
List<NamespaceCategory> categories = Namespace.getNamespaceCategories();
List<NamespaceCategory> categories = metadataUtility.getNamespaceCategories();
logger.debug("Retrieved namespaces are {}", categories);
List<String> categoriesIds = new ArrayList<String>(categories == null ? 0 : categories.size());
if(categories == null || categories.isEmpty()) {
@ -196,7 +184,7 @@ public class Validator {
+ " times and its lower bound is " + lowerBound + " and upper bound " + upperBound);
if(inserted < lowerBound || inserted > upperBound) {
throw new Exception("Field with key '" + entry.getKey()
throw new BadRequestException("Field with key '" + entry.getKey()
+ "' is mandatory, but it's not present among the provided fields or its cardinality is not respected ([min = "
+ lowerBound + ", max=" + upperBound + "]).");
}
@ -204,7 +192,7 @@ public class Validator {
// if there are no tags, throw an exception
if(tagsArrayOriginal.isEmpty()) {
throw new Exception("Please define at least one tag for this item!");
throw new BadRequestException("Please define at least one tag for this item!");
}
// sort validated custom fields and add to the extrasArrayUpdated json array
@ -422,7 +410,8 @@ public class Validator {
JSONObject group = new JSONObject();
group.put("name", CatalogueUtilMethods.fromGroupTitleToName(title));
if(propagateUp) {
List<String> parents = Validator.getGroupHierarchyNames(CatalogueUtilMethods.fromGroupTitleToName(title));
List<String> parents = Validator
.getGroupHierarchyNames(CatalogueUtilMethods.fromGroupTitleToName(title));
for(String parent : parents) {
JSONObject groupP = new JSONObject();
groupP.put("name", parent);
@ -464,7 +453,7 @@ public class Validator {
if((value == null || value.isEmpty()))
if(metadataField.getMandatory() || hasControlledVocabulary)
throw new Exception("Mandatory field with name '" + key
throw new BadRequestException("Mandatory field with name '" + key
+ "' doesn't have a value but it is mandatory or has a controlled vocabulary!");
else {
if(defaultValue != null && !defaultValue.isEmpty()) {
@ -480,7 +469,7 @@ public class Validator {
case Text:
if(regex != null && !value.matches(regex))
throw new Exception("Field with key '" + key + "' doesn't match the provided regular expression ("
throw new BadRequestException("Field with key '" + key + "' doesn't match the provided regular expression ("
+ regex + ")!");
if(hasControlledVocabulary) {
@ -498,7 +487,7 @@ public class Validator {
}
if(!match)
throw new Exception("Field with key '" + key + "' has a value '" + value
throw new BadRequestException("Field with key '" + key + "' has a value '" + value
+ "' but it doesn't match any of the vocabulary's values (" + valuesVocabulary + ")!");
}
@ -507,7 +496,7 @@ public class Validator {
case Time:
if(!isValidDate(value))
throw new Exception("Field with key '" + key + "' doesn't seem a valid time!");
throw new BadRequestException("Field with key '" + key + "' doesn't seem a valid time!");
break;
case Time_Interval:
@ -516,7 +505,7 @@ public class Validator {
for(int i = 0; i < timeValues.length; i++) {
String time = timeValues[i];
if(!isValidDate(time))
throw new Exception("Field with key '" + key + "' doesn't seem a valid time interval!");
throw new BadRequestException("Field with key '" + key + "' doesn't seem a valid time interval!");
}
break;
@ -526,11 +515,11 @@ public class Validator {
for(int i = 0; i < timeIntervals.length; i++) {
String[] timeIntervalValues = timeIntervals[i].split("/");
if(timeIntervalValues.length > 2)
throw new Exception("Field with key '" + key + "' doesn't seem a valid list of times!");
throw new BadRequestException("Field with key '" + key + "' doesn't seem a valid list of times!");
for(i = 0; i < timeIntervalValues.length; i++) {
String time = timeIntervalValues[i];
if(!isValidDate(time))
throw new Exception("Field with key '" + key + "' doesn't seem a valid list of times!");
throw new BadRequestException("Field with key '" + key + "' doesn't seem a valid list of times!");
}
}
@ -540,13 +529,13 @@ public class Validator {
if(value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
} else
throw new Exception("Field with key '" + key + "' doesn't seem a valid boolean value!");
throw new BadRequestException("Field with key '" + key + "' doesn't seem a valid boolean value!");
break;
case Number:
if(!NumberUtils.isNumber(value))
throw new Exception("Field's value with key '" + key + "' is not a valid number!");
throw new BadRequestException("Field's value with key '" + key + "' is not a valid number!");
break;
case GeoJSON:
@ -554,7 +543,7 @@ public class Validator {
try {
new ObjectMapper().readValue(fieldToValidate.getValue(), GeoJsonObject.class);
} catch(Exception e) {
throw new Exception("GeoJSON field with key '" + key + "' seems not valid!");
throw new BadRequestException("GeoJSON field with key '" + key + "' seems not valid!");
}
break;
@ -607,27 +596,4 @@ public class Validator {
return toReturn;
}
/**
* Returns the metadataform of the metadata profile (specified via name) in a given context
* @param context
* @return
* @throws Exception
*/
public static MetadataFormat getMetadataProfile(String profileName) throws Exception {
DataCalogueMetadataFormatReader reader = Profile.getDataCalogueMetadataFormatReader();
List<MetadataProfile> listProfiles = reader.getListOfMetadataProfiles();
if(listProfiles != null && !listProfiles.isEmpty()) {
for(MetadataProfile profile : listProfiles) {
if(profile.getName().equals(profileName)) {
return reader.getMetadataFormatForMetadataProfile(profile);
}
}
}
return null;
}
}

View File

@ -1,6 +1,11 @@
package org.gcube.gcat.persistence.ckan;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;
@ -10,12 +15,13 @@ import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;
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.Constants;
import org.gcube.gcat.utils.ContextUtility;
import org.gcube.gcat.utils.HTTPCall;
import org.gcube.gcat.utils.HTTPCall.HTTPMETHOD;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -43,6 +49,9 @@ public abstract class CKAN {
protected static final String RESULT_KEY = "result";
protected static final String SUCCESS_KEY = "success";
public static final String LIMIT_KEY = "limit";
public static final String OFFSET_KEY = "offset";
protected static final String NOT_FOUND_ERROR = "Not Found Error";
protected static final String AUTHORIZATION_ERROR = "Authorization Error";
protected static final String VALIDATION_ERROR = "Validation Error";
@ -53,6 +62,8 @@ public abstract class CKAN {
// ckan header authorization
public final static String AUTH_CKAN_HEADER = "Authorization";
public final static String NAME_REGEX = "^[a-z0-9_\\\\-]{2,100}$";
protected String LIST;
protected String CREATE;
protected String READ;
@ -68,24 +79,24 @@ public abstract class CKAN {
protected String apiKey;
protected JsonNode result;
protected String nameRegex;
public String getApiKey() {
if(apiKey==null) {
if(apiKey == null) {
try {
return CKANUtility.getApiKey();
}catch (Exception e) {
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getName() {
return name;
}
@ -106,7 +117,8 @@ public abstract class CKAN {
try {
this.mapper = new ObjectMapper();
this.dataCatalogue = getCatalogue();
}catch (Exception e) {
this.nameRegex = CKAN.NAME_REGEX;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
@ -130,7 +142,6 @@ public abstract class CKAN {
return DataCatalogueFactory.getFactory().getUtilsPerScope(context);
}
/**
* Validate the CKAN response and return the
* @param json
@ -150,7 +161,6 @@ public abstract class CKAN {
throw new BadRequestException(getAsString(error));
}
String message = error.get(MESSAGE_KEY).asText();
if(errorType.compareTo(NOT_FOUND_ERROR) == 0) {
@ -161,8 +171,6 @@ public abstract class CKAN {
throw new NotAuthorizedException(message);
}
// TODO parse more cases
} catch(WebApplicationException e) {
throw e;
@ -185,14 +193,18 @@ public abstract class CKAN {
protected JsonNode checkName(JsonNode jsonNode) {
try {
String gotName = jsonNode.get(NAME_KEY).asText();
if(name==null) {
if(!gotName.matches(nameRegex)) {
throw new BadRequestException("The 'name' must be between 2 and 100 characters long and contain only lowercase alphanumeric characters, '-' and '_'. You can validate your name using the regular expression : " + NAME_REGEX);
}
if(name == null) {
name = gotName;
}
if(gotName != null && gotName.compareTo(name) != 0) {
String error = String.format(
"The name (%s) does not match with the '%s' contained in the provided content (%s).",
name, NAME_KEY, gotName);
"The name (%s) does not match with the '%s' contained in the provided content (%s).", name,
NAME_KEY, gotName);
throw new BadRequestException(error);
}
return jsonNode;
@ -229,35 +241,83 @@ public abstract class CKAN {
return map;
}
public JsonNode sendRequest(HTTPMETHOD httpMethod, String path, Map<String,String> parameters, String body) {
String catalogueURL = dataCatalogue.getCatalogueUrl().endsWith("/") ? dataCatalogue.getCatalogueUrl() : dataCatalogue.getCatalogueUrl() + "/";
HTTPCall httpCall = new HTTPCall(catalogueURL);
httpCall.setgCubeTargetService(false);
httpCall.addHeader(AUTH_CKAN_HEADER, getApiKey());
String ret = httpCall.call(path, httpMethod, parameters, body, MediaType.APPLICATION_JSON);
JsonNode result = validateCKANResponse(ret);
if(result instanceof NullNode) {
result = mapper.createObjectNode();
protected StringBuilder getStringBuilder(InputStream inputStream) throws IOException {
StringBuilder result = new StringBuilder();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while((line = reader.readLine()) != null) {
result.append(line);
}
}
return result;
}
public String sendGetRequest(String path, Map<String,String> parameters) {
result = sendRequest(HTTPMETHOD.GET, path, parameters, null);
protected GXHTTPStringRequest getGXHTTPStringRequest(String path) throws UnsupportedEncodingException {
String catalogueURL = dataCatalogue.getCatalogueUrl();
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(catalogueURL);
gxhttpStringRequest.from(Constants.CATALOGUE_NAME);
gxhttpStringRequest.header("Content-type", MediaType.APPLICATION_JSON);
gxhttpStringRequest.isExternalCall(true);
gxhttpStringRequest.header(AUTH_CKAN_HEADER, getApiKey());
gxhttpStringRequest.path(path);
return gxhttpStringRequest;
}
protected String getResultAsString(HttpURLConnection httpURLConnection) throws IOException {
int responseCode = httpURLConnection.getResponseCode();
if(responseCode >= Status.BAD_REQUEST.getStatusCode()) {
Status status = Status.fromStatusCode(responseCode);
throw new WebApplicationException(status);
}
InputStream inputStream = httpURLConnection.getInputStream();
String ret = getStringBuilder(inputStream).toString();
logger.trace("Got Respose is {}", ret);
result = validateCKANResponse(ret);
if(result instanceof NullNode) {
result = mapper.createObjectNode();
}
return getAsString(result);
}
public String sendPostRequest(String path, String body) {
result = sendRequest(HTTPMETHOD.POST, path, null, body);
return getAsString(result);
protected String sendGetRequest(String path, Map<String,String> parameters) {
try {
GXHTTPStringRequest gxhttpStringRequest = getGXHTTPStringRequest(path);
gxhttpStringRequest.queryParams(parameters);
HttpURLConnection httpURLConnection = gxhttpStringRequest.get();
return getResultAsString(httpURLConnection);
} catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
public String sendPostRequest(String path, JsonNode jsonNode) {
protected String sendPostRequest(String path, String body) {
try {
GXHTTPStringRequest gxhttpStringRequest = getGXHTTPStringRequest(path);
HttpURLConnection httpURLConnection = gxhttpStringRequest.post(body);
return getResultAsString(httpURLConnection);
} catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
protected String sendPostRequest(String path, JsonNode jsonNode) {
return sendPostRequest(path, getAsString(jsonNode));
}
public String list() {
return sendGetRequest(LIST, null);
public String list(int limit, int offset) {
Map<String,String> parameters = new HashMap<>();
if(limit > 0) {
parameters.put(LIMIT_KEY, String.valueOf(limit));
}
if(offset >= 0) {
parameters.put(OFFSET_KEY, String.valueOf(offset));
}
return sendGetRequest(LIST, parameters);
}
public String create(String json) {

View File

@ -20,7 +20,7 @@ import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.gcat.annotation.PURGE;
import org.gcube.gcat.oldutils.Validator;
import org.gcube.gcat.rest.Profile;
import org.gcube.gcat.profile.MetadataUtility;
import org.gcube.gcat.social.SocialService;
import org.gcube.gcat.utils.ContextUtility;
import org.gcube.gcat.utils.URIResolver;
@ -155,9 +155,9 @@ public class CKANPackage extends CKAN {
ObjectNode objectNode = checkBaseInformation(json);
// Validating against profiles if any
List<String> profiles = Profile.getProfilesNames();
if(profiles != null && !profiles.isEmpty()) {
Validator.validateAgainstProfile(getAsString(objectNode), profiles);
MetadataUtility metadataUtility = MetadataUtility.getInstance();
if(!metadataUtility.getMetadataProfiles().isEmpty()) {
Validator.validateAgainstProfile(getAsString(objectNode));
}
return objectNode;
@ -170,8 +170,8 @@ public class CKANPackage extends CKAN {
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.get.package_list
@Override
public String list() {
return super.list();
public String list(int limit, int offset) {
return super.list(limit, offset);
}
protected void rollbackManagedResources() {
@ -337,7 +337,7 @@ public class CKANPackage extends CKAN {
for(JsonNode jsonNode : arrayNode) {
CKANResource ckanResource = new CKANResource(itemID);
ckanResource.setPreviousRepresentation(jsonNode);
ckanResource.deleteFile();
ckanResource.deleteFile(); // Only delete file is required because the item has been deleted
}
}
super.purge();

View File

@ -1,5 +1,6 @@
package org.gcube.gcat.persistence.ckan;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;
@ -14,10 +15,12 @@ import javax.ws.rs.OPTIONS;
import javax.ws.rs.PUT;
import javax.ws.rs.WebApplicationException;
import org.gcube.gcat.utils.ApplicationMode;
import org.apache.commons.io.FilenameUtils;
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
import org.gcube.gcat.utils.Constants;
import org.gcube.gcat.utils.ContextUtility;
import org.gcube.gcat.utils.HTTPCall;
import org.gcube.gcat.workspace.StorageHubManagement;
import org.gcube.gcat.workspace.CatalogueStorageHubManagement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -44,7 +47,7 @@ public class CKANResource extends CKAN {
/* TODO Remove this code ASAP. It requires a function from Storage HUB */
private static final String URI_RESOLVER_STORAGE_HUB_HOST_PROD = "data.d4science.org";
private static final String URI_RESOLVER_STORAGE_HUB_HOST_DEV = "data-d.d4science.org";
private static final String URI_RESOLVER_STORAGE_HUB_HOST_DEV = "data1-d.d4science.org";
public static final String URI_RESOLVER_STORAGE_HUB_HOST;
public static final String URI_RESOLVER_STORAGE_HUB_PATH = "/shub/";
@ -58,6 +61,7 @@ public class CKANResource extends CKAN {
private static final String TEMP = "TEMP_";
public final static String RESOURCE_NAME_REGEX = "^[\\s\\S]*$";
static {
String context = ContextUtility.getCurrentContext();
@ -78,14 +82,14 @@ public class CKANResource extends CKAN {
protected String resourceID;
protected Boolean persisted;
protected boolean persisted;
protected URL persistedURL;
protected String mimeType;
protected JsonNode previousRepresentation;
protected StorageHubManagement storageHubManagement;
protected CatalogueStorageHubManagement storageHubManagement;
public URL getPersistedURL() {
return persistedURL;
@ -111,6 +115,7 @@ public class CKANResource extends CKAN {
}
public void setPreviousRepresentation(JsonNode jsonNode) {
validate(jsonNode);
previousRepresentation = jsonNode;
}
@ -125,6 +130,7 @@ public class CKANResource extends CKAN {
public CKANResource(String itemID) {
super();
this.nameRegex = RESOURCE_NAME_REGEX;
this.itemID = itemID;
CREATE = RESOURCE_CREATE;
READ = RESOURCE_SHOW;
@ -132,11 +138,15 @@ public class CKANResource extends CKAN {
PATCH = RESOURCE_PATCH;
DELETE = RESOURCE_DELETE;
PURGE = null;
persisted = null;
persisted = false;
previousRepresentation = null;
}
@Override
public String list(int limit, int offeset) {
return list();
}
public String list() {
CKANPackage ckanPackage = new CKANPackage();
ckanPackage.setName(itemID);
@ -160,6 +170,10 @@ public class CKANResource extends CKAN {
url = copyStorageResource(url);
if(name!=null) {
objectNode.put(NAME_KEY, name);
}
if(mimeType!=null) {
objectNode.put(MIME_TYPE_KEY, mimeType);
}
@ -219,13 +233,13 @@ public class CKANResource extends CKAN {
protected URL getFinalURL(String url) {
try {
URL urlURL = new URL(url);
return getFinalURL(urlURL);
return CKANResource.getFinalURL(urlURL);
} catch(MalformedURLException e) {
throw new BadRequestException(e);
}
}
protected URL getFinalURL(URL url) {
public static URL getFinalURL(URL url) {
HTTPCall httpCall = new HTTPCall(url.toString());
httpCall.setgCubeTargetService(false);
URL finalURL = httpCall.getFinalURL(url);
@ -250,40 +264,40 @@ public class CKANResource extends CKAN {
protected URL copyStorageResource(URL url) {
persistedURL = getFinalURL(url);
if(isStorageFile(persistedURL)) {
ApplicationMode applicationMode = new ApplicationMode();
applicationMode.start();
storageHubManagement = new StorageHubManagement();
persistedURL = storageHubManagement.ensureResourcePersistence(persistedURL, itemID, resourceID, name);
mimeType = storageHubManagement.getMimeType();
persisted = true;
applicationMode.end();
storageHubManagement = new CatalogueStorageHubManagement();
try {
persistedURL = storageHubManagement.ensureResourcePersistence(persistedURL, itemID, resourceID);
name = FilenameUtils.removeExtension(storageHubManagement.getOriginalFilename());
mimeType = storageHubManagement.getMimeType();
persisted = true;
}catch (Exception e) {
throw new InternalServerErrorException(e);
}
}
return persistedURL;
}
protected void deleteStorageResource(URL url) {
protected void deleteStorageResource(URL url, String resourceID, String mimetype) {
persistedURL = getFinalURL(url);
if(isStorageFile(persistedURL)) {
ApplicationMode applicationMode = new ApplicationMode();
applicationMode.start();
storageHubManagement = new StorageHubManagement();
storageHubManagement.deleteResourcePersistence(persistedURL, itemID);
applicationMode.end();
}
}
public boolean isPersisted() {
if(persisted == null) {
persistedURL = getFinalURL(persistedURL);
if(isStorageFile(persistedURL)) {
ApplicationMode applicationMode = new ApplicationMode();
applicationMode.start();
storageHubManagement = new StorageHubManagement();
persisted = storageHubManagement.isItemPersistedFile(persistedURL, itemID);
applicationMode.end();
try {
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(url.toString());
HttpURLConnection httpURLConnection = gxhttpStringRequest.from(Constants.CATALOGUE_NAME).head();
String storageHubContentType = httpURLConnection.getContentType().split(";")[0];
if(mimetype.compareTo(storageHubContentType)!=0) {
mimetype = storageHubContentType;
// Using storage hub mimetype
}
}catch (Exception e) {
// using provided mimetype
}
storageHubManagement = new CatalogueStorageHubManagement();
try {
storageHubManagement.deleteResourcePersistence(itemID, resourceID, mimetype);
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
return persisted;
}
protected String create(JsonNode jsonNode) {
@ -291,16 +305,20 @@ public class CKANResource extends CKAN {
ObjectNode objectNode = validate(jsonNode);
objectNode = persistStorageFile(objectNode);
String ret = super.create(getAsString(objectNode));
String gotResourceID = result.get(ID_KEY).asText();
if(gotResourceID.compareTo(resourceID)!=0) {
resourceID = gotResourceID;
String revisionID = result.get(REVISION_ID_KEY).asText();
storageHubManagement.renameFile(resourceID, revisionID);
if(persisted) {
String gotResourceID = result.get(ID_KEY).asText();
if(gotResourceID!=null && gotResourceID.compareTo(resourceID)!=0) {
resourceID = gotResourceID;
String revisionID = result.get(REVISION_ID_KEY).asText();
storageHubManagement.renameFile(resourceID, revisionID);
}
}
return ret;
} catch(WebApplicationException e) {
// TODO Remove created file if any
throw e;
} catch(Exception e) {
// TODO Remove created file if any
throw new InternalServerErrorException(e);
}
}
@ -359,6 +377,11 @@ public class CKANResource extends CKAN {
throw new NotAllowedException(OPTIONS.class.getSimpleName(), moreAllowed);
}
@Override
public void delete(boolean purge) {
delete();
}
@Override
public void delete() {
try {
@ -392,7 +415,8 @@ public class CKANResource extends CKAN {
try {
getPreviousRepresentation();
URL url = new URL(previousRepresentation.get(URL_KEY).asText());
deleteStorageResource(url);
mimeType = previousRepresentation.get(MIME_TYPE_KEY).asText();
deleteStorageResource(url, resourceID, mimeType);
} catch(Exception e) {
logger.error("Unable to delete resource {}", previousRepresentation!=null ? getAsString(previousRepresentation) : "");
}

View File

@ -54,6 +54,7 @@ public class CKANUtility {
}
protected static JsonNode createCKANUser(String ckanUsername) {
ckanUsername = CKANUtility.getCKANUsername(ckanUsername);
CKANUser ckanUser = new CKANUser();
ckanUser.setApiKey(getSysAdminAPI());
try {
@ -77,7 +78,7 @@ public class CKANUtility {
ckanOrganization.setApiKey(getSysAdminAPI());
String organizationName = CKANOrganization.getCKANOrganizationName();
ckanOrganization.setName(organizationName);
ckanOrganization.addUserToOrganisation(ContextUtility.getUsername(), role, force);
ckanOrganization.addUserToOrganisation(ckanUsername, role, force);
}
public static String getApiKey() throws Exception {

View File

@ -0,0 +1,107 @@
package org.gcube.gcat.profile;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.InternalServerErrorException;
import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader;
import org.gcube.datacatalogue.metadatadiscovery.bean.MetadataProfile;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataFormat;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.NamespaceCategory;
public class MetadataUtility {
private DataCalogueMetadataFormatReader dataCalogueMetadataFormatReader;
/*
* this map contains the Metadata Profiles. The key is the name of the profile.
*/
private Map<String,MetadataProfile> metadataProfiles;
private static DataCalogueMetadataFormatReader getDataCalogueMetadataFormatReaderInstance() throws Exception {
/*
Cache<String,DataCalogueMetadataFormatReader> readerCache = CachesManager.getReaderCache();
String context = ScopeProvider.instance.get();
DataCalogueMetadataFormatReader reader
if(readerCache.containsKey(context)) {
reader = (DataCalogueMetadataFormatReader) readerCache.get(context);
} else {
reader = new DataCalogueMetadataFormatReader();
readerCache.put(context, reader);
}
*/
return new DataCalogueMetadataFormatReader();
}
public static void clearCache() {
/*
Cache<String,DataCalogueMetadataFormatReader> readerCache = CachesManager.getReaderCache();
readerCache.clear();
*/
}
private MetadataUtility() throws Exception{
dataCalogueMetadataFormatReader = getDataCalogueMetadataFormatReaderInstance();
}
private static final InheritableThreadLocal<MetadataUtility> metadataUtility = new InheritableThreadLocal<MetadataUtility>() {
@Override
protected MetadataUtility initialValue() {
try {
return new MetadataUtility();
} catch(Exception e) {
throw new InternalServerErrorException("Unable to instantiate MetadataUtility.");
}
}
};
public static MetadataUtility getInstance() {
return metadataUtility.get();
}
public DataCalogueMetadataFormatReader getDataCalogueMetadataFormatReader() {
return dataCalogueMetadataFormatReader;
}
public Map<String, MetadataProfile> getMetadataProfiles() throws Exception{
if(metadataProfiles==null) {
metadataProfiles = new HashMap<>();
List<MetadataProfile> list = dataCalogueMetadataFormatReader.getListOfMetadataProfiles();
for(MetadataProfile profile : list) {
metadataProfiles.put(profile.getName(), profile);
}
}
return metadataProfiles;
}
/**
* Returns the names of the metadata profiles in a given context
* @param context
* @return
* @throws Exception
*/
public Set<String> getProfilesNames() throws Exception {
return getMetadataProfiles().keySet();
}
public MetadataFormat getMetadataFormat(String profileName) throws Exception {
MetadataProfile profile = getMetadataProfiles().get(profileName);
if(profile!=null) {
return dataCalogueMetadataFormatReader.getMetadataFormatForMetadataProfile(profile);
}
return null;
}
public List<NamespaceCategory> getNamespaceCategories() throws Exception {
return dataCalogueMetadataFormatReader.getListOfNamespaceCategories();
}
}

View File

@ -31,6 +31,9 @@ public class BaseREST {
protected static final String LOCATION_HEADER = "Location";
public static final String LIMIT_PARAMETER = "limit";
public static final String OFFSET_PARAMETER = "offset";
protected void setCalledMethod(String method) {
CalledMethodProvider.instance.set(method);
logger.info("{}", uriInfo.getAbsolutePath());

View File

@ -32,8 +32,9 @@ public class Group extends REST<CKANGroup> {
@GET
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public String list() {
return super.list();
public String list(@QueryParam(BaseREST.LIMIT_PARAMETER) @DefaultValue("10") int limit,
@QueryParam(BaseREST.OFFSET_PARAMETER) @DefaultValue("0") int offset) {
return super.list(limit, offset);
}
@POST
@ -72,8 +73,6 @@ public class Group extends REST<CKANGroup> {
@DELETE
@Path("/{" + GROUP_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public Response delete(@PathParam(GROUP_ID_PARAMETER) String id,
@QueryParam(BaseREST.PURGE_QUERY_PARAMETER) @DefaultValue("false") Boolean purge) {
@ -82,8 +81,6 @@ public class Group extends REST<CKANGroup> {
@PURGE
@Path("/{" + GROUP_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public Response purge(@PathParam(GROUP_ID_PARAMETER) String id) {
return delete(id, true);

View File

@ -31,8 +31,9 @@ public class Item extends REST<CKANPackage> {
@GET
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public String list() {
return super.list();
public String list(@QueryParam(BaseREST.LIMIT_PARAMETER) @DefaultValue("10") int limit,
@QueryParam(BaseREST.OFFSET_PARAMETER) @DefaultValue("0") int offset) {
return super.list(limit, offset);
}
@POST
@ -73,8 +74,6 @@ public class Item extends REST<CKANPackage> {
@DELETE
@Path("/{" + ITEM_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public Response delete(@PathParam(ITEM_ID_PARAMETER) String id,
@QueryParam(BaseREST.PURGE_QUERY_PARAMETER) @DefaultValue("false") Boolean purge) {
@ -83,8 +82,6 @@ public class Item extends REST<CKANPackage> {
@PURGE
@Path("/{" + ITEM_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public Response purge(@PathParam(ITEM_ID_PARAMETER) String id) {
return super.purge(id);

View File

@ -19,9 +19,8 @@ public class License extends REST<CKANLicense> {
@GET
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public String list() {
return super.list();
return super.list(-1, -1);
}
}

View File

@ -7,9 +7,9 @@ import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader;
import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.NamespaceCategory;
import org.gcube.gcat.ResourceInitializer;
import org.gcube.gcat.profile.MetadataUtility;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
@ -21,18 +21,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
@Path(BaseREST.NAMESPACES)
public class Namespace extends BaseREST {
/**
* Returns the categories.
* @param context
* @return
* @throws Exception
*/
public static List<NamespaceCategory> getNamespaceCategories() throws Exception {
DataCalogueMetadataFormatReader reader = Profile.getDataCalogueMetadataFormatReader();
return reader.getListOfNamespaceCategories();
}
@GET
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
public String list() {
@ -42,7 +30,7 @@ public class Namespace extends BaseREST {
ArrayNode arrayNode = mapper.createArrayNode();
try {
List<NamespaceCategory> namespaces = Namespace.getNamespaceCategories();
List<NamespaceCategory> namespaces = MetadataUtility.getInstance().getNamespaceCategories();
for(NamespaceCategory namespaceCategory : namespaces) {
ObjectNode namespace = mapper.createObjectNode();
namespace.put("id", namespaceCategory.getId());

View File

@ -32,8 +32,9 @@ public class Organization extends REST<CKANOrganization> {
@GET
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public String list() {
return super.list();
public String list(@QueryParam(BaseREST.LIMIT_PARAMETER) @DefaultValue("10") int limit,
@QueryParam(BaseREST.OFFSET_PARAMETER) @DefaultValue("0") int offset) {
return super.list(limit, offset);
}
@POST
@ -72,8 +73,6 @@ public class Organization extends REST<CKANOrganization> {
@DELETE
@Path("/{" + ORGANIZATION_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public Response delete(@PathParam(ORGANIZATION_ID_PARAMETER) String id,
@QueryParam(BaseREST.PURGE_QUERY_PARAMETER) @DefaultValue("false") Boolean purge) {
@ -82,8 +81,6 @@ public class Organization extends REST<CKANOrganization> {
@PURGE
@Path("/{" + ORGANIZATION_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
public Response purge(@PathParam(ORGANIZATION_ID_PARAMETER) String id) {
return super.purge(id);
}

View File

@ -1,100 +1,58 @@
package org.gcube.gcat.rest;
import java.util.ArrayList;
import java.io.StringWriter;
import java.util.List;
import java.util.Set;
import javax.cache.Cache;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader;
import org.gcube.datacatalogue.metadatadiscovery.bean.MetadataProfile;
import org.gcube.common.resources.gcore.GenericResource;
import org.gcube.common.resources.gcore.Resources;
import org.gcube.datacatalogue.metadatadiscovery.reader.MetadataFormatDiscovery;
import org.gcube.datacatalogue.metadatadiscovery.reader.QueryForResourceUtil;
import org.gcube.gcat.ResourceInitializer;
import org.gcube.gcat.oldutils.CachesManager;
import org.gcube.gcat.profile.MetadataUtility;
import org.gcube.gcat.utils.Constants;
import org.gcube.informationsystem.publisher.RegistryPublisher;
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
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;
import org.gcube.resources.discovery.icclient.ICFactory;
import org.json.JSONObject;
import org.json.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@Path(BaseREST.PROFILES)
public class Profile extends BaseREST {
private static Logger logger = LoggerFactory.getLogger(Profile.class);
public static final String PROFILE_NAME_PARAMETER = "PROFILE_NAME";
public static DataCalogueMetadataFormatReader getDataCalogueMetadataFormatReader() throws Exception {
Cache<String,DataCalogueMetadataFormatReader> readerCache = CachesManager.getReaderCache();
String context = ScopeProvider.instance.get();
DataCalogueMetadataFormatReader reader;
if(readerCache.containsKey(context))
reader = (DataCalogueMetadataFormatReader) readerCache.get(context);
else {
reader = new DataCalogueMetadataFormatReader();
readerCache.put(context, reader);
}
return reader;
}
/**
* Returns the names of the metadata profiles in a given context
* @param context
* @return
* @throws Exception
*/
public static List<String> getProfilesNames() throws Exception {
DataCalogueMetadataFormatReader reader = getDataCalogueMetadataFormatReader();
List<String> toReturn = new ArrayList<String>();
List<MetadataProfile> listProfiles = reader.getListOfMetadataProfiles();
if(listProfiles != null && !listProfiles.isEmpty()) {
for(MetadataProfile profile : listProfiles) {
toReturn.add(profile.getName());
}
}
return toReturn;
}
/**
* Returns the source xml of the metadata profile (specified via name) in a given context
* @param context
* @return
* @throws Exception
*/
public static String getProfileSource(String profileName) throws Exception {
DataCalogueMetadataFormatReader reader = Profile.getDataCalogueMetadataFormatReader();
List<MetadataProfile> listProfiles = reader.getListOfMetadataProfiles();
String xmlToReturn = null;
if(listProfiles != null && !listProfiles.isEmpty()) {
for(MetadataProfile profile : listProfiles) {
if(profile.getName().equals(profileName)) {
xmlToReturn = reader.getMetadataFormatForMetadataProfile(profile).getMetadataSource();
break;
}
}
}
return xmlToReturn;
}
@GET
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(MediaType.APPLICATION_JSON)
public String list() {
setCalledMethod("GET /" + BaseREST.PROFILES);
@ -102,7 +60,7 @@ public class Profile extends BaseREST {
ArrayNode arrayNode = mapper.createArrayNode();
try {
List<String> names = getProfilesNames();
Set<String> names = MetadataUtility.getInstance().getProfilesNames();
for(String name : names) {
arrayNode.add(name);
}
@ -117,21 +75,165 @@ public class Profile extends BaseREST {
@GET
@Path("/{" + PROFILE_NAME_PARAMETER + "}")
@Produces({MediaType.APPLICATION_XML, ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8})
public String read(@PathParam(PROFILE_NAME_PARAMETER) String id,
public String read(@PathParam(PROFILE_NAME_PARAMETER) String name,
@DefaultValue(MediaType.APPLICATION_JSON) @HeaderParam("Accept") String accept) {
setCalledMethod("GET /" + BaseREST.PROFILES + "/{" + PROFILE_NAME_PARAMETER + "}");
try {
String profile = Profile.getProfileSource(id);
if(accept.startsWith(MediaType.APPLICATION_XML)){
return profile;
}else {
JSONObject xmlJSONObj = XML.toJSONObject(profile);
String jsonString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR);
return jsonString;
}
String profile = MetadataUtility.getInstance().getMetadataFormat(name).getMetadataSource();
if(profile != null) {
if(accept.startsWith(MediaType.APPLICATION_XML)) {
return profile;
} else {
JSONObject xmlJSONObj = XML.toJSONObject(profile);
String jsonString = xmlJSONObj.toString(PRETTY_PRINT_INDENT_FACTOR);
return jsonString;
}
} else {
throw new NotFoundException("Profile with name " + name + " not found");
}
} catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e.getMessage());
}
}
/*
public static void appendXmlFragment(org.gcube.common.resources.gcore.GenericResource.Profile profile, String xml) throws Exception {
try {
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Element elem = profile.newBody();
Node fragmentNode = docBuilder.parse(new InputSource(new StringReader(xml))).getDocumentElement();
fragmentNode = elem.getOwnerDocument().importNode(fragmentNode, true);
elem.appendChild(fragmentNode);
} catch (Exception e) {
profile.newBody(xml);
}
}
*/
/*
* TODO Check the Queries because the name in the Profile differs from the name in
* <metadataformat type="Dataset">
*
*/
protected GenericResource instantiateGenericResource(String name, String xml) throws Exception {
GenericResource genericResource = new GenericResource();
org.gcube.common.resources.gcore.GenericResource.Profile profile = genericResource.newProfile();
profile.type(MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE);
profile.name(name);
profile.description("Profile create using " + Constants.CATALOGUE_NAME);
// appendXmlFragment(profile, xml);
profile.newBody(xml);
StringWriter stringWriter = new StringWriter();
Resources.marshal(genericResource, stringWriter);
logger.debug("The generated {} is\n{}", GenericResource.class.getSimpleName(), stringWriter.toString());
return genericResource;
}
protected void createGenericResource(String name, String xml) throws Exception {
GenericResource genericResource = instantiateGenericResource(name, xml);
RegistryPublisher registryPublisher = RegistryPublisherFactory.create();
genericResource = registryPublisher.create(genericResource);
StringWriter stringWriter = new StringWriter();
Resources.marshal(genericResource, stringWriter);
logger.trace("The {} with ID {} has been created \n{}", GenericResource.class.getSimpleName(),
genericResource.id(), stringWriter.toString());
}
protected GenericResource getGenericResource(String name) {
String query = QueryForResourceUtil.getGcubeGenericQueryStringForSecondaryTypeAndName(name,
MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE);
Query q = new QueryBox(query);
DiscoveryClient<GenericResource> client = ICFactory.clientFor(GenericResource.class);
List<GenericResource> resources = client.submit(q);
if(resources == null || resources.size() == 0) {
throw new InternalServerErrorException(
"No Resources with secondaryType '" + MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE
+ "' and name '" + name + "' exists in the current context");
} else {
if(resources.size() == 1) {
GenericResource genericResource = resources.get(0);
return genericResource;
} else {
throw new InternalServerErrorException("More than one Resource with secondaryType '"
+ MetadataFormatDiscovery.DATA_CATALOGUE_METADATA_SECONDARY_TYPE + "' and name '" + name
+ "' exists in the current context");
}
}
}
protected void updateGenericResource(String name, String xml) {
GenericResource genericResource = getGenericResource(name);
logger.info("The {} with ID {} is going to be updated", GenericResource.class.getSimpleName(),
genericResource.id());
genericResource.profile().newBody(xml);
RegistryPublisher registryPublisher = RegistryPublisherFactory.create();
registryPublisher.update(genericResource);
StringWriter stringWriter = new StringWriter();
Resources.marshal(genericResource, stringWriter);
logger.trace("The {} with ID {} has been updated to \n{}", GenericResource.class.getSimpleName(),
genericResource.id(), stringWriter.toString());
}
protected void removeGenericResource(String name) {
GenericResource genericResource = getGenericResource(name);
RegistryPublisher registryPublisher = RegistryPublisherFactory.create();
registryPublisher.remove(genericResource);
}
@PUT
@Path("/{" + PROFILE_NAME_PARAMETER + "}")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public String createOrUpdate(@PathParam(PROFILE_NAME_PARAMETER) String name, String xml) {
setCalledMethod("PUT /" + BaseREST.PROFILES + "/{" + PROFILE_NAME_PARAMETER + "}");
try {
MetadataUtility metadataUtility = MetadataUtility.getInstance();
metadataUtility.getDataCalogueMetadataFormatReader().validateProfile(xml);
if(metadataUtility.getMetadataFormat(name) == null) {
createGenericResource(name, xml);
} else {
updateGenericResource(name, xml);
}
return xml;
} catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e.getMessage());
}finally {
// TOOD Actually Cache has been removed. Remove the following code if it will not be re-introduced
// Cleaning the cache
MetadataUtility.clearCache();
}
}
@DELETE
@Path("/{" + PROFILE_NAME_PARAMETER + "}")
public Response delete(@PathParam(PROFILE_NAME_PARAMETER) String name) {
setCalledMethod("DELETE /" + BaseREST.PROFILES + "/{" + PROFILE_NAME_PARAMETER + "}");
try {
MetadataUtility metadataUtility = MetadataUtility.getInstance();
if(metadataUtility.getMetadataFormat(name) == null) {
throw new NotFoundException("Profile with name " + name + " not found");
} else {
removeGenericResource(name);
return Response.status(Status.NO_CONTENT).build();
}
} catch(WebApplicationException e) {
throw e;
} catch(Exception e) {
throw new InternalServerErrorException(e.getMessage());
} finally {
// Cleaning the cache
MetadataUtility.clearCache();
}
}
}

View File

@ -29,10 +29,10 @@ public class REST<C extends CKAN> extends BaseREST {
}
}
public String list() {
public String list(int limit, int offset) {
setCalledMethod("GET /" + COLLECTION_PARAMETER);
C ckan = getInstance();
return ckan.list();
return ckan.list(limit, offset);
}
public Response create(String json) {

View File

@ -79,8 +79,6 @@ public class Resource extends BaseREST {
@DELETE
@Path("/{" + RESOURCE_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
public void delete(@PathParam(ITEM_ID_PARAMETER) String itemID,
@PathParam(RESOURCE_ID_PARAMETER) String resourceID) {
setCalledMethod("DELETE /" + COLLECTION + "/{" + RESOURCE_ID_PARAMETER + "}");

View File

@ -25,12 +25,10 @@ public class User extends REST<CKANUser> {
super(BaseREST.USERS, USER_ID_PARAMETER, CKANUser.class);
}
@GET
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Override
public String list() {
return super.list();
return super.list(-1,-1);
}
@POST
@ -60,8 +58,6 @@ public class User extends REST<CKANUser> {
@DELETE
@Path("/{" + USER_ID_PARAMETER + "}")
@Consumes(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
@Produces(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8)
public Response delete(@PathParam(USER_ID_PARAMETER) String id) {
return super.delete(id, false);
}

View File

@ -1,20 +1,19 @@
package org.gcube.gcat.social;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.cache.Cache;
import javax.ws.rs.core.MediaType;
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue;
import org.gcube.gcat.oldutils.CachesManager;
import org.gcube.gcat.persistence.ckan.CKAN;
import org.gcube.gcat.utils.ApplicationMode;
import org.gcube.gcat.utils.Constants;
import org.gcube.gcat.utils.ContextUtility;
import org.gcube.gcat.utils.HTTPCall;
import org.gcube.gcat.utils.HTTPCall.HTTPMETHOD;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -101,10 +100,15 @@ public class SocialService extends Thread {
return userCache.get(username);
else {
String socialServiceBasePath = socialService.getServiceBasePath();
HTTPCall httpCall = new HTTPCall(socialServiceBasePath);
String response = httpCall.call(SOCIAL_SERVICE_GET_USER_INFO_PATH, HTTPMETHOD.GET, (Map<String,String>) null,
MediaType.APPLICATION_JSON);
JsonNode jsonNode = objectMapper.readTree(response);
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(socialServiceBasePath);
gxhttpStringRequest.header("User-Agent", Constants.CATALOGUE_NAME);
gxhttpStringRequest.header("Accept", MediaType.APPLICATION_JSON);
gxhttpStringRequest.path(SOCIAL_SERVICE_GET_USER_INFO_PATH);
HttpURLConnection httpURLConnection = gxhttpStringRequest.get();
String message = httpURLConnection.getResponseMessage();
JsonNode jsonNode = objectMapper.readTree(message);
userCache.put(username, jsonNode);
return jsonNode;
}
@ -175,14 +179,17 @@ public class SocialService extends Thread {
// Do not use ApplicationMode class here because is a thread and change the current token could impact
// on the other threads.
HTTPCall httpCall = new HTTPCall(basePath);
httpCall.setgCubeTargetService(false);
httpCall.addHeader(org.gcube.common.authorization.client.Constants.TOKEN_HEADER_ENTRY,
ApplicationMode.getCatalogueApplicationToken());
String response = httpCall.call(SOCIAL_SERVICE_WRITE_APPLICATION_POST_PATH, HTTPMETHOD.POST,
objectMapper.writeValueAsString(objectNode), MediaType.APPLICATION_JSON);
JsonNode jsonNode = objectMapper.readTree(response);
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(basePath);
gxhttpStringRequest.header("User-Agent", Constants.CATALOGUE_NAME);
gxhttpStringRequest.setSecurityToken(Constants.getCatalogueApplicationToken());
gxhttpStringRequest.path(SOCIAL_SERVICE_WRITE_APPLICATION_POST_PATH);
HttpURLConnection httpURLConnection = gxhttpStringRequest.post(objectMapper.writeValueAsString(objectNode));
String ret = httpURLConnection.getResponseMessage();
JsonNode jsonNode = objectMapper.readTree(ret);
if(jsonNode.get(SOCIAL_POST_RESPONSE_SUCCESS_KEY).asBoolean()) {
logger.info("Post written : {}", message);
} else {

View File

@ -1,92 +0,0 @@
package org.gcube.gcat.utils;
import java.io.InputStream;
import java.util.Properties;
import javax.ws.rs.WebApplicationException;
import org.gcube.common.authorization.client.Constants;
import org.gcube.common.authorization.library.AuthorizationEntry;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.provider.ClientInfo;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.authorization.library.utils.Caller;
import org.gcube.common.scope.api.ScopeProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ApplicationMode {
private static final Logger logger = LoggerFactory.getLogger(ApplicationMode.class);
private static final String PROPERTY_FILENAME = "config.properties";
private static final String TOKEN_VARNAME = "TOKEN";
private static final String CATALOGUE_APPLICATION_TOKEN;
public static String getCatalogueApplicationToken() {
return CATALOGUE_APPLICATION_TOKEN;
}
static {
try {
Properties properties = new Properties();
InputStream input = Constants.class.getClassLoader().getResourceAsStream(PROPERTY_FILENAME);
// load a properties file
properties.load(input);
CATALOGUE_APPLICATION_TOKEN = properties.getProperty(TOKEN_VARNAME);
}catch (Exception e) {
throw new WebApplicationException(e);
}
}
private final String originalToken;
public ApplicationMode() {
String applicationtoken = SecurityTokenProvider.instance.get();
if(applicationtoken.compareTo(CATALOGUE_APPLICATION_TOKEN)!=0) {
this.originalToken = applicationtoken;
}else {
logger.warn("You are already in application Mode. Operation on this instance will not have any effect.");
this.originalToken = null;
}
}
public static void setToken(String token) {
SecurityTokenProvider.instance.set(token);
ScopeProvider.instance.set(ContextUtility.getCurrentContext());
try {
AuthorizationEntry authorizationEntry = Constants.authorizationService().get(token);
ClientInfo clientInfo = authorizationEntry.getClientInfo();
logger.debug("User : {} - Type : {}", clientInfo.getId(), clientInfo.getType().name());
String qualifier = authorizationEntry.getQualifier();
Caller caller = new Caller(clientInfo, qualifier);
AuthorizationProvider.instance.set(caller);
}catch (Exception e) {
logger.error("Unable to set Caller");
}
}
public synchronized void start() {
if(originalToken!=null) {
setToken(CATALOGUE_APPLICATION_TOKEN);
}else {
logger.warn("You are already in application Mode. start() does not provide any effect.");
}
}
public synchronized void end() {
if(originalToken!=null) {
setToken(originalToken);
}else {
logger.warn("You are already in application Mode. end() does not provide any effect.");
}
}
}

View File

@ -1,10 +1,35 @@
package org.gcube.gcat.utils;
import java.io.InputStream;
import java.util.Properties;
import javax.ws.rs.WebApplicationException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class Constants {
public static final String CATALOGUE_NAME = "ScienceCatalogue";
public static final String CATALOGUE_NAME = "gCat";
private static final String PROPERTY_FILENAME = "config.properties";
private static final String TOKEN_VARNAME = "TOKEN";
private static final String CATALOGUE_APPLICATION_TOKEN;
public static String getCatalogueApplicationToken() {
return CATALOGUE_APPLICATION_TOKEN;
}
static {
try {
Properties properties = new Properties();
InputStream input = Constants.class.getClassLoader().getResourceAsStream(PROPERTY_FILENAME);
// load a properties file
properties.load(input);
CATALOGUE_APPLICATION_TOKEN = properties.getProperty(TOKEN_VARNAME);
}catch (Exception e) {
throw new WebApplicationException(e);
}
}
}

View File

@ -1,61 +1,26 @@
package org.gcube.gcat.utils;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.scope.api.ScopeProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HTTPCall {
private static final Logger logger = LoggerFactory.getLogger(HTTPCall.class);
protected static final String USER_AGENT_KEY = "User-Agent";
protected static final String USER_AGENT_NAME = Constants.CATALOGUE_NAME;
public enum HTTPMETHOD {
HEAD, GET, POST, PUT, DELETE;
@Override
public String toString() {
return this.name();
}
}
public static final String PATH_SEPARATOR = "/";
public static final String PARAM_STARTER = "?";
public static final String PARAM_EQUALS = "=";
public static final String PARAM_SEPARATOR = "&";
public static final String UTF8 = "UTF-8";
protected static final String USER_AGENT_NAME = "gCat";
protected final String address;
protected final String userAgent;
protected Map<String,String> headers;
/**
* When the target service is a gCube Service it adds the HTTP header
* to provide gCube authorization token and/or scope
*/
protected boolean gCubeTargetService;
public boolean isgCubeTargetService() {
return gCubeTargetService;
}
@ -70,63 +35,7 @@ public class HTTPCall {
protected HTTPCall(String address, String userAgent) {
this.address = address;
this.userAgent = userAgent;
this.gCubeTargetService = true;
this.headers = new HashMap<>();
addHeader(USER_AGENT_KEY, this.userAgent);
}
public void addHeader(String key, String value) {
headers.put(key, value);
}
protected String getParametersDataString(Map<String,String> parameters) throws UnsupportedEncodingException {
if(parameters == null) {
return null;
}
StringBuilder result = new StringBuilder();
boolean first = true;
for(String key : parameters.keySet()) {
if(first) {
first = false;
} else {
result.append(PARAM_SEPARATOR);
}
result.append(URLEncoder.encode(key, UTF8));
result.append(PARAM_EQUALS);
result.append(URLEncoder.encode(parameters.get(key), UTF8));
}
return result.toString();
}
protected URL getURL(String address, String path, String urlParameters) throws MalformedURLException {
StringWriter stringWriter = new StringWriter();
stringWriter.append(address);
if(address.endsWith(PATH_SEPARATOR)) {
if(path.startsWith(PATH_SEPARATOR)) {
path = path.substring(1);
}
} else {
if(path.compareTo("") != 0 && !path.startsWith(PATH_SEPARATOR)) {
stringWriter.append(PATH_SEPARATOR);
}
}
stringWriter.append(path);
if(urlParameters != null) {
stringWriter.append(PARAM_STARTER);
stringWriter.append(urlParameters);
}
return getURL(stringWriter.toString());
}
protected URL getURL(String urlString) throws MalformedURLException {
@ -137,27 +46,23 @@ public class HTTPCall {
return url;
}
protected HttpURLConnection getConnection(String path, String urlParameters, HTTPMETHOD method, String body,
InputStream inputStream, String contentType) throws Exception {
URL url = getURL(address, path, urlParameters);
return getConnection(url, method, body, inputStream, contentType);
}
public URL getFinalURL(URL url) {
try {
URL finalURL = url;
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(false);
connection.setRequestProperty(USER_AGENT_KEY, USER_AGENT_NAME);
// connection.setRequestMethod(HEAD.class.getSimpleName());
int responseCode = connection.getResponseCode();
String responseMessage = connection.getResponseMessage();
if(responseCode >= Status.BAD_REQUEST.getStatusCode()) {
Status status = Status.fromStatusCode(responseCode);
String responseMessage = connection.getResponseMessage();
throw new WebApplicationException(responseMessage, status);
}
if(responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| responseCode == Status.TEMPORARY_REDIRECT.getStatusCode() || responseCode == 308) {
@ -168,140 +73,6 @@ public class HTTPCall {
return finalURL;
}catch (WebApplicationException e) {
throw e;
}catch (Exception e) {
throw new InternalServerErrorException(e);
}
}
protected HttpURLConnection getConnection(URL url, HTTPMETHOD method, String body, InputStream inputStream,
String contentType) throws Exception {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if(gCubeTargetService) {
if(SecurityTokenProvider.instance.get() == null) {
if(ScopeProvider.instance.get() == null) {
throw new RuntimeException("Null Token and Scope. Please set your token first.");
}
connection.setRequestProperty("gcube-scope", ScopeProvider.instance.get());
} else {
connection.setRequestProperty(org.gcube.common.authorization.client.Constants.TOKEN_HEADER_ENTRY,
SecurityTokenProvider.instance.get());
}
}
connection.setDoOutput(true);
connection.setRequestProperty("Content-type", contentType);
for(String key : headers.keySet()) {
connection.setRequestProperty(key, headers.get(key));
}
connection.setRequestMethod(method.toString());
if(inputStream != null && (method == HTTPMETHOD.POST || method == HTTPMETHOD.PUT)) {
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
byte[] buffer = new byte[1024];
int len;
while((len = inputStream.read(buffer)) > 0) {
wr.write(buffer, 0, len);
}
wr.flush();
wr.close();
}
if(body != null && (method == HTTPMETHOD.POST || method == HTTPMETHOD.PUT)) {
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(body);
wr.flush();
wr.close();
}
int responseCode = connection.getResponseCode();
String responseMessage = connection.getResponseMessage();
logger.trace("{} {} : {} - {}", method, connection.getURL(), responseCode, responseMessage);
// 308 Permanent Redirect https://tools.ietf.org/html/rfc7538#section-3
if(responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| responseCode == Status.TEMPORARY_REDIRECT.getStatusCode() || responseCode == 308) {
URL redirectURL = getURL(connection.getHeaderField("Location"));
logger.trace("{} is going to be redirect to {}", url.toString(), redirectURL.toString());
connection = getConnection(redirectURL, method, body, inputStream, contentType);
}
return connection;
}
protected StringBuilder getStringBuilder(InputStream inputStream) throws IOException {
StringBuilder result = new StringBuilder();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while((line = reader.readLine()) != null) {
result.append(line);
}
}
return result;
}
public String call(String path, HTTPMETHOD method, Map<String,String> parameters, String contentType) {
return call(path, method, parameters, null, contentType);
}
public String call(String path, HTTPMETHOD method, String body, String contentType) {
return call(path, method, null, body, contentType);
}
public String call(String path, HTTPMETHOD method, Map<String,String> parameters, String body, String contentType) {
return call(path, method, body, null, parameters, contentType);
}
public String call(String path, HTTPMETHOD method, InputStream inputStream, Map<String,String> parameters,
String contentType) {
return call(path, method, null, inputStream, parameters, contentType);
}
private String call(String path, HTTPMETHOD method, String body, InputStream inputStream,
Map<String,String> parameters, String contentType) {
HttpURLConnection connection;
try {
String urlParameters = getParametersDataString(parameters);
connection = getConnection(path, urlParameters, method, body, inputStream, contentType);
int responseCode = connection.getResponseCode();
String responseMessage = connection.getResponseMessage();
logger.info("{} {} : {} - {}", method, connection.getURL(), responseCode, responseMessage);
if(responseCode >= Status.BAD_REQUEST.getStatusCode()) {
try {
StringBuilder result = getStringBuilder(connection.getErrorStream());
String res = result.toString();
logger.trace("Server returned content : {}", res);
return res;
}catch (Exception e) {
Status status = Status.fromStatusCode(responseCode);
throw new WebApplicationException(responseMessage, status);
}
}
StringBuilder result = getStringBuilder(connection.getInputStream());
String res = result.toString();
logger.trace("Server returned content : {}", res);
connection.disconnect();
return res;
} catch(WebApplicationException e) {
throw e;
} catch(Exception e) {

View File

@ -1,12 +1,13 @@
package org.gcube.gcat.utils;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import java.net.HttpURLConnection;
import javax.ws.rs.WebApplicationException;
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.utils.HTTPCall.HTTPMETHOD;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
@ -29,18 +30,20 @@ public class URIResolver {
DataCatalogue dataCatalogue = CKAN.getCatalogue();
String uriResolverURL = dataCatalogue.getUriResolverUrl();
HTTPCall httpCall = new HTTPCall(uriResolverURL);
ObjectNode requestContent = objectMapper.createObjectNode();
requestContent.put(CATALOGUE_CONTEXT, ContextUtility.getCurrentContext());
requestContent.put(ENTITY_TYPE, EntityContext.PRODUCT.toString());
requestContent.put(ENTITY_NAME, name);
requestContent.put(CATALOGUE_PLAIN_URL, true);
String url = httpCall.call("", HTTPMETHOD.POST, objectMapper.writeValueAsString(requestContent),
MediaType.APPLICATION_JSON);
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(uriResolverURL);
gxhttpStringRequest.header("User-Agent", Constants.CATALOGUE_NAME);
HttpURLConnection httpURLConnection = gxhttpStringRequest.post(objectMapper.writeValueAsString(requestContent));
String url = httpURLConnection.getResponseMessage();
return url;
} catch(Exception e) {
throw new WebApplicationException(e);
}

View File

@ -0,0 +1,44 @@
package org.gcube.gcat.workspace;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.gcube.common.storagehub.model.Metadata;
import org.gcube.storagehub.MetadataMatcher;
public class CatalogueMetadata implements MetadataMatcher {
public static final String ORIGINAL_URL = "OriginalURL";
public static final String ORIGINAL_NAME = "OriginalName";
public static final String CATALOGUE_ITEM_ID = "CatalogueItemID";
public static final String CATALOGUE_RESOURCE_ID = "CatalogueResourceID";
public static final String CATALOGUE_RESOURCE_REVISION_ID = "CatalogueResourceRevisionID";
protected String itemID;
public CatalogueMetadata(String itemID) {
this.itemID = itemID;
}
@Override
public boolean check(Metadata metadata) {
Map<String,Object> map = metadata.getMap();
if(map.get(CATALOGUE_ITEM_ID).toString().compareTo(itemID) == 0) {
return true;
}
return false;
}
public Metadata getMetadata(URL url, String originalName, String resourceID) {
Map<String,Object> map = new HashMap<>();
map.put(ORIGINAL_URL, url.toString());
map.put(ORIGINAL_NAME, originalName);
map.put(CATALOGUE_ITEM_ID, itemID);
map.put(CATALOGUE_RESOURCE_ID, resourceID);
Metadata metadata = new Metadata(map);
return metadata;
}
}

View File

@ -0,0 +1,109 @@
package org.gcube.gcat.workspace;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.util.Map;
import org.gcube.common.gxhttp.request.GXHTTPStringRequest;
import org.gcube.common.storagehub.client.dsl.FileContainer;
import org.gcube.common.storagehub.model.Metadata;
import org.gcube.gcat.utils.Constants;
import org.gcube.storagehub.ApplicationMode;
import org.gcube.storagehub.StorageHubManagement;
import org.glassfish.jersey.media.multipart.ContentDisposition;
public class CatalogueStorageHubManagement {
protected StorageHubManagement storageHubManagement;
protected String originalFilename;
protected String mimeType;
public String getOriginalFilename() {
return originalFilename;
}
public String getMimeType() {
return mimeType;
}
public CatalogueStorageHubManagement() {
this.storageHubManagement = new StorageHubManagement();
}
protected String getOriginalFileName(HttpURLConnection httpURLConnection) throws ParseException {
String contentDisposition = httpURLConnection.getHeaderFields().get("Content-Disposition").get(0);
contentDisposition = contentDisposition.replaceAll("= ", "=").replaceAll(" =", "=");
ContentDisposition formDataContentDisposition = new ContentDisposition(contentDisposition);
return formDataContentDisposition.getFileName();
}
public URL ensureResourcePersistence(URL persistedURL, String itemID, String resourceID) throws Exception {
ApplicationMode applicationMode = new ApplicationMode(Constants.getCatalogueApplicationToken());
try {
applicationMode.start();
GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(persistedURL.toString());
gxhttpStringRequest.isExternalCall(true);
HttpURLConnection httpURLConnection = gxhttpStringRequest.get();
mimeType = httpURLConnection.getContentType().split(";")[0];
originalFilename = getOriginalFileName(httpURLConnection);
CatalogueMetadata catalogueMetadata = new CatalogueMetadata(itemID);
storageHubManagement.setCheckMetadata(catalogueMetadata);
Metadata metadata = catalogueMetadata.getMetadata(persistedURL, originalFilename, resourceID);
persistedURL = storageHubManagement.persistFile(httpURLConnection.getInputStream(), resourceID, mimeType, metadata);
mimeType = storageHubManagement.getMimeType();
return persistedURL;
} finally {
applicationMode.end();
}
}
public void deleteResourcePersistence(String itemID, String resourceID, String mimeType) throws Exception {
ApplicationMode applicationMode = new ApplicationMode(Constants.getCatalogueApplicationToken());
try {
applicationMode.start();
storageHubManagement = new StorageHubManagement();
CatalogueMetadata catalogueMetadata = new CatalogueMetadata(itemID);
storageHubManagement.setCheckMetadata(catalogueMetadata);
storageHubManagement.removePersistedFile(resourceID, mimeType);
} finally {
applicationMode.end();
}
}
protected void internalAddRevisionID(String resourceID, String revisionID) {
FileContainer fileContainer = storageHubManagement.getCreatedFile();
Metadata metadata = fileContainer.get().getMetadata();
Map<String,Object> map = metadata.getMap();
map.put(CatalogueMetadata.CATALOGUE_RESOURCE_ID, resourceID);
map.put(CatalogueMetadata.CATALOGUE_RESOURCE_REVISION_ID, revisionID);
metadata.setMap(map);
fileContainer.setMetadata(metadata);
}
public void renameFile(String resourceID, String revisionID) {
ApplicationMode applicationMode = new ApplicationMode(Constants.getCatalogueApplicationToken());
try {
applicationMode.start();
FileContainer createdfile = storageHubManagement.getCreatedFile();
createdfile.rename(resourceID);
internalAddRevisionID(resourceID, revisionID);
}finally {
applicationMode.end();
}
}
public void addRevisionID(String resourceID, String revisionID) {
ApplicationMode applicationMode = new ApplicationMode(Constants.getCatalogueApplicationToken());
try {
applicationMode.start();
internalAddRevisionID(resourceID, revisionID);
}finally {
applicationMode.end();
}
}
}

View File

@ -1,295 +0,0 @@
package org.gcube.gcat.workspace;
import java.io.StringWriter;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.InternalServerErrorException;
import org.gcube.common.homelibrary.home.Home;
import org.gcube.common.homelibrary.home.HomeLibrary;
import org.gcube.common.homelibrary.home.HomeManager;
import org.gcube.common.homelibrary.home.HomeManagerFactory;
import org.gcube.common.homelibrary.home.User;
import org.gcube.common.homelibrary.home.workspace.Workspace;
import org.gcube.common.storagehub.client.StreamDescriptor;
import org.gcube.common.storagehub.client.dsl.ContainerType;
import org.gcube.common.storagehub.client.dsl.FileContainer;
import org.gcube.common.storagehub.client.dsl.FolderContainer;
import org.gcube.common.storagehub.client.dsl.ItemContainer;
import org.gcube.common.storagehub.client.dsl.ListResolver;
import org.gcube.common.storagehub.client.dsl.ListResolverTyped;
import org.gcube.common.storagehub.client.dsl.OpenResolver;
import org.gcube.common.storagehub.client.dsl.StorageHubClient;
import org.gcube.common.storagehub.model.Metadata;
import org.gcube.common.storagehub.model.items.AbstractFileItem;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.gcat.utils.Constants;
import org.gcube.gcat.utils.ContextUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StorageHubManagement {
private static final Logger logger = LoggerFactory.getLogger(StorageHubManagement.class);
public static final String ORIGINAL_URL = "OriginalURL";
public static final String ORIGINAL_NAME = "OriginalName";
public static final String CATALOGUE_ITEM_ID = "CatalogueItemID";
public static final String CATALOGUE_RESOURCE_ID = "CatalogueResourceID";
public static final String CATALOGUE_RESOURCE_REVISION_ID = "CatalogueResourceRevisionID";
public static final String CATALOGUE_FOLDER_DESCRIPTION = "Catalogue Folder used to persist Resources";
protected final StorageHubClient storageHubClient;
protected FileContainer createdFile;
protected String mimeType;
public String getMimeType() {
return mimeType;
}
public StorageHubManagement() {
storageHubClient = new StorageHubClient();
}
protected void recursiveList(FolderContainer folder, int level) {
ListResolverTyped listResolverTyped = folder.list();
List<ItemContainer<? extends Item>> containers = listResolverTyped.getContainers();
for(ItemContainer<? extends Item> itemContainer : containers) {
Item item = itemContainer.get();
String name = item.getName();
ContainerType containerType = itemContainer.getType();
StringWriter indent = new StringWriter(level + 1);
for(int i = 0; i < level + 1; i++) {
indent.append('-');
}
logger.debug("{} {} {} (ID:{})", indent.toString(), containerType, name, itemContainer.getId());
switch(containerType) {
case FOLDER:
FolderContainer folderContainer = (FolderContainer) itemContainer;
//if(item.getName().compareTo("553095a0-a14a-4e41-b014-2e6f3a1aeac7")!=0)
recursiveList(folderContainer, level + 1);
break;
case FILE:
break;
case GENERIC_ITEM:
break;
default:
break;
}
}
}
protected FolderContainer getWorkspaceRoot() {
try {
return storageHubClient.getWSRoot();
}catch (Exception e) {
String username = ContextUtility.getUsername();
logger.info("Unable to obtain the Workspace Root for {}. Going to create it.", username);
try {
HomeManagerFactory factory = HomeLibrary.getHomeManagerFactory();
HomeManager manager = factory.getHomeManager();
User user = manager.createUser(username);
@SuppressWarnings("deprecation")
Home home = manager.getHome(user);
Workspace ws = home.getWorkspace();
ws.getRoot();
return storageHubClient.getWSRoot();
}catch (Exception ex) {
logger.info("Unable to create the Workspace Root for {}.", username);
throw new InternalServerErrorException(e);
}
}
}
protected FolderContainer getOrCreateFolder(FolderContainer parent, String name, String description) {
try {
FolderContainer destinationFolder = null;
ListResolverTyped listResolverTyped = parent.list();
List<ItemContainer<? extends Item>> containers = listResolverTyped.getContainers();
for(ItemContainer<? extends Item> itemContainer : containers) {
if(itemContainer instanceof FolderContainer) {
if(itemContainer.get().getName().compareTo(name) == 0) {
destinationFolder = (FolderContainer) itemContainer;
}
}
}
if(destinationFolder == null) {
destinationFolder = parent.newFolder(name, description);
}
return destinationFolder;
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
public static String getFolderName() {
String currentContext = ContextUtility.getCurrentContext();
String folderName = currentContext.replaceFirst("/", "").replace("/", "_");
return folderName;
}
protected FolderContainer getCatalogueFolder() {
FolderContainer destinationFolder = getWorkspaceRoot();
String folderName = getFolderName();
destinationFolder = getOrCreateFolder(destinationFolder, folderName, ContextUtility.getCurrentContext() + " folder");
destinationFolder = getOrCreateFolder(destinationFolder, Constants.CATALOGUE_NAME, CATALOGUE_FOLDER_DESCRIPTION);
return destinationFolder;
}
protected FolderContainer getDestinationFolder(AbstractFileItem item) {
FolderContainer destinationFolder = getCatalogueFolder();
mimeType = item.getContent().getMimeType();
String[] splittedMimeType = mimeType.split("/");
for(String name : splittedMimeType) {
try {
destinationFolder = getOrCreateFolder(destinationFolder, name,
"Automatic Folder Created using mimetype");
} catch(Exception e) {
throw new InternalServerErrorException(e);
}
}
return destinationFolder;
}
protected FileContainer copyFile(FileContainer sourceFileContainer, FolderContainer destinationFolder,
String copiedFilename) {
StreamDescriptor streamDescriptor = sourceFileContainer.download("");
FileContainer createdFile = destinationFolder.uploadFile(streamDescriptor.getStream(), copiedFilename,
sourceFileContainer.get().getDescription());
/*
FileContainer copiedFile = sourceFileContainer.copy(destinationFolder, copiedFilename);
*/
return createdFile;
}
protected ItemContainer<? extends Item> getContainerByStorageURL(URL url) {
URL finalURL = url;
String path = finalURL.getPath();
String fileID = path.substring(path.lastIndexOf('/') + 1);
OpenResolver openResolver = storageHubClient.open(fileID);
ItemContainer<Item> itemContainer = openResolver.asItem();
Item item = itemContainer.get();
if(item instanceof AbstractFileItem) {
logger.debug("The resource with ID {} is a file", fileID);
return openResolver.asFile();
}
return itemContainer;
}
protected boolean isItemPersistedFile(FileContainer fileContainer, FolderContainer destinationFolder, String itemID) {
// Checking if the file is already a file of the science catalogue folder of the scope related to such an item.
ListResolver listResolver = fileContainer.getAnchestors();
List<ItemContainer<? extends Item>> itemContainers = listResolver.getContainers();
for(ItemContainer<? extends Item> itemContainer : itemContainers) {
if(itemContainer.getId().compareTo(destinationFolder.getId()) == 0) {
Metadata metadata = fileContainer.get().getPropertyMap();
Map<String,Object> map = metadata.getValues();
if(map.get(CATALOGUE_ITEM_ID).toString().compareTo(itemID) == 0) {
return true;
}
}
}
return false;
}
public boolean isItemPersistedFile(URL url, String itemID) {
ItemContainer<? extends Item> itemContainer = getContainerByStorageURL(url);
FileContainer fileContainer;
if(itemContainer instanceof FileContainer) {
fileContainer = (FileContainer) itemContainer;
}else {
return false;
}
FolderContainer destinationFolder = getDestinationFolder(fileContainer.get());
return isItemPersistedFile(fileContainer, destinationFolder, itemID);
}
protected void tree(FolderContainer folderContainer) throws Exception {
logger.debug("{} (ID:{})", folderContainer.get().getName(), folderContainer.getId());
recursiveList(folderContainer, 0);
}
protected FileContainer getFileByID(String id) throws Exception {
OpenResolver openResolver = storageHubClient.open(id);
FileContainer fileContainer = (FileContainer) openResolver.asFile();
return fileContainer;
}
protected void deleteFileByID(String id) throws Exception {
FileContainer fileContainer = getFileByID(id);
fileContainer.delete();
}
public URL ensureResourcePersistence(URL url, String itemID, String resourceID, String name) {
ItemContainer<? extends Item> itemContainer = getContainerByStorageURL(url);
FileContainer fileContainer;
if(itemContainer instanceof FileContainer) {
fileContainer = (FileContainer) itemContainer;
}else {
return url;
}
FolderContainer destinationFolder = getDestinationFolder(fileContainer.get());
if(isItemPersistedFile(fileContainer, destinationFolder, itemID)) {
return url;
}
createdFile = copyFile(fileContainer, destinationFolder, resourceID);
Map<String,Object> map = new HashMap<>();
map.put(ORIGINAL_URL, url.toString());
map.put(ORIGINAL_NAME, name);
map.put(CATALOGUE_ITEM_ID, itemID);
map.put(CATALOGUE_RESOURCE_ID, resourceID);
Metadata metadata = new Metadata(map);
createdFile.setMetadata(metadata);
URL finalURL = createdFile.getPublicLink();
logger.debug("Original File URL was {} - Final URL to ensure persistency is {}", url, finalURL);
return finalURL;
}
public void deleteResourcePersistence(URL url, String itemID) {
FileContainer fileContainer = (FileContainer) getContainerByStorageURL(url);
FolderContainer destinationFolder = getDestinationFolder(fileContainer.get());
if(isItemPersistedFile(fileContainer, destinationFolder, itemID)) {
fileContainer.delete();
}
}
protected void addRevisionID(FileContainer fileContainer, String resourceID, String revisionID) {
Metadata metadata = fileContainer.get().getPropertyMap();
Map<String,Object> map = metadata.getValues();
map.put(CATALOGUE_RESOURCE_ID, resourceID);
map.put(CATALOGUE_RESOURCE_REVISION_ID, revisionID);
metadata.setValues(map);
fileContainer.setMetadata(metadata);;
}
public void addRevisionID(String resourceID, String revisionID) {
addRevisionID(createdFile, resourceID, revisionID);
}
public void renameFile(String resourceID, String revisionID) {
renameFile(createdFile, resourceID);
addRevisionID(createdFile, resourceID, revisionID);
}
protected void renameFile(FileContainer fileContainer, String newName) {
fileContainer.rename(newName);
}
}

View File

@ -1,316 +0,0 @@
gCube System - License
------------------------------------------------------------
European Union Public Licence V. 1.1
EUPL © the European Community 2007
This European Union Public Licence (the “EUPL”) applies to the Work or Software
(as defined below) which is provided under the terms of this Licence. Any use of
the Work, other than as authorised under this Licence is prohibited (to the
extent such use is covered by a right of the copyright holder of the Work).
The Original Work is provided under the terms of this Licence when the Licensor
(as defined below) has placed the following notice immediately following the
copyright notice for the Original Work:
Licensed under the EUPL V.1.1
or has expressed by any other mean his willingness to license under the EUPL.
1. Definitions
In this Licence, the following terms have the following meaning:
- The Licence: this Licence.
- The Original Work or the Software: the software distributed and/or
communicated by the Licensor under this Licence, available as Source Code and
also as Executable Code as the case may be.
- Derivative Works: the works or software that could be created by the Licensee,
based upon the Original Work or modifications thereof. This Licence does not
define the extent of modification or dependence on the Original Work required
in order to classify a work as a Derivative Work; this extent is determined by
copyright law applicable in the country mentioned in Article 15.
- The Work: the Original Work and/or its Derivative Works.
- The Source Code: the human-readable form of the Work which is the most
convenient for people to study and modify.
- The Executable Code: any code which has generally been compiled and which is
meant to be interpreted by a computer as a program.
- The Licensor: the natural or legal person that distributes and/or communicates
the Work under the Licence.
- Contributor(s): any natural or legal person who modifies the Work under the
Licence, or otherwise contributes to the creation of a Derivative Work.
- The Licensee or “You”: any natural or legal person who makes any usage of the
Software under the terms of the Licence.
- Distribution and/or Communication: any act of selling, giving, lending,
renting, distributing, communicating, transmitting, or otherwise making
available, on-line or off-line, copies of the Work or providing access to its
essential functionalities at the disposal of any other natural or legal
person.
2. Scope of the rights granted by the Licence
The Licensor hereby grants You a world-wide, royalty-free, non-exclusive,
sub-licensable licence to do the following, for the duration of copyright vested
in the Original Work:
- use the Work in any circumstance and for all usage, reproduce the Work, modify
- the Original Work, and make Derivative Works based upon the Work, communicate
- to the public, including the right to make available or display the Work or
- copies thereof to the public and perform publicly, as the case may be, the
- Work, distribute the Work or copies thereof, lend and rent the Work or copies
- thereof, sub-license rights in the Work or copies thereof.
Those rights can be exercised on any media, supports and formats, whether now
known or later invented, as far as the applicable law permits so.
In the countries where moral rights apply, the Licensor waives his right to
exercise his moral right to the extent allowed by law in order to make effective
the licence of the economic rights here above listed.
The Licensor grants to the Licensee royalty-free, non exclusive usage rights to
any patents held by the Licensor, to the extent necessary to make use of the
rights granted on the Work under this Licence.
3. Communication of the Source Code
The Licensor may provide the Work either in its Source Code form, or as
Executable Code. If the Work is provided as Executable Code, the Licensor
provides in addition a machine-readable copy of the Source Code of the Work
along with each copy of the Work that the Licensor distributes or indicates, in
a notice following the copyright notice attached to the Work, a repository where
the Source Code is easily and freely accessible for as long as the Licensor
continues to distribute and/or communicate the Work.
4. Limitations on copyright
Nothing in this Licence is intended to deprive the Licensee of the benefits from
any exception or limitation to the exclusive rights of the rights owners in the
Original Work or Software, of the exhaustion of those rights or of other
applicable limitations thereto.
5. Obligations of the Licensee
The grant of the rights mentioned above is subject to some restrictions and
obligations imposed on the Licensee. Those obligations are the following:
Attribution right: the Licensee shall keep intact all copyright, patent or
trademarks notices and all notices that refer to the Licence and to the
disclaimer of warranties. The Licensee must include a copy of such notices and a
copy of the Licence with every copy of the Work he/she distributes and/or
communicates. The Licensee must cause any Derivative Work to carry prominent
notices stating that the Work has been modified and the date of modification.
Copyleft clause: If the Licensee distributes and/or communicates copies of the
Original Works or Derivative Works based upon the Original Work, this
Distribution and/or Communication will be done under the terms of this Licence
or of a later version of this Licence unless the Original Work is expressly
distributed only under this version of the Licence. The Licensee (becoming
Licensor) cannot offer or impose any additional terms or conditions on the Work
or Derivative Work that alter or restrict the terms of the Licence.
Compatibility clause: If the Licensee Distributes and/or Communicates Derivative
Works or copies thereof based upon both the Original Work and another work
licensed under a Compatible Licence, this Distribution and/or Communication can
be done under the terms of this Compatible Licence. For the sake of this clause,
“Compatible Licence” refers to the licences listed in the appendix attached to
this Licence. Should the Licensees obligations under the Compatible Licence
conflict with his/her obligations under this Licence, the obligations of the
Compatible Licence shall prevail.
Provision of Source Code: When distributing and/or communicating copies of the
Work, the Licensee will provide a machine-readable copy of the Source Code or
indicate a repository where this Source will be easily and freely available for
as long as the Licensee continues to distribute and/or communicate the Work.
Legal Protection: This Licence does not grant permission to use the trade names,
trademarks, service marks, or names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the copyright notice.
6. Chain of Authorship
The original Licensor warrants that the copyright in the Original Work granted
hereunder is owned by him/her or licensed to him/her and that he/she has the
power and authority to grant the Licence.
Each Contributor warrants that the copyright in the modifications he/she brings
to the Work are owned by him/her or licensed to him/her and that he/she has the
power and authority to grant the Licence.
Each time You accept the Licence, the original Licensor and subsequent
Contributors grant You a licence to their contributions to the Work, under the
terms of this Licence.
7. Disclaimer of Warranty
The Work is a work in progress, which is continuously improved by numerous
contributors. It is not a finished work and may therefore contain defects or
“bugs” inherent to this type of software development.
For the above reason, the Work is provided under the Licence on an “as is” basis
and without warranties of any kind concerning the Work, including without
limitation merchantability, fitness for a particular purpose, absence of defects
or errors, accuracy, non-infringement of intellectual property rights other than
copyright as stated in Article 6 of this Licence.
This disclaimer of warranty is an essential part of the Licence and a condition
for the grant of any rights to the Work.
8. Disclaimer of Liability
Except in the cases of wilful misconduct or damages directly caused to natural
persons, the Licensor will in no event be liable for any direct or indirect,
material or moral, damages of any kind, arising out of the Licence or of the use
of the Work, including without limitation, damages for loss of goodwill, work
stoppage, computer failure or malfunction, loss of data or any commercial
damage, even if the Licensor has been advised of the possibility of such
damage. However, the Licensor will be liable under statutory product liability
laws as far such laws apply to the Work.
9. Additional agreements
While distributing the Original Work or Derivative Works, You may choose to
conclude an additional agreement to offer, and charge a fee for, acceptance of
support, warranty, indemnity, or other liability obligations and/or services
consistent with this Licence. However, in accepting such obligations, You may
act only on your own behalf and on your sole responsibility, not on behalf of
the original Licensor or any other Contributor, and only if You agree to
indemnify, defend, and hold each Contributor harmless for any liability incurred
by, or claims asserted against such Contributor by the fact You have accepted
any such warranty or additional liability.
10. Acceptance of the Licence
The provisions of this Licence can be accepted by clicking on an icon “I agree”
placed under the bottom of a window displaying the text of this Licence or by
affirming consent in any other similar way, in accordance with the rules of
applicable law. Clicking on that icon indicates your clear and irrevocable
acceptance of this Licence and all of its terms and conditions.
Similarly, you irrevocably accept this Licence and all of its terms and
conditions by exercising any rights granted to You by Article 2 of this Licence,
such as the use of the Work, the creation by You of a Derivative Work or the
Distribution and/or Communication by You of the Work or copies thereof.
11. Information to the public
In case of any Distribution and/or Communication of the Work by means of
electronic communication by You (for example, by offering to download the Work
from a remote location) the distribution channel or media (for example, a
website) must at least provide to the public the information requested by the
applicable law regarding the Licensor, the Licence and the way it may be
accessible, concluded, stored and reproduced by the Licensee.
12. Termination of the Licence
The Licence and the rights granted hereunder will terminate automatically upon
any breach by the Licensee of the terms of the Licence.
Such a termination will not terminate the licences of any person who has
received the Work from the Licensee under the Licence, provided such persons
remain in full compliance with the Licence.
13. Miscellaneous
Without prejudice of Article 9 above, the Licence represents the complete
agreement between the Parties as to the Work licensed hereunder.
If any provision of the Licence is invalid or unenforceable under applicable
law, this will not affect the validity or enforceability of the Licence as a
whole. Such provision will be construed and/or reformed so as necessary to make
it valid and enforceable.
The European Commission may publish other linguistic versions and/or new
versions of this Licence, so far this is required and reasonable, without
reducing the scope of the rights granted by the Licence. New versions of the
Licence will be published with a unique version number.
All linguistic versions of this Licence, approved by the European Commission,
have identical value. Parties can take advantage of the linguistic version of
their choice.
14. Jurisdiction
Any litigation resulting from the interpretation of this License, arising
between the European Commission, as a Licensor, and any Licensee, will be
subject to the jurisdiction of the Court of Justice of the European Communities,
as laid down in article 238 of the Treaty establishing the European Community.
Any litigation arising between Parties, other than the European Commission, and
resulting from the interpretation of this License, will be subject to the
exclusive jurisdiction of the competent court where the Licensor resides or
conducts its primary business.
15. Applicable Law
This Licence shall be governed by the law of the European Union country where
the Licensor resides or has his registered office.
This licence shall be governed by the Belgian law if:
- a litigation arises between the European Commission, as a Licensor, and any
- Licensee; the Licensor, other than the European Commission, has no residence
- or registered office inside a European Union country.
===
Appendix
“Compatible Licences” according to article 5 EUPL are:
- GNU General Public License (GNU GPL) v. 2
- Open Software License (OSL) v. 2.1, v. 3.0
- Common Public License v. 1.0
- Eclipse Public License v. 1.0
- Cecill v. 2.0

View File

@ -1,76 +0,0 @@
The gCube System - gCube Catalogue Service
--------------------------------------------------
This service allows any client to publish on the gCube Catalogue.
This software is part of the gCube Framework (https://www.gcube-system.org/): an
open-source software toolkit used for building and operating Hybrid Data
Infrastructures enabling the dynamic deployment of Virtual Research Environments
by favouring the realisation of reuse oriented policies.
The projects leading to this software have received funding from a series of
European Union programmes including:
* the Sixth Framework Programme for Research and Technological Development -
DILIGENT (grant no. 004260);
* the Seventh Framework Programme for research, technological development and
demonstration - D4Science (grant no. 212488), D4Science-II (grant no.
239019),ENVRI (grant no. 283465), EUBrazilOpenBio (grant no. 288754), iMarine
(grant no. 283644);
* the H2020 research and innovation programme - BlueBRIDGE (grant no. 675680),
EGIEngage (grant no. 654142), ENVRIplus (grant no. 654182), Parthenos (grant
no. 654119), SoBigData (grant no. 654024), AGINFRA PLUS (grant no. 731001).
Version
--------------------------------------------------
1.0.0-SNAPSHOT (2019-01-10)
Please see the file named "changelog.xml" in this directory for the release notes.
Authors
--------------------------------------------------
* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
* Costantino Perciante (costantino.perciante@isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
Maintainers
-----------
* Luca Frosini (luca.frosini-AT-isti.cnr.it), Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" - CNR, Pisa (Italy).
Download information
--------------------------------------------------
Source code is available from SVN:
https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/gcat
Binaries can be downloaded from the gCube website:
https://www.gcube-system.org/
Installation
--------------------------------------------------
Installation documentation is available on-line in the gCube Wiki:
https://wiki.gcube-system.org/gcube/index.php
Documentation
--------------------------------------------------
Documentation is available on-line in the gCube Wiki:
https://wiki.gcube-system.org/gcube/index.php
Support
--------------------------------------------------
Bugs and support requests can be reported in the gCube issue tracking tool:
https://support.d4science.org/projects/gcube/
Licensing
--------------------------------------------------
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<ReleaseNotes>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-4-0" date="2019-01-10">
<Change></Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-3-0" date="2018-10-10">
<Change>Complete refactoring of code</Change>
<Change>Item Port type is now RESTful (old methods are still allowed)</Change>
<Change>Added update support for Item #11516</Change>
<Change>Changed caching mechanism from ehcache API to JSR-107. Ehcache is still used as runtime library.</Change>
<Change>Solved random NullPointer Exception on catalogue-ws related to old caching mechanism #11466</Change>
<Change>Fixed normalization of the organization name #12506</Change>
<Change>Added the possibility to deny social post on catalogue-ws #12514</Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-1-1"
date="2018-01-11">
<Change>Item purge method enhanced</Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-1-0"
date="2017-06-20">
<Change>Minor fixes while checking user's permissions</Change>
<Change>Namespaces are no longer transparently managed</Change>
<Change>Fixed 'default' value for metadata</Change>
<Change>Improved exception handling</Change>
</Changeset>
<Changeset component="org.gcube.data-catalogue.catalogue-ws.1-0-0"
date="2017-05-01">
<Change>First Release</Change>
</Changeset>
</ReleaseNotes>

View File

@ -1,31 +0,0 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>servicearchive</id>
<formats>
<format>tar.gz</format>
</formats>
<baseDirectory>/</baseDirectory>
<fileSets>
<fileSet>
<directory>/home/lucafrosini/workspace/gcat/distro</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
<includes>
<include>README</include>
<include>LICENSE</include>
<include>changelog.xml</include>
<include>profile.xml</include>
</includes>
<fileMode>755</fileMode>
<filtered>true</filtered>
</fileSet>
</fileSets>
<files>
<file>
<source>target/gcat-1.0.0-SNAPSHOT.war</source>
<outputDirectory>/gcat</outputDirectory>
</file>
</files>
</assembly>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<application mode='online'>
<name>gcat</name>
<group>DataPublishing</group>
<version>1.0.0-SNAPSHOT</version>
<description>This service allows any client to publish on the gCube Catalogue.</description>
<local-persistence location='target' />
</application>

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Resource>
<ID />
<Type>Service</Type>
<Profile>
<Description>This service allows any client to publish on the gCube Catalogue.</Description>
<Class>DataPublishing</Class>
<Name>gcat</Name>
<Version>1.0.0</Version>
<Packages>
<Main>
<Description>This service allows any client to publish on the gCube Catalogue.</Description>
<Name>gcat</Name>
<Version>1.0.0-SNAPSHOT</Version>
<MavenCoordinates>
<groupId>org.gcube.data-publishing</groupId>
<artifactId>gcat</artifactId>
<version>1.0.0-SNAPSHOT</version>
</MavenCoordinates>
<Files>
<File>gcat-1.0.0-SNAPSHOT.war</File>
</Files>
</Main>
</Packages>
</Profile>
</Resource>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<web-app>
<servlet>
<servlet-name>org.gcube.gcat.ResourceInitializer</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>org.gcube.gcat.ResourceInitializer</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -18,7 +18,7 @@ public class CKANLicenseTest extends ContextTest {
@Test
public void list() throws Exception {
CKANLicense license = new CKANLicense();
String ret = license.list();
String ret = license.list(-1,-1);
ObjectMapper mapper = new ObjectMapper();
JsonNode gotList = mapper.readTree(ret);
Assert.assertTrue(gotList instanceof ArrayNode);

View File

@ -1,9 +1,9 @@
package org.gcube.gcat.persistence.ckan;
import java.util.HashMap;
import java.util.Map;
import org.gcube.gcat.ContextTest;
import org.gcube.gcat.persistence.ckan.CKAN;
import org.gcube.gcat.persistence.ckan.CKANPackage;
import org.gcube.gcat.persistence.ckan.CKANResource;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
@ -27,37 +27,58 @@ public class CKANPackageTest extends ContextTest {
private static final String ITEM_NAME_VALUE = "restful_transaction_model";
private static final String LICENSE_VALUE = "CC-BY-SA-4.0";
private static final String EXTRAS_TYPE_VALUE_VALUE = "EmptyType";
private static final String EXTRAS_TYPE_VALUE_VALUE = "EmptyProfile";
@Test
public void list() throws Exception {
CKANPackage ckanPackage = new CKANPackage();
ObjectMapper mapper = new ObjectMapper();
String ret = ckanPackage.list();
String ret = ckanPackage.list(-1,0);
JsonNode gotList = mapper.readTree(ret);
Assert.assertTrue(gotList instanceof ArrayNode);
logger.debug("List :\n{}", mapper.writeValueAsString(gotList));
}
/*
* DEV
* PRE
*
* Workspace(luca.frosini) > RESTful Transaction Model.pdf
* https://data-d.d4science.org/shub/e03355cd-058a-4e3a-8d5b-cf3676a46840
* URL url = new URL("https://goo.gl/fSZH1o");
* https://data1-d.d4science.org/shub/E_YjI4STdKKzRlNjgzMm9jQWxjcmtReDNwbDFYR3lpTHo3SjdtN1RDZ3c2OGk0ZHZhdE5iZElBKzNxUDAyTGFqZw==
* https://goo.gl/HcUWni
*
*
* Workspace(luca.frosini) > RESTful Transaction Model v 1.0.pdf
* https://data-d.d4science.org/shub/8ad187c4-8f94-4c47-a780-706d0d33c1bb
* URL url = new URL("https://goo.gl/6vZSmp");
* https://data1-d.d4science.org/shub/E_aThRa1NpWFJpTGEydEU2bEJhMXNjZy8wK3BxekJKYnpYTy81cUkwZVdicEZ0aGFRZmY4MkRnUC8xWW0zYzVoVg==
* https://goo.gl/J8AwQW
*
*
* Workspace(luca.frosini) > RESTful Transaction Model v 1.1.pdf
* https://data-d.d4science.org/shub/7b6628e4-b397-4df9-b387-2d643ae0095c
* URL url = new URL("https://goo.gl/jvXMcd");
* https://data1-d.d4science.org/shub/E_NkhrbVV4VTluT0RKVUtCRldobFZTQU5ySTZneFdpUzJ2UjJBNlZWNDlURDVHamo4WjY5RnlrcHZGTGNkT2prUg==
* https://goo.gl/78ViuR
*
*/
@Test
public void testNameRegex() {
Map<String, Boolean> stringsToTest = new HashMap<>();
stringsToTest.put("Test", false); // Fails for T
stringsToTest.put("test-test+test-test", false); // Fails for +
stringsToTest.put("t", false); // Fails because is too short. Min length is 2 characters
stringsToTest.put("te", true);
stringsToTest.put("test-test_test-test", true);
stringsToTest.put("test-test_test-test_test-test_test-test_test-test_test-test_test-test_test-test_test-test_test-test_", true);
// // Fails because is too long. Max length is 100 characters
stringsToTest.put("test-test_test-test_test-test_test-test_test-test_test-test_test-test_test-test_test-test_test-test_t", false);
for(String testString : stringsToTest.keySet()) {
boolean match = testString.matches(CKANPackage.NAME_REGEX);
logger.debug("'{}' does {}match the regex {}", testString, match ? "" : "NOT ", CKANPackage.NAME_REGEX);
Assert.assertEquals(stringsToTest.get(testString), match);
}
}
protected CKANPackage createPackage(ObjectMapper mapper) throws Exception {
@ -78,7 +99,7 @@ public class CKANPackageTest extends ContextTest {
ObjectNode resourceNode = mapper.createObjectNode();
resourceNode.put(CKANResource.NAME_KEY, "RESTful Transaction Model");
// Workspace(luca.frosini) > RESTful Transaction Model v 1.0.pdf
resourceNode.put(CKANResource.URL_KEY, "https://goo.gl/6vZSmp");
resourceNode.put(CKANResource.URL_KEY, "https://goo.gl/J8AwQW");
resourceArrayNode.add(resourceNode);
ArrayNode extraArrayNode = itemObjectNode.putArray(CKANPackage.EXTRA_TYPES_KEY);
@ -123,7 +144,7 @@ public class CKANPackageTest extends ContextTest {
ArrayNode resources = (ArrayNode) readItemObjectNode.get(CKANPackage.RESOURCES_KEY);
ObjectNode objectNode = (ObjectNode) resources.get(0);
// Workspace(luca.frosini) > RESTful Transaction Model v 1.1.pdf
objectNode.put(CKANResource.URL_KEY, "https://goo.gl/jvXMcd");
objectNode.put(CKANResource.URL_KEY, "https://goo.gl/78ViuR");
resources.set(0, objectNode);
((ObjectNode) readItemObjectNode).replace(CKANPackage.RESOURCES_KEY, resources);

View File

@ -4,7 +4,8 @@ import java.net.URL;
import java.util.UUID;
import org.gcube.gcat.ContextTest;
import org.gcube.gcat.persistence.ckan.CKANResource;
import org.gcube.gcat.utils.Constants;
import org.gcube.storagehub.ApplicationMode;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -16,55 +17,64 @@ public class CKANResourceTest extends ContextTest {
private static final Logger logger = LoggerFactory.getLogger(CKANResourceTest.class);
/*
* PROD
* Workspace(luca.frosini) > RESTful Transaction Model.pdf
* https://data.d4science.org/shub/ab4daec8-2ce4-43d7-9d37-00b2051e3530
* URL url = new URL("https://goo.gl/bFME6Q");
*/
/*
* DEV
* PRE
*
* Workspace(luca.frosini) > RESTful Transaction Model.pdf
* https://data-d.d4science.org/shub/e03355cd-058a-4e3a-8d5b-cf3676a46840
* URL url = new URL("https://goo.gl/fSZH1o");
* https://data1-d.d4science.org/shub/E_YjI4STdKKzRlNjgzMm9jQWxjcmtReDNwbDFYR3lpTHo3SjdtN1RDZ3c2OGk0ZHZhdE5iZElBKzNxUDAyTGFqZw==
* https://goo.gl/HcUWni
*
*
* Workspace(luca.frosini) > RESTful Transaction Model v 1.0.pdf
* https://data-d.d4science.org/shub/5df695ea-986a-437d-abaf-ed1542a7f5af
* URL url = new URL("https://goo.gl/7ofQwn");
* https://data1-d.d4science.org/shub/E_aThRa1NpWFJpTGEydEU2bEJhMXNjZy8wK3BxekJKYnpYTy81cUkwZVdicEZ0aGFRZmY4MkRnUC8xWW0zYzVoVg==
* https://goo.gl/J8AwQW
*
*
* Workspace(luca.frosini) > RESTful Transaction Model v 1.1.pdf
* https://data-d.d4science.org/shub/7b6628e4-b397-4df9-b387-2d643ae0095c
* URL url = new URL("https://goo.gl/jvXMcd");
* https://data1-d.d4science.org/shub/E_NkhrbVV4VTluT0RKVUtCRldobFZTQU5ySTZneFdpUzJ2UjJBNlZWNDlURDVHamo4WjY5RnlrcHZGTGNkT2prUg==
* https://goo.gl/78ViuR
*
*/
@Test
public void test() throws Exception {
ApplicationMode applicationMode = new ApplicationMode(Constants.getCatalogueApplicationToken());
applicationMode.start();
//
applicationMode.end();
}
// @Test
public void testCopyStorageResource() throws Exception {
URL url = new URL("https://goo.gl/fSZH1o");
URL url = new URL("https://goo.gl/HcUWni");
String itemID = UUID.randomUUID().toString();
CKANResource ckanResource = new CKANResource(itemID);
ckanResource.resourceID = UUID.randomUUID().toString();
URL finalURL = ckanResource.copyStorageResource(url);
logger.debug("Initial URL is {} - Final URL is {}", url, finalURL);
ckanResource.deleteStorageResource(finalURL);
ckanResource.deleteStorageResource(finalURL, ckanResource.resourceID, ckanResource.mimeType);
}
// @Test
@Test
public void testCreate() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = objectMapper.createObjectNode();
objectNode.put(CKANResource.URL_KEY, "https://data.d4science.org/shub/ab4daec8-2ce4-43d7-9d37-00b2051e3530");
objectNode.put(CKANResource.ID_KEY, "8422b5d4-626b-46f2-9121-bbc6d443071d");
objectNode.put(CKANResource.NAME_KEY, "MyTestTy_rest_upload");
objectNode.put(CKANResource.URL_KEY, "https://data.d4science.org/shub/58a13287-3e91-4afd-bd80-cf4605a0edaa");
objectNode.put("description", "i uploaded this file using the REST API");
// objectNode.put(CKANResource.ID_KEY, "ba7ab7e8-c268-4219-98cd-c73470870999");
CKANResource ckanResource = new CKANResource("f9221556-4b1f-49f2-8951-a4c30d71cd37");
CKANResource ckanResource = new CKANResource("ba7ab7e8-c268-4219-98cd-c73470870999");
String json = ckanResource.getAsString(objectNode);
logger.debug("Going to create Resource {}", json);
ckanResource.create(json);
ckanResource.create(objectNode);
}
// @Test
public void testDelete() throws Exception {
CKANResource ckanResource = new CKANResource("f0326fec-d8ac-42c7-abff-c7905b4d938e");
ckanResource.setResourceID("fcf98272-41e7-4f05-9294-fdafb1a33074");
ckanResource.delete();
}
}

View File

@ -27,7 +27,7 @@ public class CKANUserTest extends ContextTest {
@Test
public void list() throws Exception {
CKANUser ckanUser = getCKANUser();
String ret = ckanUser.list();
String ret = ckanUser.list(-1,-1);
logger.debug("{}", ret);
}

View File

@ -1,11 +1,14 @@
package org.gcube.gcat.rest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.stream.Collectors;
import javax.ws.rs.core.MediaType;
import org.gcube.gcat.ContextTest;
import org.gcube.gcat.rest.Profile;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -53,4 +56,24 @@ public class ProfileTest extends ContextTest {
}
}
public static String PROFILE_EXAMPLE_FILENAME = "EmptyProfileExample.xml";
public static String PROFILE_NAME_EXAMPLE = "EmptyProfile";
@Test
public void testCreateUpdateDeleteGenericResource() throws Exception {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(PROFILE_EXAMPLE_FILENAME);
String xml = new BufferedReader(new InputStreamReader(inputStream)).lines()
.collect(Collectors.joining("\n"));
logger.debug("Body\n{}", xml);
Profile profile = new Profile();
profile.createOrUpdate(PROFILE_NAME_EXAMPLE, xml);
/*
Thread.sleep(TimeUnit.SECONDS.toMillis(30));
profile.createOrUpdate(PROFILE_NAME_EXAMPLE, "<metadataformat type=\"" + PROFILE_NAME_EXAMPLE + "\" />");
Thread.sleep(TimeUnit.SECONDS.toMillis(30));
profile.delete(PROFILE_NAME_EXAMPLE);
*/
}
}

View File

@ -0,0 +1,125 @@
package org.gcube.gcat.workspace;
import java.net.URL;
import java.util.Map;
import org.gcube.common.storagehub.client.dsl.FileContainer;
import org.gcube.common.storagehub.model.Metadata;
import org.gcube.gcat.ContextTest;
import org.gcube.gcat.persistence.ckan.CKANResource;
import org.gcube.storagehub.StorageHubManagement;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CatalogueStorageHubManagementTest extends ContextTest {
private static final Logger logger = LoggerFactory.getLogger(CatalogueStorageHubManagementTest.class);
/*
* PRE
*
* Workspace(luca.frosini) > RESTful Transaction Model.pdf
* https://data1-d.d4science.org/shub/E_YjI4STdKKzRlNjgzMm9jQWxjcmtReDNwbDFYR3lpTHo3SjdtN1RDZ3c2OGk0ZHZhdE5iZElBKzNxUDAyTGFqZw==
* https://goo.gl/HcUWni
*
* Workspace(luca.frosini) > RESTful Transaction Model v 1.0.pdf
* https://data1-d.d4science.org/shub/E_aThRa1NpWFJpTGEydEU2bEJhMXNjZy8wK3BxekJKYnpYTy81cUkwZVdicEZ0aGFRZmY4MkRnUC8xWW0zYzVoVg==
* https://goo.gl/J8AwQW
*
*
* Workspace(luca.frosini) > RESTful Transaction Model v 1.1.pdf
* https://data1-d.d4science.org/shub/E_NkhrbVV4VTluT0RKVUtCRldobFZTQU5ySTZneFdpUzJ2UjJBNlZWNDlURDVHamo4WjY5RnlrcHZGTGNkT2prUg==
* https://goo.gl/78ViuR
*
*/
public static final String ORIGINAL_STORAGE_URL_STRING = "https://data1-d.d4science.org/shub/E_YjI4STdKKzRlNjgzMm9jQWxjcmtReDNwbDFYR3lpTHo3SjdtN1RDZ3c2OGk0ZHZhdE5iZElBKzNxUDAyTGFqZw==";
public static final URL ORIGINAL_STORAGE_URL;
public static final String SHORT_URL_STRING = "https://goo.gl/HcUWni";
public static final URL SHORT_STORAGE_URL;
public static final String MIME_TYPE = "application/pdf";
static {
try {
ORIGINAL_STORAGE_URL = new URL(ORIGINAL_STORAGE_URL_STRING);
SHORT_STORAGE_URL = new URL(SHORT_URL_STRING);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
public static final String ITEM_ID = "MyItem";
public static final String RESOURCE_ID = "1234";
protected CatalogueStorageHubManagement catalogueStorageHubManagement;
protected StorageHubManagement storageHubManagement;
protected CatalogueMetadata catalogueMetadata;
public CatalogueStorageHubManagementTest() {
catalogueStorageHubManagement = new CatalogueStorageHubManagement();
storageHubManagement = catalogueStorageHubManagement.storageHubManagement;
catalogueMetadata = new CatalogueMetadata(ITEM_ID);
}
@Test
public void getFinalURL() {
URL finalURL = CKANResource.getFinalURL(SHORT_STORAGE_URL);
Assert.assertTrue(finalURL.toString().compareTo(ORIGINAL_STORAGE_URL_STRING)==0);
}
protected void checkMetadata(FileContainer fileContainer, String version) {
Metadata gotMetadata = fileContainer.get().getMetadata();
Map<String, Object> gotMap = gotMetadata.getMap();
CatalogueMetadata catalogueMetadata = new CatalogueMetadata(ITEM_ID);
Metadata expectedMetadata = catalogueMetadata.getMetadata(ORIGINAL_STORAGE_URL, fileContainer.get().getName(), RESOURCE_ID);
Map<String, Object> expectedMap = expectedMetadata.getMap();
for(String key : gotMap.keySet()) {
String value = (String) gotMap.get(key);
if(key.compareTo(CatalogueMetadata.CATALOGUE_RESOURCE_REVISION_ID)==0) {
Assert.assertTrue(value.compareTo(version)==0);
}else {
String expectedValue = (String) expectedMap.get(key);
Assert.assertTrue(value.compareTo(expectedValue)==0);
}
}
}
@Test
public void testPersistence() throws Exception {
URL persistedURL = catalogueStorageHubManagement.ensureResourcePersistence(ORIGINAL_STORAGE_URL, ITEM_ID, RESOURCE_ID);
logger.debug("Publick Link of persisted file is {}", persistedURL);
Assert.assertTrue(catalogueStorageHubManagement.getMimeType().compareTo(MIME_TYPE)==0);
FileContainer createdFileContainer = storageHubManagement.getCreatedFile();
String version = "2";
catalogueStorageHubManagement.renameFile(RESOURCE_ID, version);
checkMetadata(createdFileContainer, version);
version = "3";
catalogueStorageHubManagement.addRevisionID(RESOURCE_ID, version);
checkMetadata(createdFileContainer, version);
catalogueStorageHubManagement.deleteResourcePersistence(ITEM_ID, RESOURCE_ID, MIME_TYPE);
}
}

View File

@ -1,106 +0,0 @@
package org.gcube.gcat.workspace;
import java.util.List;
import java.util.Map;
import org.gcube.common.homelibrary.home.Home;
import org.gcube.common.homelibrary.home.HomeLibrary;
import org.gcube.common.homelibrary.home.HomeManager;
import org.gcube.common.homelibrary.home.HomeManagerFactory;
import org.gcube.common.homelibrary.home.User;
import org.gcube.common.homelibrary.home.workspace.Workspace;
import org.gcube.common.homelibrary.home.workspace.WorkspaceFolder;
import org.gcube.common.homelibrary.home.workspace.WorkspaceItem;
import org.gcube.common.storagehub.client.dsl.FileContainer;
import org.gcube.common.storagehub.client.dsl.FolderContainer;
import org.gcube.common.storagehub.client.dsl.ItemContainer;
import org.gcube.common.storagehub.client.dsl.ListResolver;
import org.gcube.common.storagehub.model.Metadata;
import org.gcube.common.storagehub.model.items.Item;
import org.gcube.common.storagehub.model.service.Version;
import org.gcube.gcat.ContextTest;
import org.gcube.gcat.utils.ApplicationMode;
import org.gcube.gcat.utils.ContextUtility;
import org.gcube.gcat.workspace.StorageHubManagement;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StorageHubManagementTest extends ContextTest {
private static final Logger logger = LoggerFactory.getLogger(StorageHubManagementTest.class);
@Test
public void testHL() throws Exception {
ApplicationMode applicationMode = new ApplicationMode();
applicationMode.start();
String username = ContextUtility.getUsername();
HomeManagerFactory factory = HomeLibrary.getHomeManagerFactory();
HomeManager manager = factory.getHomeManager();
User user = manager.createUser(username);
@SuppressWarnings("deprecation")
Home home = manager.getHome(user);
Workspace ws = home.getWorkspace();
WorkspaceFolder workspaceFolder = ws.getRoot();
List<WorkspaceItem> workspaceItems = workspaceFolder.getChildren(true);
for(WorkspaceItem workspaceItem : workspaceItems) {
logger.debug("{} {}{}", workspaceFolder.getType(), workspaceItem.getName(), workspaceItem.isHidden()? " (hidden)":"");
}
}
@Test
public void myTest() throws Exception {
String folderName = StorageHubManagement.getFolderName();
logger.debug(folderName);
}
@Test
public void test() throws Exception {
ApplicationMode applicationMode = new ApplicationMode();
applicationMode.start();
StorageHubManagement storageHubManagement = new StorageHubManagement();
FolderContainer root = storageHubManagement.getWorkspaceRoot();
storageHubManagement.tree(root);
}
@Test
public void listFolders() throws Exception {
ApplicationMode applicationMode = new ApplicationMode();
applicationMode.start();
StorageHubManagement storageHubManagement = new StorageHubManagement();
FolderContainer root = storageHubManagement.getWorkspaceRoot();
storageHubManagement.getCatalogueFolder();
storageHubManagement.tree(root);
applicationMode.end();
}
// @Test
public void deleteFile() throws Exception {
StorageHubManagement storageHubManagement = new StorageHubManagement();
String id = "";
storageHubManagement.deleteFileByID(id);
}
@Test
public void getFileInfo() throws Exception {
StorageHubManagement storageHubManagement = new StorageHubManagement();
String id = "";
FileContainer fileContainer = storageHubManagement.getFileByID(id);
logger.debug("StorageHub ID {} - File Name {}", id, fileContainer.get().getName());
ListResolver listResolver = fileContainer.getAnchestors();
List<ItemContainer<? extends Item>> itemContainers = listResolver.getContainers();
for(ItemContainer<? extends Item> itemContainer : itemContainers) {
logger.debug("{}", itemContainer.get().getName());
}
Metadata metadata = fileContainer.get().getPropertyMap();
Map<String,Object> map = metadata.getValues();
logger.debug("{}", map);
List<Version> versions = fileContainer.getVersions();
for(Version version : versions){
logger.debug("Version {} {}", version.getId(), version.getName());
}
}
}

View File

@ -0,0 +1,9 @@
<metadataformat type="EmptyProfile">
<metadatafield>
<fieldName>test</fieldName>
<mandatory>false</mandatory>
<dataType>String</dataType>
<maxOccurs>1</maxOccurs>
<note>Test Field</note>
</metadatafield>
</metadataformat>

View File

@ -10,7 +10,7 @@
<logger name="org.gcube" level="ERROR" />
<logger name="org.gcube.datacatalogue" level="TRACE" />
<logger name="org.gcube.gcat" level="TRACE" />
<root level="WARN">
<appender-ref ref="STDOUT" />

View File

@ -1 +0,0 @@
227af25a-7631-4abd-a866-a67ff7f63276

View File

@ -1,3 +0,0 @@
DO CANCEL THIS FILE IN PRODUCTION and DEV ENVIRONMENTS
The presence of this file indicates the home library client to look for the preprod instance of the workspace repository.