Compare commits

...

40 Commits

Author SHA1 Message Date
luca.frosini 18b77a179a Added missing query parameters 2023-11-09 19:10:34 +01:00
luca.frosini 85935c71d7 Added expiring time for ModelKnowledge 2023-10-31 15:44:38 +01:00
luca.frosini ae136f9567 The client must not enforce the pagination. It is a server side issue 2023-10-31 15:33:03 +01:00
luca.frosini e1b1f23e81 Improving offset limit management to properly support paginated result 2023-10-31 15:25:08 +01:00
luca.frosini 8d5c498d07 Improved Changelog 2023-10-27 15:03:43 +02:00
luca.frosini f6772e4647 Improved ContextCache 2023-10-27 14:53:03 +02:00
luca.frosini 54d387e035 Added constant which defines pagination defaults 2023-09-27 16:24:51 +02:00
luca.frosini 25fffa886d Added query parameters to get paginated results 2023-09-13 18:40:15 +02:00
luca.frosini 19f1614a15 Enhanced version to support new feature 2023-09-13 11:46:14 +02:00
luca.frosini f35c1564b8 Removed -SNAPSHOT for release 2023-07-21 14:23:35 +02:00
luca.frosini 745da916b1 Ignored MacOs File 2023-06-21 11:44:39 +02:00
Luca Frosini 35d8d854e2 Fixing cache 2023-05-16 11:01:57 +02:00
Luca Frosini 5aad485d06 Improved code 2023-05-10 17:50:40 +02:00
Luca Frosini e7e251dac8 improved context cache 2023-05-10 17:15:10 +02:00
Luca Frosini f6f2402b07 Removed query parameter which is not needed 2023-05-10 17:14:39 +02:00
Luca Frosini 6e33d8a936 Added available query parameters 2023-05-05 11:19:03 +02:00
Luca Frosini 693c9f54b2 Fixed changelog 2023-05-03 16:01:56 +02:00
Luca Frosini 6d08991dc3 Added interface RequestInfo 2023-05-02 17:23:49 +02:00
Luca Frosini 3596058992 fixed constant value 2023-05-02 15:48:19 +02:00
Luca Frosini a26b4fcba5 Adde INCLUDE_META_ and INCLUDE_META_IN_ALL_INSTANCES QUERY_PARAMETERs 2023-05-02 14:38:13 +02:00
Luca Frosini 71a9acae34 Fixed code to comply with uuid property rename to id 2023-04-28 11:46:13 +02:00
Luca Frosini a60aa315fe Enhanced major version 2023-04-26 10:56:45 +02:00
Luca Frosini 74a5ce896c Reorganized utilities and their usage 2023-04-21 15:58:25 +02:00
Luca Frosini e1284006e7 Porting code to redesigned E/R format 2023-04-19 11:37:03 +02:00
Luca Frosini 9c23f9f42a Redesigning E/R instance definition 2023-04-18 17:51:40 +02:00
Luca Frosini ee6fb393d3 Removed -SNAPSHOT to release the component 2023-03-03 12:03:18 +01:00
Luca Frosini c50ca21744 Merge branch 'master' of gitea@code-repo.d4science.org:gCubeSystem/resource-registry-api.git 2023-03-03 12:02:37 +01:00
Luca Frosini 9cc1b8727e Removed -SNAPSHOT to release the component 2023-03-03 12:00:11 +01:00
Luca Frosini 741c80cc19 fixed code 2023-03-01 20:06:07 +01:00
Luca Frosini 8a6c9179ef common-utility 1.X.X has been renamed to common-utility-sg3 2023-02-24 14:56:35 +01:00
Luca Frosini d3667cd4d3 Added usage of common-utility 2023-02-22 15:13:49 +01:00
Luca Frosini bb14a1d871 Removed usage of authorization-utils 2023-02-16 15:57:03 +01:00
Luca Frosini 15612ec339 suppressed warning 2023-02-09 17:03:37 +01:00
Luca Frosini e3de1aa426 Splitted code to use a function individually 2023-02-09 17:01:59 +01:00
Luca Frosini 2d295bf216 Upgraded ContextTest to new auth 2023-02-09 16:41:26 +01:00
Luca Frosini d7dad5f824 Merged some changes made in branch feature/23630 2023-02-09 16:26:59 +01:00
Luca Frosini 61e8cd6cb0 Merged changes made on branch 2023-02-09 16:18:10 +01:00
Luca Frosini 13370bef1e Merging changes made in branch 'feature/23630' 2023-02-09 16:04:39 +01:00
Luca Frosini eef2db5eb7 Enhanced gcube-bom version 2023-02-09 15:35:55 +01:00
Luca Frosini c05ac9e107 Moved to reorganized is-model 2023-02-07 16:59:52 +01:00
50 changed files with 6211 additions and 141 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
target
.classpath
.project
/.DS_Store

View File

@ -2,6 +2,24 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
# Changelog for Resource Registry API
# [v5.1.0-SNAPSHOT]
- Added Contexts as Teee in ContextCache [#24555]
- Added query parameters to paginate result of queries [#24648]
## [v5.0.0]
- Migrate code to reorganized E/R format [#24992]
- Added query parameters to request Metadata [#25040]
## [v4.3.0]
- Enhanced gcube-bom version
- Added usage of common-utility to overcome issues with different Smartgears version (i.e. 3 and 4)
## [v4.2.0]
- Added INCLUDE_RELATION_PARAM param in AccessPath used by query APIs [#20298]
@ -16,6 +34,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Added ContextCache utilities
- Added support to provide APIs to get the list of instance contexts [#20012] [#20013]
## [v4.0.0] [r4.26.0] - 2020-11-11
- Switched JSON management to gcube-jackson [#19116]

14
pom.xml
View File

@ -10,7 +10,7 @@
<groupId>org.gcube.information-system</groupId>
<artifactId>resource-registry-api</artifactId>
<version>4.2.0</version>
<version>5.1.0-SNAPSHOT</version>
<name>Resource Registry API</name>
<description>Resource Registry API is a library containing classes shared across resource-registry-* components</description>
@ -30,7 +30,7 @@
<dependency>
<groupId>org.gcube.distribution</groupId>
<artifactId>gcube-bom</artifactId>
<version>2.1.0</version>
<version>2.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -42,6 +42,10 @@
<groupId>org.gcube.information-system</groupId>
<artifactId>information-system-model</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>common-utility-sg3</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
@ -58,5 +62,11 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-utils</artifactId>
<version>[2.2.0, 3.0.0-SNAPSHOT)</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -2,9 +2,12 @@ package org.gcube.informationsystem.resourceregistry.api.contexts;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ -13,9 +16,13 @@ import org.gcube.informationsystem.contexts.impl.relations.IsParentOfImpl;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.tree.Tree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ContextCache {
private static Logger logger = LoggerFactory.getLogger(ContextCache.class);
@ -42,25 +49,9 @@ public class ContextCache {
return singleton;
}
public void cleanCache() {
cleanCache(Calendar.getInstance());
}
private void cleanCache(Calendar now) {
this.contexts = null;
this.uuidToContext = new HashMap<>();
this.uuidToContextFullName = new HashMap<>();
this.contextFullNameToUUID = new HashMap<>();
this.creationTime = Calendar.getInstance();
this.creationTime.setTimeInMillis(now.getTimeInMillis());
this.expiringTime = Calendar.getInstance();
this.expiringTime.setTimeInMillis(now.getTimeInMillis());
this.expiringTime.add(Calendar.MILLISECOND, -1);
}
protected ContextCacheRenewal contextCacheRenewal;
// in millisec used for logging purposes only
// in millisec used only for logging and debugging
protected Calendar creationTime;
// in millisec
protected Calendar expiringTime;
@ -69,25 +60,53 @@ public class ContextCache {
protected Map<UUID, Context> uuidToContext;
protected Map<UUID, String> uuidToContextFullName;
protected Map<String, UUID> contextFullNameToUUID;
protected Tree<Context> contextsTree;
public ContextCache() {
Calendar now = Calendar.getInstance();
cleanCache(now);
}
public void cleanCache() {
cleanCache(Calendar.getInstance());
}
protected void cleanCache(Calendar calendar) {
this.contexts = null;
this.uuidToContext = new LinkedHashMap<>();
this.uuidToContextFullName = new LinkedHashMap<>();
this.contextFullNameToUUID = new TreeMap<>();
this.contextsTree = new Tree<Context>(new ContextInformation());
this.contextsTree.setAllowMultipleInheritance(false);
this.creationTime = Calendar.getInstance();
this.creationTime.setTimeInMillis(calendar.getTimeInMillis());
this.expiringTime = Calendar.getInstance();
this.expiringTime.setTimeInMillis(calendar.getTimeInMillis());
this.expiringTime.add(Calendar.MILLISECOND, -1);
this.expiringTime.add(Calendar.MILLISECOND, expiringTimeout);
}
public void renew() throws ResourceRegistryException {
cleanCache();
refreshContextsIfNeeded();
}
public ContextCacheRenewal getContextCacheRenewal() {
return contextCacheRenewal;
}
public void setContextCacheRenewal(ContextCacheRenewal contextCacheRenewal) {
if(this.contextCacheRenewal==null) {
this.contextCacheRenewal = contextCacheRenewal;
}
}
public void refreshContextsIfNeeded() throws ResourceRegistryException {
public synchronized void refreshContextsIfNeeded() throws ResourceRegistryException {
Calendar now = Calendar.getInstance();
if((now.after(expiringTime) || (contexts==null)) && contextCacheRenewal!=null) {
try {
List<Context> contexts = contextCacheRenewal.renew();
singleton.cleanCache(now);
setContexts(contexts);
setContexts(now, contexts);
} catch (ResourceRegistryException e) {
logger.error("Unable to refresh Cache", e);
if(contexts==null) {
@ -103,48 +122,61 @@ public class ContextCache {
return contexts;
}
private void setContexts(List<Context> contexts) {
public void setContexts(List<Context> contexts) {
Calendar now = Calendar.getInstance();
setContexts(now, contexts);
}
protected void setContexts(Calendar calendar, List<Context> contexts) {
cleanCache(calendar);
this.contexts = new ArrayList<>();
for(Context c : contexts) {
UUID uuid = c.getHeader().getUUID();
UUID uuid = c.getID();
Context context = new ContextImpl(c.getName());
context.setHeader(c.getHeader());
context.setMetadata(c.getMetadata());
context.setID(uuid);
this.contexts.add(context);
this.uuidToContext.put(uuid, context);
}
for(Context c : contexts) {
UUID uuid = c.getHeader().getUUID();
UUID uuid = c.getID();
Context context = this.uuidToContext.get(uuid);
if(c.getParent()!=null) {
IsParentOf ipo = c.getParent();
UUID parentUUID = ipo.getSource().getHeader().getUUID();
UUID parentUUID = ipo.getSource().getID();
Context parent = this.uuidToContext.get(parentUUID);
IsParentOf isParentOf = new IsParentOfImpl(parent, context);
isParentOf.setHeader(ipo.getHeader());
isParentOf.setID(parentUUID);
isParentOf.setMetadata(ipo.getMetadata());
parent.addChild(isParentOf);
context.setParent(isParentOf);
}
}
for(Context context : contexts) {
UUID uuid = context.getHeader().getUUID();
UUID uuid = context.getID();
String fullName = getContextFullName(context);
this.uuidToContextFullName.put(uuid, fullName);
this.contextFullNameToUUID.put(fullName, uuid);
}
SortedSet<String> contextFullNames = new TreeSet<String>(contextFullNameToUUID.keySet());
for(String contextFullName : contextFullNames) {
UUID uuid = contextFullNameToUUID.get(contextFullName);
Context context = uuidToContext.get(uuid);
contextsTree.addNode(context);
}
}
private String getContextFullName(Context context) {
protected String getContextFullName(Context context) {
StringBuilder stringBuilder = new StringBuilder();
IsParentOf ipo = context.getParent();
if(ipo!=null) {
Context c = ipo.getSource();
c = uuidToContext.get(c.getHeader().getUUID());
c = uuidToContext.get(c.getID());
String parentFullName = getContextFullName(c);
stringBuilder.append(parentFullName);
}
@ -176,12 +208,12 @@ public class ContextCache {
public synchronized Context getContextByUUID(String uuid) throws ResourceRegistryException {
refreshContextsIfNeeded();
return uuidToContext.get(UUID.fromString(uuid));
return getContextByUUID(UUID.fromString(uuid));
}
public synchronized Context getContextByFullName(String contextFullName) throws ResourceRegistryException {
UUID uuid = getUUIDByFullName(contextFullName);
return uuidToContext.get(uuid);
return getContextByUUID(uuid);
}
/**
@ -189,7 +221,7 @@ public class ContextCache {
*/
public synchronized Map<UUID, String> getUUIDToContextFullNameAssociation() throws ResourceRegistryException {
refreshContextsIfNeeded();
return new HashMap<>(uuidToContextFullName);
return new LinkedHashMap<>(uuidToContextFullName);
}
/**
@ -197,7 +229,11 @@ public class ContextCache {
*/
public synchronized Map<String, UUID> getContextFullNameToUUIDAssociation() throws ResourceRegistryException {
refreshContextsIfNeeded();
return new HashMap<>(contextFullNameToUUID);
return new TreeMap<>(contextFullNameToUUID);
}
public Tree<Context> getContextsTree() {
return contextsTree;
}
}

View File

@ -5,6 +5,9 @@ import java.util.List;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public interface ContextCacheRenewal {
public List<Context> renew() throws ResourceRegistryException;

View File

@ -0,0 +1,30 @@
package org.gcube.informationsystem.resourceregistry.api.contexts;
import java.util.LinkedHashSet;
import java.util.Set;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
import org.gcube.informationsystem.tree.NodeInformation;
public class ContextInformation implements NodeInformation<Context> {
@Override
public String getIdentifier(Context context) {
return context.getID().toString();
}
@Override
public Set<String> getParentIdentifiers(Context root, Context context) {
Set<String> set = new LinkedHashSet<>();
if(root !=null && context.getID().compareTo(root.getID())==0) {
return set;
}
IsParentOf parent = context.getParent();
if(parent!=null) {
set.add(parent.getSource().getID().toString());
}
return set;
}
}

View File

@ -12,15 +12,18 @@ import org.gcube.com.fasterxml.jackson.core.JsonParseException;
import org.gcube.com.fasterxml.jackson.databind.JavaType;
import org.gcube.com.fasterxml.jackson.databind.JsonMappingException;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.informationsystem.utils.ElementMapper;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ContextUtility {
private static Logger logger = LoggerFactory.getLogger(ContextUtility.class);
// public static Set<UUID> getContextUUIDSe(String jsonArray) throws IOException {
// public static Set<UUID> getContextUUIDSet(String jsonArray) throws IOException {
// ObjectMapper mapper = ElementMapper.getObjectMapper();
// JavaType type = mapper.getTypeFactory().constructCollectionType(HashSet.class, UUID.class);
// return mapper.readValue(jsonArray, type);
@ -30,7 +33,7 @@ public class ContextUtility {
// Set<UUID> uuids = getContextUUIDSet(jsonArray);
// return getContextFullNameSet(uuids);
// }
//
public static Map<UUID, String> getContextMap(String objectnode) throws JsonParseException, JsonMappingException, IOException{
ObjectMapper mapper = ElementMapper.getObjectMapper();
JavaType type = mapper.getTypeFactory().constructMapType(HashMap.class, UUID.class, String.class);
@ -46,13 +49,12 @@ public class ContextUtility {
return uuids;
}
public static Set<String> getContextFullNameSet(Collection<UUID> uuids) throws Exception {
ContextCache contextCache = ContextCache.getInstance();
public static Set<String> getContextFullNameSet(ContextCache contextCache, Collection<UUID> uuids) throws Exception {
Set<String> contextFullNames = new HashSet<>();
try {
Map<UUID, String> uuidToContextFullNameAssociation = contextCache.getUUIDToContextFullNameAssociation();
if(!uuidToContextFullNameAssociation.keySet().containsAll(uuids)) {
logger.debug("{} does not contain all the contexts identified by the following UUID list. Trying to invalidate the cache", ContextCache.class.getSimpleName(), uuids);
logger.debug("{} does not contain all the contexts identified by the following UUID list {}. Trying to invalidate the cache", ContextCache.class.getSimpleName(), uuids);
contextCache.cleanCache();
uuidToContextFullNameAssociation = contextCache.getUUIDToContextFullNameAssociation();
}

View File

@ -2,7 +2,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class AlreadyPresentException extends ResourceRegistryException {

View File

@ -2,7 +2,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class AvailableInAnotherContextException extends ResourceRegistryException {

View File

@ -2,7 +2,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class CreationException extends ResourceRegistryException {

View File

@ -13,7 +13,7 @@ import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.DeserializationFeature;
import org.gcube.com.fasterxml.jackson.databind.JsonMappingException;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.informationsystem.utils.discovery.ReflectionUtility;
import org.gcube.informationsystem.utils.ReflectionUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -2,7 +2,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class NotFoundException extends ResourceRegistryException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ContextException extends ResourceRegistryException {

View File

@ -2,7 +2,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.contexts;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ContextMoveException extends ContextException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundExcep
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ContextNotFoundException extends NotFoundException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresen
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class EntityAlreadyPresentException extends AlreadyPresentException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.CreationExcep
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class EntityCreationException extends CreationException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundExcep
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class EntityNotFoundException extends NotFoundException {

View File

@ -2,10 +2,8 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.fac
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityAlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class FacetAlreadyPresentException extends EntityAlreadyPresentException {

View File

@ -2,10 +2,8 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.fac
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityNotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class FacetNotFoundException extends EntityNotFoundException {

View File

@ -2,10 +2,8 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.res
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityAlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ResourceAlreadyPresentException extends EntityAlreadyPresentException {

View File

@ -2,10 +2,8 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.res
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityNotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ResourceNotFoundException extends EntityNotFoundException {

View File

@ -2,7 +2,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.queries;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
/**
* @author Luca Frosini (ISTI - CNR)
*/

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class QueryTemplateException extends ResourceRegistryException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundExcep
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class QueryTemplateNotFoundException extends NotFoundException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.CreationExcep
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class RelationCreationException extends CreationException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.Rel
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ConsistsOfCreationException extends RelationCreationException {

View File

@ -2,7 +2,6 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.is
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class IsParentOfCreationException extends IsParentOfException {

View File

@ -2,6 +2,9 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.is
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class IsParentOfException extends ResourceRegistryException {
/**

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.Rel
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class IsRelatedToCreationException extends RelationCreationException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class SchemaException extends ResourceRegistryException {

View File

@ -4,7 +4,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundExcep
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class SchemaNotFoundException extends NotFoundException {

View File

@ -2,6 +2,9 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions.types;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class SchemaViolationException extends ResourceRegistryException {
/**

View File

@ -0,0 +1,122 @@
package org.gcube.informationsystem.resourceregistry.api.request;
import org.gcube.informationsystem.base.reference.IdentifiableElement;
import org.gcube.informationsystem.model.reference.properties.Metadata;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class BaseRequestInfo implements RequestInfo {
public static final Integer DEFAULT_OFFSET = 0;
public static final Integer DEFAULT_LIMIT = 10;
public static final Integer UNBOUNDED_LIMIT = -1;
/**
* The offset parameter indicates the starting position of the result.
*/
protected Integer offset;
/**
* To get unlimited results the limit query parameters must be set to -1.
* If the results are too much the operation could have a timeout.
*/
protected Integer limit;
/**
* Track if the request requested to include {@link Metadata}
*/
protected boolean includeMeta;
/**
* Track if the request requested to include {@link Metadata} in all
* {@link IdentifiableElement} or just in the root instance
*/
protected boolean allMeta;
/**
* Track if hierarchicalMode has been requested
*/
protected boolean hierarchicalMode;
/**
* Track if the request requested to include contexts
*/
protected boolean includeContexts;
public BaseRequestInfo() {
this(null, null);
}
public BaseRequestInfo(Integer offset, Integer limit) {
this.offset = offset;
this.limit = limit;
this.includeMeta = false;
this.allMeta = false;
this.hierarchicalMode = false;
this.includeContexts = false;
}
@Override
public Integer getLimit() {
return limit;
}
@Override
public void setLimit(Integer limit) {
this.limit = limit;
}
@Override
public Integer getOffset() {
return offset;
}
@Override
public void setOffset(Integer offset) {
this.offset = offset;
}
@Override
public boolean includeMeta() {
return includeMeta;
}
@Override
public void setIncludeMeta(boolean includeMeta) {
this.includeMeta = includeMeta;
}
@Override
public boolean allMeta() {
return allMeta;
}
@Override
public void setAllMeta(boolean allMeta) {
this.allMeta = allMeta;
}
@Override
public boolean isHierarchicalMode() {
return hierarchicalMode;
}
@Override
public void setHierarchicalMode(boolean hierarchicalMode) {
this.hierarchicalMode = hierarchicalMode;
}
@Override
public boolean includeContexts() {
return includeContexts;
}
@Override
public void setIncludeContexts(boolean includeContexts) {
this.includeContexts = includeContexts;
}
}

View File

@ -0,0 +1,32 @@
package org.gcube.informationsystem.resourceregistry.api.request;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public interface RequestInfo {
public Integer getLimit();
public void setLimit(Integer limit);
public Integer getOffset();
public void setOffset(Integer offset);
public boolean includeMeta();
public void setIncludeMeta(boolean includeMeta);
public boolean allMeta();
public void setAllMeta(boolean allMeta);
public boolean isHierarchicalMode();
public void setHierarchicalMode(boolean hierarchicalMode);
public boolean includeContexts();
public void setIncludeContexts(boolean includeContexts);
}

View File

@ -18,7 +18,13 @@ public class AccessPath {
public static final String RAW_QUERY_PARAMETER_DEFAULT_VALUE = "false";
public static final String HIERARCHICAL_MODE_QUERY_PARAMETER = InstancePath.HIERARCHICAL_MODE_QUERY_PARAMETER;
public static final String INCLUDE_CONTEXTS_IN_HEADER_QUERY_PARAMETER = InstancePath.INCLUDE_CONTEXTS_IN_HEADER_QUERY_PARAMETER;
public static final String INCLUDE_CONTEXTS_QUERY_PARAMETER = InstancePath.INCLUDE_CONTEXTS_QUERY_PARAMETER;
public static final String INCLUDE_META_QUERY_PARAMETER = InstancePath.INCLUDE_META_QUERY_PARAMETER;
public static final String INCLUDE_META_IN_ALL_INSTANCES_QUERY_PARAMETER = InstancePath.INCLUDE_META_IN_ALL_INSTANCES_QUERY_PARAMETER;
public static final String OFFSET_QUERY_PARAMETER = InstancePath.OFFSET_QUERY_PARAMETER;
public static final String LIMIT_QUERY_PARAMETER = InstancePath.LIMIT_QUERY_PARAMETER;
/**
* Used only in getRelated() function

View File

@ -1,6 +1,3 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.rest;
/**
@ -12,4 +9,8 @@ public class ContextPath {
public static final String CURRENT_CONTEXT_PATH_PART = "CURRENT_CONTEXT";
public static final String INCLUDE_META_QUERY_PARAMETER = InstancePath.INCLUDE_META_QUERY_PARAMETER;
public static final String OFFSET_QUERY_PARAMETER = InstancePath.OFFSET_QUERY_PARAMETER;
public static final String LIMIT_QUERY_PARAMETER = InstancePath.LIMIT_QUERY_PARAMETER;
}

View File

@ -1,13 +1,35 @@
package org.gcube.informationsystem.resourceregistry.api.rest;
import org.gcube.informationsystem.base.reference.IdentifiableElement;
import org.gcube.informationsystem.model.reference.properties.Metadata;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class InstancePath {
public static final String INSTANCES_PATH_PART = "instances";
public static final String OFFSET_QUERY_PARAMETER = "offset";
public static final String LIMIT_QUERY_PARAMETER = "limit";
public static final String POLYMORPHIC_QUERY_PARAMETER = "polymorphic";
public static final String HIERARCHICAL_MODE_QUERY_PARAMETER = "hierarchical";
public static final String INCLUDE_CONTEXTS_IN_HEADER_QUERY_PARAMETER = "includeContextsInHeader";
public static final String INCLUDE_CONTEXTS_QUERY_PARAMETER = "includeContexts";
/**
* Request to include {@link Metadata} in {@link IdentifiableElement} root instance
*/
public static final String INCLUDE_META_QUERY_PARAMETER = "includeMeta";
/**
* Request to include {@link Metadata} in all {@link IdentifiableElement}
* instance.
* It must be used in conjunction with {@link #INCLUDE_META_QUERY_PARAMETER}
* If {@link #INCLUDE_META_QUERY_PARAMETER} is false it has no meaning
*/
public static final String INCLUDE_META_IN_ALL_INSTANCES_QUERY_PARAMETER = "allMeta";
}

View File

@ -7,7 +7,8 @@ public class QueryTemplatePath {
public static final String QUERY_TEMPLATES_PATH_PART = "query-templates";
public static final String INCLUDE_META_QUERY_PARAMETER = InstancePath.INCLUDE_META_QUERY_PARAMETER;
public static final String INCLUDE_META_IN_ALL_INSTANCES_QUERY_PARAMETER = InstancePath.INCLUDE_META_IN_ALL_INSTANCES_QUERY_PARAMETER;
}

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.rest;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.context.ContextUtility;
/**
* @author Luca Frosini (ISTI - CNR)
@ -12,7 +12,7 @@ public abstract class ServiceInstance {
public static final String BASE_URL = "https://url.d4science.org";
public static String getServiceURL() {
String context = ScopeProvider.instance.get();
String context = ContextUtility.getCurrentContextFullName();
return getServiceURL(context);
}

View File

@ -1,5 +1,8 @@
package org.gcube.informationsystem.resourceregistry.api.rest;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class SharingPath {
public static final String SHARING_PATH_PART = "sharing";
@ -21,4 +24,8 @@ public class SharingPath {
*/
public static final String FORCE_ADD_TO_CONTEXT_QUERY_PARAMETER = "forceAddToContext";
public static final String INCLUDE_CONTEXTS_QUERY_PARAMETER = InstancePath.INCLUDE_CONTEXTS_QUERY_PARAMETER;
public static final String INCLUDE_META_QUERY_PARAMETER = InstancePath.INCLUDE_META_QUERY_PARAMETER;
public static final String INCLUDE_META_IN_ALL_INSTANCES_QUERY_PARAMETER = InstancePath.INCLUDE_META_IN_ALL_INSTANCES_QUERY_PARAMETER;
}

View File

@ -7,6 +7,8 @@ public class TypePath {
public static final String TYPES_PATH_PART = "types";
public static final String POLYMORPHIC_QUERY_PARAMETER = "polymorphic";
public static final String POLYMORPHIC_QUERY_PARAMETER = InstancePath.POLYMORPHIC_QUERY_PARAMETER;
public static final String INCLUDE_META_QUERY_PARAMETER = InstancePath.INCLUDE_META_QUERY_PARAMETER;
}

View File

@ -20,10 +20,13 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.reso
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource.ResourceNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationNotFoundException;
import org.gcube.informationsystem.utils.ElementMapper;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class HTTPUtility {
private static final Logger logger = LoggerFactory.getLogger(HTTPUtility.class);

View File

@ -1,58 +0,0 @@
package org.gcube.informationsystem.resourceregistry.api.utils;
import java.io.IOException;
import java.util.UUID;
import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.base.reference.IdentifiableElement;
import org.gcube.informationsystem.types.TypeMapper;
import org.gcube.informationsystem.utils.ElementMapper;
public abstract class Utility {
public static String getClassFromJsonNode(JsonNode jsonNode){
return jsonNode.get(Element.CLASS_PROPERTY).asText();
}
public static String getClassFromJsonString(String json) throws JsonProcessingException, IOException{
JsonNode jsonNode = ElementMapper.getObjectMapper().readTree(json);
return getClassFromJsonNode(jsonNode);
}
public static String getUUIDStringFromJsonNode(JsonNode jsonNode){
return jsonNode.get(IdentifiableElement.HEADER_PROPERTY).get(Element.CLASS_PROPERTY).asText();
}
public static UUID getUUIDFromJsonNode(JsonNode jsonNode){
String uuidString = getUUIDStringFromJsonNode(jsonNode);
return UUID.fromString(uuidString);
}
public static String getUUIDStringFromJsonString(String json) throws JsonProcessingException, IOException{
JsonNode jsonNode = ElementMapper.getObjectMapper().readTree(json);
return getUUIDStringFromJsonNode(jsonNode);
}
public static UUID getUUIDFromJsonString(String json) throws JsonProcessingException, IOException{
JsonNode jsonNode = ElementMapper.getObjectMapper().readTree(json);
return getUUIDFromJsonNode(jsonNode);
}
// TODO move somewhere else, probably in Element
public static String getTypeName(Element element){
return getTypeName(element.getClass());
}
public static <E extends Element> String getTypeName(Class<E> clz){
if(!clz.isInterface()){
return clz.getAnnotation(JsonTypeName.class).value();
}else {
return TypeMapper.getType(clz);
}
}
}

View File

@ -0,0 +1,134 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.gcube.common.authorization.utils.manager.SecretManager;
import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
import org.gcube.common.authorization.utils.secret.JWTSecret;
import org.gcube.common.authorization.utils.secret.Secret;
import org.gcube.common.authorization.utils.secret.SecretUtility;
import org.gcube.common.keycloak.KeycloakClientFactory;
import org.gcube.common.keycloak.model.TokenResponse;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.informationsystem.model.reference.properties.Metadata;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
@SuppressWarnings("deprecation")
public class ContextTest {
private static final Logger logger = LoggerFactory.getLogger(ContextTest.class);
protected static final String CONFIG_INI_FILENAME = "config.ini";
public static final String PARENT_DEFAULT_TEST_SCOPE;
public static final String DEFAULT_TEST_SCOPE;
public static final String ALTERNATIVE_TEST_SCOPE;
public static final String GCUBE;
public static final String DEVNEXT;
public static final String NEXTNEXT;
public static final String DEVSEC;
public static final String DEVVRE;
protected static final Properties properties;
protected static final String CLIENT_ID_PROPERTY_KEY = "client_id";
protected static final String CLIENT_SECRET_PROPERTY_KEY = "client_secret";
protected static final String clientID;
protected static final String clientSecret;
static {
GCUBE = "/gcube";
DEVNEXT = GCUBE + "/devNext";
NEXTNEXT = DEVNEXT + "/NextNext";
DEVSEC = GCUBE + "/devsec";
DEVVRE = DEVSEC + "/devVRE";
PARENT_DEFAULT_TEST_SCOPE = "/gcube";
DEFAULT_TEST_SCOPE = DEVNEXT;
ALTERNATIVE_TEST_SCOPE = NEXTNEXT;
properties = new Properties();
InputStream input = ContextTest.class.getClassLoader().getResourceAsStream(CONFIG_INI_FILENAME);
try {
// load the properties file
properties.load(input);
clientID = properties.getProperty(CLIENT_ID_PROPERTY_KEY);
clientSecret = properties.getProperty(CLIENT_SECRET_PROPERTY_KEY);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void set(Secret secret) throws Exception {
SecretManagerProvider.instance.reset();
SecretManager secretManager = new SecretManager();
secretManager.addSecret(secret);
SecretManagerProvider.instance.set(secretManager);
SecretManagerProvider.instance.get().set();
}
public static void setContextByName(String fullContextName) throws Exception {
Secret secret = getSecretByContextName(fullContextName);
set(secret);
}
private static TokenResponse getJWTAccessToken(String context) throws Exception {
ScopeProvider.instance.set(context);
TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(clientID, clientSecret, context, null);
return tr;
}
public static Secret getSecretByContextName(String context) throws Exception {
TokenResponse tr = getJWTAccessToken(context);
Secret secret = new JWTSecret(tr.getAccessToken());
return secret;
}
public static void setContext(String token) throws Exception {
Secret secret = getSecret(token);
set(secret);
}
private static Secret getSecret(String token) throws Exception {
Secret secret = SecretUtility.getSecretByTokenString(token);
return secret;
}
public static String getUser() {
String user = Metadata.UNKNOWN_USER;
try {
user = SecretManagerProvider.instance.get().getUser().getUsername();
} catch(Exception e) {
logger.error("Unable to retrieve user. {} will be used", user);
}
return user;
}
@BeforeClass
public static void beforeClass() throws Exception {
setContextByName(DEFAULT_TEST_SCOPE);
}
@AfterClass
public static void afterClass() throws Exception {
SecretManagerProvider.instance.reset();
}
}

View File

@ -0,0 +1,80 @@
package org.gcube.informationsystem.resourceregistry.api.contexts;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.List;
import java.util.UUID;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.gcube.informationsystem.tree.Node;
import org.gcube.informationsystem.tree.NodeElaborator;
import org.gcube.informationsystem.tree.Tree;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ContextCacheTest{
private static final Logger logger = LoggerFactory.getLogger(ContextCacheTest.class);
protected File getTypesDirectory() throws Exception {
URL logbackFileURL = ContextCacheTest.class.getClassLoader().getResource("logback-test.xml");
File logbackFile = new File(logbackFileURL.toURI());
File resourcesDirectory = logbackFile.getParentFile();
return new File(resourcesDirectory, "contexts");
}
protected String readFile(File file) throws IOException {
byte[] encoded = Files.readAllBytes(file.toPath());
return new String(encoded, Charset.defaultCharset());
}
protected List<Context> getContexts() throws Exception {
File typesDirectory = getTypesDirectory();
File file = new File(typesDirectory, "contexts.json");
String json = readFile(file);
List<Context> contexts = ElementMapper.unmarshalList(Context.class, json);
return contexts;
}
@Test
public void test() throws Exception {
List<Context> contexts = getContexts();
ContextCache contextCache = new ContextCache();
contextCache.setContexts(contexts);
contextCache.setContextCacheRenewal(new ContextCacheRenewal() {
@Override
public List<Context> renew() throws ResourceRegistryException {
try {
return getContexts();
}catch (Exception e) {
throw new ResourceRegistryException(e);
}
}
});
Tree<Context> contextTree = contextCache.getContextsTree();
contextTree.elaborate(new NodeElaborator<Context>() {
@Override
public void elaborate(Node<Context> node, int level) throws Exception {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < level; ++i) {
stringBuffer.append(Node.INDENTATION);
}
Context context = node.getNodeElement();
UUID uuid = context.getID();
String fullName = contextCache.getContextFullNameByUUID(uuid);
logger.info("{}- {} (ID:{})", stringBuffer.toString(), fullName, uuid);
}
});
}
}

View File

@ -3,7 +3,7 @@ package org.gcube.informationsystem.resourceregistry.api.exceptions;
import java.lang.reflect.Constructor;
import java.util.List;
import org.gcube.informationsystem.utils.discovery.ReflectionUtility;
import org.gcube.informationsystem.utils.ReflectionUtility;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;

View File

@ -0,0 +1,19 @@
package org.gcube.informationsystem.resourceregistry.api.rest;
import org.gcube.informationsystem.resourceregistry.api.ContextTest;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ServiceInstanceTest extends ContextTest {
@Test
public void test() {
String url = ServiceInstance.getServiceURL();
String testURL = ServiceInstance.BASE_URL.replace("url.", "url.gcube.");
Assert.assertTrue(url.compareTo(testURL)==0);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
[{"type":"Context","id":"9a7752f6-ca01-4a89-a9dd-f36aeb2cbf50","name":"gcube","parent":null,"children":[{"type":"IsParentOf","id":"b4bdbd3e-87c4-43d1-b642-532f6a30ad44","target":{"type":"Context","id":"4e6adfe6-ab93-47c0-a532-339bb92ad07a","name":"devNext"}},{"type":"IsParentOf","id":"542179cb-36fc-4d4e-9771-b55d3b2bd301","target":{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec"}}]},{"type":"Context","id":"4e6adfe6-ab93-47c0-a532-339bb92ad07a","name":"devNext","parent":{"type":"IsParentOf","id":"b4bdbd3e-87c4-43d1-b642-532f6a30ad44","source":{"type":"Context","id":"9a7752f6-ca01-4a89-a9dd-f36aeb2cbf50","name":"gcube"}},"children":[{"type":"IsParentOf","id":"01cc9e06-475b-43a4-a4cd-7f5070f0dc65","target":{"type":"Context","id":"c7f3af7e-7e8c-406e-8d5a-cd11c82b5fa3","name":"NextNext"}}]},{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec","parent":{"type":"IsParentOf","id":"542179cb-36fc-4d4e-9771-b55d3b2bd301","source":{"type":"Context","id":"9a7752f6-ca01-4a89-a9dd-f36aeb2cbf50","name":"gcube"}},"children":[{"type":"IsParentOf","id":"e28b8e16-84d5-4cd9-a5a1-8a55fa371d0c","target":{"type":"Context","id":"a3e40b10-01d0-11ed-8d67-f3498769ebff","name":"CCP"}},{"type":"IsParentOf","id":"e46696d5-3290-4d7a-b22a-71940bda7ec0","target":{"type":"Context","id":"8efe07f5-de24-49f9-a2fb-fbfdcfda8c91","name":"devVRE"}}]},{"type":"Context","id":"c7f3af7e-7e8c-406e-8d5a-cd11c82b5fa3","name":"NextNext","parent":{"type":"IsParentOf","id":"01cc9e06-475b-43a4-a4cd-7f5070f0dc65","source":{"type":"Context","id":"4e6adfe6-ab93-47c0-a532-339bb92ad07a","name":"devNext"}},"children":[]},{"type":"Context","id":"a3e40b10-01d0-11ed-8d67-f3498769ebff","name":"CCP","parent":{"type":"IsParentOf","id":"e28b8e16-84d5-4cd9-a5a1-8a55fa371d0c","source":{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec"}},"children":[]},{"type":"Context","id":"8efe07f5-de24-49f9-a2fb-fbfdcfda8c91","name":"devVRE","parent":{"type":"IsParentOf","id":"e46696d5-3290-4d7a-b22a-71940bda7ec0","source":{"type":"Context","id":"2a9f4a4b-5f3e-4eee-9630-e2f7b2e58c34","name":"devsec"}},"children":[]}]