Compare commits

...

70 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
Luca Frosini fda1b553f6 Fixed condition 2022-11-11 12:01:04 +01:00
Luca Frosini 1d2af818c2 Removed -SNAPSHOT to release the component 2022-10-19 11:50:39 +02:00
Luca Frosini d52621961c Merge branch 'master' of gitea@code-repo.d4science.org:gCubeSystem/resource-registry-api.git 2022-07-22 14:41:34 +02:00
Luca Frosini 97f3f6c2e9 Fixed CHANGELOG 2022-07-22 14:41:16 +02:00
Luca Frosini aa501ed35d Backported service instance predictive URL 2022-07-21 16:41:25 +02:00
Luca Frosini c253696868 Reorganized query and path parameters constants 2022-07-20 12:09:07 +02:00
Luca Frosini eb609e5a72 Removed empty line 2022-07-18 16:33:08 +02:00
Luca Frosini 2025a20586 Removed uneeded parameters 2022-07-18 16:27:21 +02:00
Luca Frosini 499dea63f8 ignored ini file 2022-07-18 15:48:59 +02:00
Luca Frosini 9819a1bd7f Added comment 2022-07-14 15:50:29 +02:00
Luca Frosini be64562088 Removed uneeded dependecy 2022-07-07 11:35:05 +02:00
Luca Frosini 4306f81be6 Fixed service class 2022-06-13 14:29:05 +02:00
Luca Frosini 0e67832e24 Added a way to force add to context 2022-06-08 16:04:35 +02:00
Luca Frosini d5411dd739 Fixed ContextCache clean 2022-06-07 17:24:34 +02:00
Luca Frosini a7b98b71f5 Refactored package name 2022-02-01 16:45:34 +01:00
Luca Frosini 6a5c7ae7c1 Added QueryTemplate dedicated exceptions 2022-02-01 16:45:21 +01:00
Luca Frosini e635e0817e Added support for context names included in header among UUIDs 2021-10-28 11:17:54 +02:00
Luca Frosini 1e7a8d606a Fixed import due to packages renaming 2021-10-25 11:38:51 +02:00
Luca Frosini 05ffdc68a2 Aligned package names 2021-10-25 10:59:11 +02:00
Luca Frosini fd64e5fc85 Adding Query Templates support 2021-10-21 19:08:11 +02:00
Luca Frosini 95c1400f0f Fixed package 2021-10-21 19:07:45 +02:00
Luca Frosini 16cd10f5e1 Enhanced version and fixed CHANGELOG 2021-10-21 17:01:11 +02:00
Luca Frosini 5f1246befb Adding QueryTemplates support 2021-10-21 16:59:40 +02:00
Luca Frosini ba01253865 Added useful overloaded method 2021-09-17 11:42:42 +02:00
Luca Frosini e0f0985ef6 Removed old query parameter which cause only bugs 2021-07-07 11:57:28 +02:00
Luca Frosini 548ddfa32a Added a _ prefix for query parameters to avoid constraint clashes 2021-07-07 11:23:07 +02:00
Luca Frosini 26b1f8c4ec Aligned distro files with new specification 2021-06-29 18:13:42 +02:00
Luca Frosini 0043f967ad Updated gcube-bom version 2021-06-29 18:13:24 +02:00
Luca Frosini fdd2865050 Added SchemaViolationException refs #7355 #18216 #20531 2021-02-16 17:01:26 +01:00
Luca Frosini 9d9d0e3fe0 Added query param #20298 2021-01-28 23:00:40 +01:00
77 changed files with 6537 additions and 297 deletions

1
.gitignore vendored
View File

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

View File

@ -2,11 +2,39 @@ 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]
- Added support for context names included in header among UUIDs [#22090]
- Added support for Json Query [#22047]
- Added support for Query Templates [#22091]
- Added class to get service URL [#23658]
## [v4.1.0]
- 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]

26
FUNDING.md Normal file
View File

@ -0,0 +1,26 @@
# Acknowledgments
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](https://cordis.europa.eu/project/id/004260) (grant no. 004260).
- the Seventh Framework Programme for research, technological development and demonstration
- [D4Science](https://cordis.europa.eu/project/id/212488) (grant no. 212488);
- [D4Science-II](https://cordis.europa.eu/project/id/239019) (grant no.239019);
- [ENVRI](https://cordis.europa.eu/project/id/283465) (grant no. 283465);
- [iMarine](https://cordis.europa.eu/project/id/283644) (grant no. 283644);
- [EUBrazilOpenBio](https://cordis.europa.eu/project/id/288754) (grant no. 288754).
- the H2020 research and innovation programme
- [SoBigData](https://cordis.europa.eu/project/id/654024) (grant no. 654024);
- [PARTHENOS](https://cordis.europa.eu/project/id/654119) (grant no. 654119);
- [EGI-Engage](https://cordis.europa.eu/project/id/654142) (grant no. 654142);
- [ENVRI PLUS](https://cordis.europa.eu/project/id/654182) (grant no. 654182);
- [BlueBRIDGE](https://cordis.europa.eu/project/id/675680) (grant no. 675680);
- [PerformFISH](https://cordis.europa.eu/project/id/727610) (grant no. 727610);
- [AGINFRA PLUS](https://cordis.europa.eu/project/id/731001) (grant no. 731001);
- [DESIRA](https://cordis.europa.eu/project/id/818194) (grant no. 818194);
- [ARIADNEplus](https://cordis.europa.eu/project/id/823914) (grant no. 823914);
- [RISIS 2](https://cordis.europa.eu/project/id/824091) (grant no. 824091);
- [EOSC-Pillar](https://cordis.europa.eu/project/id/857650) (grant no. 857650);
- [Blue Cloud](https://cordis.europa.eu/project/id/862409) (grant no. 862409);
- [SoBigData-PlusPlus](https://cordis.europa.eu/project/id/871042) (grant no. 871042);

View File

@ -45,26 +45,4 @@ 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);
- iMarine(grant no. 283644);
- EUBrazilOpenBio (grant no. 288754).
- the H2020 research and innovation programme
- SoBigData (grant no. 654024);
- PARTHENOS (grant no. 654119);
- EGIEngage (grant no. 654142);
- ENVRIplus (grant no. 654182);
- BlueBRIDGE (grant no. 675680);
- PerformFish (grant no. 727610);
- AGINFRAplus (grant no. 731001);
- DESIRA (grant no. 818194);
- ARIADNEplus (grant no. 823914);
- RISIS2 (grant no. 824091);
The projects leading to this software have received funding from a series of European Union programmes see [FUNDING.md](FUNDING.md)

16
pom.xml
View File

@ -10,7 +10,7 @@
<groupId>org.gcube.information-system</groupId>
<artifactId>resource-registry-api</artifactId>
<version>4.1.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.0.1</version>
<version>2.4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -44,11 +44,7 @@
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-client</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>gxHTTP</artifactId>
<artifactId>common-utility-sg3</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@ -66,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

@ -5,7 +5,7 @@ package org.gcube.informationsystem.resourceregistry.api;
*/
public class Constants {
public static final String SERVICE_CLASS = "InformationSystem";
public static final String SERVICE_CLASS = "org.gcube.information-system";
public static final String SERVICE_NAME = "resource-registry";
public static final String SERVICE_ENTRY_NAME = "org.gcube.informationsystem.resourceregistry.ResourceInitializer";

View File

@ -2,20 +2,27 @@ 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;
import org.gcube.informationsystem.context.impl.entities.ContextImpl;
import org.gcube.informationsystem.context.impl.relations.IsParentOfImpl;
import org.gcube.informationsystem.context.reference.entities.Context;
import org.gcube.informationsystem.context.reference.relations.IsParentOf;
import org.gcube.informationsystem.contexts.impl.entities.ContextImpl;
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, expiringTimeout);
}
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)) {
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);
}
@ -159,6 +191,11 @@ public class ContextCache {
return uuidToContextFullName.get(uuid);
}
public synchronized String getContextFullNameByUUID(String uuid) throws ResourceRegistryException {
refreshContextsIfNeeded();
return uuidToContextFullName.get(UUID.fromString(uuid));
}
public synchronized UUID getUUIDByFullName(String contextFullName) throws ResourceRegistryException {
refreshContextsIfNeeded();
return contextFullNameToUUID.get(contextFullName);
@ -169,9 +206,14 @@ public class ContextCache {
return uuidToContext.get(uuid);
}
public synchronized Context getContextByUUID(String uuid) throws ResourceRegistryException {
refreshContextsIfNeeded();
return getContextByUUID(UUID.fromString(uuid));
}
public synchronized Context getContextByFullName(String contextFullName) throws ResourceRegistryException {
UUID uuid = getUUIDByFullName(contextFullName);
return uuidToContext.get(uuid);
return getContextByUUID(uuid);
}
/**
@ -179,7 +221,7 @@ public class ContextCache {
*/
public synchronized Map<UUID, String> getUUIDToContextFullNameAssociation() throws ResourceRegistryException {
refreshContextsIfNeeded();
return new HashMap<>(uuidToContextFullName);
return new LinkedHashMap<>(uuidToContextFullName);
}
/**
@ -187,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

@ -2,9 +2,12 @@ package org.gcube.informationsystem.resourceregistry.api.contexts;
import java.util.List;
import org.gcube.informationsystem.context.reference.entities.Context;
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

@ -2,30 +2,42 @@ package org.gcube.informationsystem.resourceregistry.api.contexts;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
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> getContextUUIDSet(String jsonArray) throws IOException {
ObjectMapper mapper = ElementMapper.getObjectMapper();
JavaType type = mapper.getTypeFactory().constructCollectionType(HashSet.class, UUID.class);
return mapper.readValue(jsonArray, type);
}
// 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);
// }
//
// public static Set<String> getContextFullNameSet(String jsonArray) throws Exception {
// Set<UUID> uuids = getContextUUIDSet(jsonArray);
// return getContextFullNameSet(uuids);
// }
public static Set<String> getContextFullNameSet(String jsonArray) throws Exception {
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);
return mapper.readValue(objectnode, type);
}
public static Set<UUID> getContextUUIDSet(Collection<String> uuidStrings) throws Exception {
@ -37,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

@ -1,4 +1,4 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.context;
package org.gcube.informationsystem.resourceregistry.api.exceptions.contexts;
import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException;

View File

@ -1,7 +1,7 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.exceptions.context;
package org.gcube.informationsystem.resourceregistry.api.exceptions.contexts;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.context;
package org.gcube.informationsystem.resourceregistry.api.exceptions.contexts;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ContextException extends ResourceRegistryException {

View File

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

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.context;
package org.gcube.informationsystem.resourceregistry.api.exceptions.contexts;
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ContextNotFoundException extends NotFoundException {

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities;
import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class EntityAlreadyPresentException extends AlreadyPresentException {

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities;
import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAnotherContextException;

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities;
import org.gcube.informationsystem.resourceregistry.api.exceptions.CreationException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class EntityCreationException extends CreationException {

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities;
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class EntityNotFoundException extends NotFoundException {

View File

@ -1,11 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.facet;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityAlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class FacetAlreadyPresentException extends EntityAlreadyPresentException {

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.facet;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityAvailableInAnotherContextException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,9 +1,9 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.facet;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityCreationException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityCreationException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,11 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityNotFoundException;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.facet;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityNotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class FacetNotFoundException extends EntityNotFoundException {

View File

@ -1,11 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityAlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ResourceAlreadyPresentException extends EntityAlreadyPresentException {

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityAvailableInAnotherContextException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,9 +1,9 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityCreationException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityCreationException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,11 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityNotFoundException;
package org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.EntityNotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ResourceNotFoundException extends EntityNotFoundException {

View File

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

View File

@ -0,0 +1,27 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.queries.templates;
import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class QueryTemplateAlreadyPresentException extends AlreadyPresentException {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = -3185950257529005913L;
public QueryTemplateAlreadyPresentException(String message) {
super(message);
}
public QueryTemplateAlreadyPresentException(Throwable cause) {
super(cause);
}
public QueryTemplateAlreadyPresentException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,27 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.exceptions.queries.templates;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class QueryTemplateCreationException extends QueryTemplateException {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = 7777044293030289951L;
public QueryTemplateCreationException(String message) {
super(message);
}
public QueryTemplateCreationException(Throwable cause) {
super(cause);
}
public QueryTemplateCreationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,27 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.queries.templates;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class QueryTemplateException extends ResourceRegistryException {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = 8119058749936021156L;
public QueryTemplateException(String message) {
super(message);
}
public QueryTemplateException(Throwable cause) {
super(cause);
}
public QueryTemplateException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,27 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.queries.templates;
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class QueryTemplateNotFoundException extends NotFoundException {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = 3034336911176161784L;
public QueryTemplateNotFoundException(String message) {
super(message);
}
public QueryTemplateNotFoundException(Throwable cause) {
super(cause);
}
public QueryTemplateNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations;
import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException;

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations;
import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAnotherContextException;

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations;
import org.gcube.informationsystem.resourceregistry.api.exceptions.CreationException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class RelationCreationException extends CreationException {

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations;
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.consistsOf;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.consistsof;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationAlreadyPresentException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationAlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.consistsOf;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.consistsof;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationAvailableInAnotherContextException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.consistsOf;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.consistsof;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationCreationException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationCreationException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class ConsistsOfCreationException extends RelationCreationException {

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.consistsOf;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.consistsof;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationNotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isparentof;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isparentof;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationAlreadyPresentException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationAlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,8 +1,7 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isparentof;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isparentof;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class IsParentOfCreationException extends IsParentOfException {

View File

@ -1,7 +1,10 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isparentof;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isparentof;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class IsParentOfException extends ResourceRegistryException {
/**

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isparentof;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isparentof;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationNotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isrelatedto;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isrelatedto;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationAlreadyPresentException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationAlreadyPresentException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isrelatedto;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isrelatedto;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationAvailableInAnotherContextException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isrelatedto;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isrelatedto;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationCreationException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationCreationException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class IsRelatedToCreationException extends RelationCreationException {

View File

@ -1,6 +1,6 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.relation.isrelatedto;
package org.gcube.informationsystem.resourceregistry.api.exceptions.relations.isrelatedto;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationNotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.schema;
package org.gcube.informationsystem.resourceregistry.api.exceptions.types;
import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException;

View File

@ -1,7 +1,7 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.exceptions.schema;
package org.gcube.informationsystem.resourceregistry.api.exceptions.types;
/**
* @author Luca Frosini (ISTI - CNR)

View File

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

View File

@ -1,10 +1,9 @@
package org.gcube.informationsystem.resourceregistry.api.exceptions.schema;
package org.gcube.informationsystem.resourceregistry.api.exceptions.types;
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public class SchemaNotFoundException extends NotFoundException {

View File

@ -0,0 +1,26 @@
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 {
/**
* Generated Serial Version UID
*/
private static final long serialVersionUID = -2563703637351710301L;
public SchemaViolationException(String message) {
super(message);
}
public SchemaViolationException(Throwable cause) {
super(cause);
}
public SchemaViolationException(String message, Throwable cause) {
super(message, cause);
}
}

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

@ -5,39 +5,41 @@ package org.gcube.informationsystem.resourceregistry.api.rest;
*/
public class AccessPath {
public static final String HIERARCHICAL_MODE_PARAM = InstancePath.HIERARCHICAL_MODE_PARAM;
public static final String INCLUDE_CONTEXTS_IN_HEADER_PARAM = InstancePath.INCLUDE_CONTEXTS_IN_HEADER_PARAM;
public static final String TYPE_PATH_PARAM = "TYPE_NAME";
public static final String UUID_PATH_PARAM = "UUID";
public static final String CONTEXT_UUID_PATH_PARAM = "CONTEXT_UUID";
public static final String ACCESS_PATH_PART = "access";
public static final String CONTEXTS_PATH_PART = ContextPath.CONTEXTS_PATH_PART;
public static final String TYPES_PATH_PART = TypePath.TYPES_PATH_PART;
public static final String INSTANCES_PATH_PART = InstancePath.INSTANCES_PATH_PART;
public static final String QUERY_TEMPLATES_PATH_PART = QueryTemplatePath.QUERY_TEMPLATES_PATH_PART;
public static final String QUERY_PATH_PART = "query";
public static final String QUERY_PARAM = "q";
public static final String Q_QUERY_PARAMETER = "q";
public static final String RAW_QUERY_PARAMETER = "raw";
public static final String RAW_QUERY_PARAMETER_DEFAULT_VALUE = "false";
public static final String LIMIT_PARAM = "limit";
public static final int UNBOUNDED = -1;
public static final int DEFAULT_LIMIT = 20;
public static final String HIERARCHICAL_MODE_QUERY_PARAMETER = InstancePath.HIERARCHICAL_MODE_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 FETCH_PLAN_PARAM = "fetchPlan";
public static final String DEFAULT_FETCH_PLAN_PARAM = "*:-1";
public static final String RAW_PARAM = "raw";
public static final String DEFAULT_RAW_PARAM = "false";
public static final String OFFSET_QUERY_PARAMETER = InstancePath.OFFSET_QUERY_PARAMETER;
public static final String LIMIT_QUERY_PARAMETER = InstancePath.LIMIT_QUERY_PARAMETER;
public static final String RESOURCE_TYPE_PATH_PART = "RESOURCE_TYPE_NAME";
public static final String RELATION_TYPE_PATH_PART = "RELATION_TYPE_NAME";
public static final String REFERENCE_TYPE_PATH_PART = "REFERENCE_TYPE_NAME";
public static final String REFERENCE_PARAM = "reference";
public static final String POLYMORPHIC_PARAM = "polymorphic";
public static final String DIRECTION_PARAM = "direction";
public static final String CURRENT_CONTEXT = "CURRENT_CONTEXT";
/**
* Used only in getRelated() function
* The _ is prepended to avoid clash with field name
*/
public static final String _REFERENCE_QUERY_PARAMETER = "_reference";
/**
* Used only in getRelated() function
* The _ is prepended to avoid clash with field name
*/
public static final String _POLYMORPHIC_QUERY_PARAMETER = "_polymorphic";
/**
* Used only in getRelated() function
* The _ is prepended to avoid clash with field name
*/
public static final String _DIRECTION_QUERY_PARAMETER = "_direction";
}

View File

@ -1,6 +1,3 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.rest;
/**
@ -10,4 +7,10 @@ public class ContextPath {
public static final String CONTEXTS_PATH_PART = "contexts";
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,31 +0,0 @@
/**
*
*/
package org.gcube.informationsystem.resourceregistry.api.rest;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ERPath {
public static final String ER_PATH_PART = "er";
protected static final String PROPERTY_PATH_PART = "property";
protected static final String ENTITY_PATH_PART = "entity";
public static final String FACET_PATH_PART = "facet";
public static final String RESOURCE_PATH_PART = "resource";
protected static final String RELATION_PATH_PART = "relation";
public static final String CONSISTS_OF_PATH_PART = "consistsOf";
public static final String IS_RELATED_TO_PATH_PART = "isRelatedTo";
public static final String SOURCE_PATH_PART = "source";
public static final String TARGET_PATH_PART = "target";
public static final String ADD_PATH_PART = "add";
public static final String REMOVE_PATH_PART = "remove";
}

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 POLYMORPHIC_PARAM = AccessPath.POLYMORPHIC_PARAM;
public static final String OFFSET_QUERY_PARAMETER = "offset";
public static final String LIMIT_QUERY_PARAMETER = "limit";
public static final String HIERARCHICAL_MODE_PARAM = "hierarchical";
public static final String POLYMORPHIC_QUERY_PARAMETER = "polymorphic";
public static final String INCLUDE_CONTEXTS_IN_HEADER_PARAM = "includeContextsInHeader";
public static final String HIERARCHICAL_MODE_QUERY_PARAMETER = "hierarchical";
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

@ -0,0 +1,14 @@
package org.gcube.informationsystem.resourceregistry.api.rest;
/**
* @author Luca Frosini (ISTI - CNR)
*/
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

@ -0,0 +1,27 @@
package org.gcube.informationsystem.resourceregistry.api.rest;
import org.gcube.common.context.ContextUtility;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public abstract class ServiceInstance {
private static final String PROD_ROOT_SCOPE = "/d4science.research-infrastructures.eu";
public static final String BASE_URL = "https://url.d4science.org";
public static String getServiceURL() {
String context = ContextUtility.getCurrentContextFullName();
return getServiceURL(context);
}
public static String getServiceURL(String context) {
if(context.startsWith(PROD_ROOT_SCOPE)) {
return BASE_URL;
}
String root = context.split("/")[1];
return BASE_URL.replace("url", "url." + root.replaceAll("\\.", "-"));
}
}

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";
@ -13,6 +16,16 @@ public class SharingPath {
REMOVE
}
public static final String DRY_RUN_QUERY_PARAMETER = "dryRun";
public static final String DRY_RUN_QUERY_QUERY_PARAMETER = "dryRun";
/**
* Used to add a resource to a context independently from the source
* context.
*/
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_PARAM = AccessPath.POLYMORPHIC_PARAM;
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

@ -6,7 +6,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import org.gcube.common.gxhttp.reference.GXConnection.HTTPMETHOD;
import org.gcube.informationsystem.base.reference.Element;
import org.gcube.informationsystem.model.reference.entities.Facet;
import org.gcube.informationsystem.model.reference.entities.Resource;
@ -15,16 +14,19 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAn
import org.gcube.informationsystem.resourceregistry.api.exceptions.ExceptionMapper;
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
import org.gcube.informationsystem.utils.ElementMapper;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.facet.FacetAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.facet.FacetNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entities.resource.ResourceAvailableInAnotherContextException;
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.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);
@ -74,7 +76,7 @@ public class HTTPUtility {
int responseCode = connection.getResponseCode();
String responseMessage = connection.getResponseMessage();
if(connection.getRequestMethod().compareTo(HTTPMETHOD.HEAD.toString())==0) {
if(connection.getRequestMethod().compareTo("HEAD")==0) {
if(responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
return null;
}

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);
}
}

1
src/test/resources/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/config.ini

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":[]}]