Resource Registry Service - Query & Access

From Gcube Wiki
Revision as of 11:10, 27 January 2022 by Luca.frosini (Talk | contribs) (JSON Query for Facet)

Jump to: navigation, search

This section provides information regarding how to interact with Resource Registry Service for Query and Access. REST and JAVA API are presented for each functionality.

Please note that the provided examples can intentionally hide some details in the response to avoid unneeded complexity.

Query & Access

Query & Access exposes the safe methods available in the dedicated collection plus 2 APIs dedicated to query the instances.

  • List Contexts: it allows to enumerate the contexts;
  • Read Context: it allows to read a context;
  • Read: it allows reading a Type. This API allows also the listing of type and its subtypes by indicating the query parameter polymorphic=true.
  • List Instances: it allows to list instances of a certain type;
  • Exists Instance: it allows to check if an instance exists in a certain context;
  • Read Instace: it allows to get the representation of the requested instance in a certain context;
  • Get Instance Contexts: it allows to get the list of contexts an instance belongs to;
  • Prepared Query: it allows to query the graph in respect to the model;
  • Raw Query: it allows to query the raw graph used to represent the model in the backend.

On this page, the APIs already available in the dedicated collection will not be presented. Please check the dedicated page. The reason to expose the safe method already available in the dedicated collection is for security reasons.

Query & Access Collection

Operation HTTP Method URL
Access To Contexts
List Contexts GET /access/contexts
Read Context GET /access/contexts/{UUID}
Access To Types
Read Type GET /access/types/{TYPE_NAME}[?polymorphic=true]
Access To Instances
List Instances GET /access/instances/{TYPE_NAME}[?polymorphic=true]
Exists Instance /access/instances/{TYPE_NAME}/{UUID}
Read Instace GET /access/instances/{TYPE_NAME}/{UUID}
Get Instace Contexts GET /access/instances/{TYPE_NAME}/{UUID}/contexts
Access To Query Templates
List Query Templates GET /access/query-templates
Read Query Template GET /access/query-templates/{QUERY_TEMPLATE_NAME}
Query
Prepared Query GET /access/query/{RESOURCE_TYPE_NAME}/{RELATION_TYPE_NAME}/{ENTITY_TYPE_NAME}[?reference={REFERENCE_ENTITY_UUID}&polymorphic=true&direction=out]
Query GET /access/query?q={QUERY}
JSON Query POST /access/query

Resource Registry Client

Resource Registry Client is a java library providing RPC facilities to interact with Query & Access Collection. The library hides all the complexity of marshalling and unmarshalling of requests and results. By using this library any client is able to manage java classes instead of JSON objects.

To use the Java library to interact with [#Query & Access Collection | Query & Access Collection]] declare the following dependency in your pom.xml file.

<dependency>
	<groupId>org.gcube.information-system</groupId>
	<artifactId>resource-registry-client</artifactId>
	<version>[4.0.0,5.0.0-SNAPSHOT)</version>
<dependency>

To use the client you just need to instantiate the client via the provided factory.

import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory;
 
...
 
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();

APIs

Prepared Query

This APIs allows getting a list of resources respecting some constraints.

Prepared Query via Java client

public <R extends Resource, C extends ConsistsOf<?,?>, F extends Facet> List<R> getResourcesFromReferenceFacet(Class<R> resourceClass, Class<C> consistsOfClass, F referenceFacet, boolean polymorphic) throws ResourceRegistryException;
 
public <R extends Resource, C extends ConsistsOf<?,?>, F extends Facet> List<R> getResourcesFromReferenceFacet(Class<R> resourceClass, Class<C> consistsOfClass, Class<F> facetClass, UUID referenceFacetUUID, boolean polymorphic) throws ResourceRegistryException;
 
public String getResourcesFromReferenceFacet(String resourceType, String consistsOfType, String facetType, UUID referenceFacetUUID, boolean polymorphic) throws ResourceRegistryException;
 
 
 
public <R extends Resource, C extends ConsistsOf<?,?>, F extends Facet> List<R> getFilteredResources(Class<R> resourceClass, Class<C> consistsOfClass, Class<F> facetClass, boolean polymorphic, Map<String,String> facetConstraint) throws ResourceRegistryException;
 
public String getFilteredResources(String resourceType, String consistsOfType, String facetType, boolean polymorphic, Map<String,String> facetConstraint) throws ResourceRegistryException;
 
 
 
public <R extends Resource, I extends IsRelatedTo<?,?>, RR extends Resource> List<R> getRelatedResourcesFromReferenceResource(Class<R> resourceClass, Class<I> isRelatedToClass, RR referenceResource, Direction direction, boolean polymorphic) throws ResourceRegistryException;
 
public <R extends Resource, I extends IsRelatedTo<?,?>, RR extends Resource> List<R> getRelatedResourcesFromReferenceResource(Class<R> resourceClass, Class<I> isRelatedToClass, Class<RR> referenceResourceClass, UUID referenceResourceUUID, Direction direction, boolean polymorphic) throws ResourceRegistryException;
 
public String getRelatedResourcesFromReferenceResource(String resourceType, String isRelatedToType, String referenceResourceType, UUID referenceResourceUUID, Direction direction, boolean polymorphic) throws ResourceRegistryException;
 
 
 
public <R extends Resource, I extends IsRelatedTo<?,?>, RR extends Resource> List<R> getRelatedResources(Class<R> resourceClass, Class<I> isRelatedToClass, Class<RR> referenceResourceClass, Direction direction, boolean polymorphic) throws ResourceRegistryException;
 
public String getRelatedResources(String resourceType, String isRelatedToType, String referenceResourceType, Direction direction, boolean polymorphic) throws ResourceRegistryException;
Prepared Query via Java client Example 1

All the EService identified by a SoftwareFacet.

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
List<EService> list = resourceRegistryClient.getFilteredResources(EService.class, IsIdentifiedBy.class, SoftwareFacet.class, true, null);

An alternative API is

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
String jsonString = resourceRegistryClient.getFilteredResources("EService", "IsIdentifiedBy", "SoftwareFacet", true, null);
List<EService> list = ElementMapper.unmarshalList(EService.class, jsonString);

The direction can only be out because IsIdentifiedBy is an out relation (it is a ConsistsOf) form EService.

The EService schema imposes the SoftwareFacet with IsIdentifiedBy, so this query has the same result of getting all the EService instances.

Prepared Query via Java client Example 2

The EService identified By the SoftwareFacet with UUID 97984812-90e6-4eb7-b804-50a9ad3fe4fb.

Request URL

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
UUID uuid = UUID.fromString("97984812-90e6-4eb7-b804-50a9ad3fe4fb");
List<EService> list = resourceRegistryClient.getResourcesFromReferenceFacet(EService.class, IsIdentifiedBy.class, SoftwareFacet.class, uuid, true);

Alternative APIs are

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
SoftwareFacet softwareFacetInstance = new SoftwareFacetImpl();
UUID uuid = UUID.fromString("97984812-90e6-4eb7-b804-50a9ad3fe4fb");
Header header = new HeaderImpl(uuid);
softwareFacetInstance.setHeader(header);
List<EService> list = resourceRegistryClient.getResourcesFromReferenceFacet(EService.class, IsIdentifiedBy.class, softwareFacetInstance, true);


ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
UUID uuid = UUID.fromString("97984812-90e6-4eb7-b804-50a9ad3fe4fb");
String jsonString = resourceRegistryClient.getResourcesFromReferenceFacet("EService", "IsIdentifiedBy", "SoftwareFacet", uuid, true);
List<EService> list = ElementMapper.unmarshalList(EService.class, jsonString);
Prepared Query via Java client Example 3

The EService identified by the SoftwareFacet with the following constraint group=VREManagement AND name=WhnManager

Request URL

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
Map<String, String> facetConstraints = new HashMap<>();
facetConstraints.put("group", "VREManagement");
facetConstraints.put("name", "WhnManager");
 
List<EService> list = resourceRegistryClient.getFilteredResources(EService.class, IsIdentifiedBy.class, SoftwareFacet.class, true, facetConstraints);

An alternative API is

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
Map<String, String> facetConstraints = new HashMap<>();
facetConstraints.put("group", "VREManagement");
facetConstraints.put("name", "WhnManager");
 
String jsonString = resourceRegistryClient.getFilteredResources("EService", "IsIdentifiedBy", "SoftwareFacet", true, facetConstraints);
List<EService> list = ElementMapper.unmarshalList(EService.class, jsonString);
Prepared Query via Java client Example 4

All the Resources identified By a ContactFacet

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
List<Resource> list = resourceRegistryClient.getFilteredResources(Resource.class, IsIdentifiedBy.class, ContactFacet.class, true, null);

An alternative API is

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
String jsonString = resourceRegistryClient.getFilteredResources("Resource", "IsIdentifiedBy", "ContactFacet", true, null);
List<Resource> list = ElementMapper.unmarshalList(Resource.class, jsonString);
Prepared Query via Java client Example 5

All the Resources with a ContactFacet.

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
List<Resource> list = resourceRegistryClient.getFilteredResources(Resource.class, ConsistsOf.class, ContactFacet.class, true, null);

An alternative API is

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
String jsonString = resourceRegistryClient.getFilteredResources("Resource", "ConsistsOf", "ContactFacet", true, null);
List<Resource> list = ElementMapper.unmarshalList(Resource.class, jsonString);
Prepared Query via Java client Example 6

All the Resources with a ContactFacet with the following constraint name=Luca AND Surname=Frosini.

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
Map<String, String> facetConstraints = new HashMap<>();
facetConstraints.put("name", "Luca");
facetConstraints.put("surname", "Frosini");
 
List<Resource> list = resourceRegistryClient.getFilteredResources(Resource.class, ConsistsOf.class, ContactFacet.class, true, facetConstraints);

An alternative API is

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
Map<String, String> facetConstraints = new HashMap<>();
facetConstraints.put("name", "Luca");
facetConstraints.put("surname", "Frosini");
 
String jsonString = resourceRegistryClient.getFilteredResources("Resource", "ConsistsOf", "ContactFacet", true, facetConstraints);
List<Resource> list = ElementMapper.unmarshalList(Resource.class, jsonString);
Prepared Query via Java client Example 7

All the EService having an incoming (IN) Hosts relation with an HostingNode (i.e. all Smartgears services).

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
List<EService> list = resourceRegistryClient.getRelatedResources(EService.class, Hosts.class, HostingNode.class, Direction.IN, true);

An alternative API is

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
String jsonString = resourceRegistryClient.getRelatedResources("EService", "Hosts", "HostingNode", Direction.IN, true);
List<EService> list = ElementMapper.unmarshalList(EService.class, jsonString);
Prepared Query via Java client Example 8

All the EService having an incoming (IN) Hosts relation (i.e. hosted by) the HostingNode with UUID 16032d09-3823-444e-a1ff-a67de4f350a.

In other words, it returns all the EService running on the HostingNode with UUID 16032d09-3823-444e-a1ff-a67de4f350a..

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
UUID uuid = UUID.fromString("16032d09-3823-444e-a1ff-a67de4f350a");
List<EService> list = resourceRegistryClient.getRelatedResourcesFromReferenceResource(EService.class, Hosts.class, HostingNode.class, uuid, Direction.IN, true);

Alternative APIs are

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
HostingNode hostingNodeInstance = new HostingNodeImpl();
UUID uuid = UUID.fromString("16032d09-3823-444e-a1ff-a67de4f350a");
Header header = new HeaderImpl(uuid);
hostingNodeInstance.setHeader(header);
List<EService> list = resourceRegistryClient.getRelatedResourcesFromReferenceResource(EService.class, Hosts.class, hostingNodeInstance, Direction.IN, true);


ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
UUID uuid = UUID.fromString("16032d09-3823-444e-a1ff-a67de4f350a");
String jsonString = resourceRegistryClient.getRelatedResourcesFromReferenceResource("EService", "Hosts", "HostingNode", uuid, Direction.IN, true);
List<EService> list = ElementMapper.unmarshalList(EService.class, jsonString);

Prepared Query via REST API

GET /access/query/{RESOURCE_TYPE_NAME}/{RELATION_TYPE_NAME}/{ENTITY_TYPE_NAME}[?_polymorphic=false&_direction=out&_reference={REFERENCE_ENTITY_UUID}]&[name1=value1&name2=value2&name3=value3]
Code Type Description
200 String A JSON array of filtered resources.
Prepared Query via REST API Example 1

All the EService identified by a SoftwareFacet.

Request URL

GET /access/query/EService/IsIdentifiedBy/SoftwareFacet?_polymorphic=true&_direction=out

The direction can only be out because IsIdentifiedBy is an out relation (it is a ConsistsOf) form EService.

The EService schema imposes the SoftwareFacet with IsIdentifiedBy, so this query has the same result of getting all the EService instances.

Prepared Query via REST API Example 2

The EService identified By the SoftwareFacet with UUID 97984812-90e6-4eb7-b804-50a9ad3fe4fb.

Request URL

GET /access/query/EService/IsIdentifiedBy/SoftwareFacet?_polymorphic=true&_direction=out&_reference=97984812-90e6-4eb7-b804-50a9ad3fe4fb
Prepared Query via REST API Example 3

The EService identified by the SoftwareFacet with the following constraint group=VREManagement AND name=WhnManager

Request URL

GET /access/query/EService/IsIdentifiedBy/SoftwareFacet?_polymorphic=true&_direction=out&group=VREManagement&name=WhnManager
Prepared Query via REST API Example 4

All the Resources identified By a ContactFacet

Request URL

GET /access/query/Resource/IsIdentifiedBy/ContactFacet?_polymorphic=true&_direction=out
Prepared Query via REST API Example 5

All the Resources with a ContactFacet.

Request URL

GET /access/query/Resource/ConsistsOf/ContactFacet?_polymorphic=true&_direction=out
Prepared Query via REST API Example 6

All the Resources with a ContactFacet with the following constraint name=Luca AND Surname=Frosini.

Request URL

GET /access/query/Resource/ConsistsOf/ContactFacet?_polymorphic=true&_direction=out&name=Luca&surname=Frosini
Prepared Query via REST API Example 7

All the EService having an incoming (IN) Hosts relation with an HostingNode (i.e. all Smartgears services).

Request URL

GET /access/query/EService/Hosts/HostingNode?_polymorphic=true&_direction=in
Prepared Query via REST API Example 8

All the EService having an incoming (IN) Hosts relation (i.e. hosted by) the HostingNode with UUID 16032d09-3823-444e-a1ff-a67de4f350a.

In other words, it returns all the EService running on the HostingNode with UUID 16032d09-3823-444e-a1ff-a67de4f350a..

Request URL

GET /access/query/EService/Hosts/HostingNode?_polymorphic=true&_direction=in&reference=16032d09-3823-444e-a1ff-a67de4f350a8

This query return all the EService running on the reference HostingNode.

Raw Query

This API provides a way to query the underlying database persistence by using the persistence query language dialect. This API does not guarantee consistency with the IS Model concepts. The result is related to how the service decide to represent the IS Model concepts on the persistence data model.

At the time of writing the underlying database, persistence is OrientDB. It should be used only for development purposes only because the way to represent the IS Model concepts can change at any time or can change the database persistence.

At the time of writing the query language supported is OrientDB SQL Dialect.

Raw Query via Java Client

public String query(final String query, final int limit, final String fetchPlan) throws InvalidQueryException, ResourceRegistryException;
 
public String query(final String query, final int limit, final String fetchPlan, boolean raw) throws InvalidQueryException, ResourceRegistryException;
Raw Query via Java Client Example 1

This query request one (limit=1) SoftwareFacet as represented in the underling db (raw=true).

This query must be used only by the administrators for debugging purposes.

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
String jsonString = resourceRegistryClient.query("SELECT FROM SoftwareFacet", 1, null, true);
Raw Query via REST API Example 2

This query request one (limit=1) SoftwareFacet represented according to the IS Model.

This is the same query of the previous example but the service transforms the result according to the IS Model.

ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
String jsonString = resourceRegistryClient.query("SELECT FROM SoftwareFacet", 1, null);
List<SoftwareFacet> list = ElementMapper.unmarshalList(SoftwareFacet.class, jsonString);

Raw Query via REST API

GET /access/query?q={QUERY}&limit={N}&fetchPlan=*:-1&raw=false
Code Type Description
200 String A JSON object with the result of the raw query.
Raw Query via REST API Example 1

This query request one (limit=1) SoftwareFacet as represented in the underling db (raw=true).

This query must be used only by the administrators for debugging purposes.

Request URL

GET /access/query?limit=10&q=SELECT FROM SoftwareFacet&limit=1&raw=true

Response Body

[
    {
        "@class": "SoftwareFacet",
        "name": "WhnManager",
        "description": "Web Hosting Node Service",
        "header": {
            "@class": "Header",
            "creationTime": "2021-07-01 08:51:02.298 +0200",
            "createdBy": "luca.frosini",
            "uuid": "97984812-90e6-4eb7-b804-50a9ad3fe4fb",
            "lastUpdateBy": "luca.frosini",
            "lastUpdateTime": "2021-07-01 12:35:26.274 +0200"
        },
        "optional": false,
        "_allow": [
            "#4:15",
            "#4:13",
            "#4:11",
            "#4:9",
            "#5:12"
        ],
        "_allowRead": [
            "#4:12",
            "#4:10",
            "#4:16",
            "#4:14"
        ],
        "version": "2.0.0-4.15.0-132431",
        "in_IsIdentifiedBy": [
            "#839:0"
        ],
        "group": "VREManagement"
    }
]

As you can see the response contains a lot of database-specific information. You cannot use or rely on them to interact with the resource registry service.

Raw Query via REST API Example 2

This query request one (limit=1) SoftwareFacet represented according to the IS Model.

This is the same query of the previous example but the service transforms the result according to the IS Model.

Request URL

GET /access/query?limit=10&q=SELECT FROM SoftwareFacet&limit=1&raw=true

Response Body

[
    {
        "name": "WhnManager",
        "description": "Web Hosting Node Service",
        "header": {
            "@class": "Header",
            "creationTime": "2021-07-01 08:51:02.298 +0200",
            "createdBy": "luca.frosini",
            "uuid": "97984812-90e6-4eb7-b804-50a9ad3fe4fb",
            "lastUpdateBy": "luca.frosini",
            "lastUpdateTime": "2021-07-01 12:35:26.274 +0200"
        },
        "optional": "false",
        "version": "2.0.0-4.15.0-132431",
        "group": "VREManagement",
        "@class": "SoftwareFacet",
        "@superClasses": [
            "Facet"
        ]
    }
]


JSON Query

Creating a JSON query is very simple as far as you know the model. You just need to know the shape of the interested instance.

JSON Query for Resources

Let's imagine you want to get the EService representing the down instances of the service identified as DataTransfer:data-transfer-service.

{
	"@class": "EService",
	"consistsOf": [
		{
			"@class": "IsIdentifiedBy",
			"target": {
				"@class": "SoftwareFacet",
				"name": "data-transfer-service",
				"group": "DataTransfer"
			}
		}
		{
			"@class": "ConsistsOf",
			"target": {
				"@class": "StateFacet",
				"value": "down"
			}
		},
 
	]
}

As you can notice the JSON query has exactly the same shape of each instance of the result.


Even more complex queries are really simple:

{
	"@class": "EService",
	"consistsOf": [
		{
			"@class": "ConsistsOf",
			"propagationConstraint" : {
				"add": "propagate"
			},
			"target": {
				"@class": "StateFacet",
				"value": "down"
			}
		},
		{
			"@class": "IsIdentifiedBy",
			"target": {
				"@class": "SoftwareFacet",
				"name": "data-transfer-service",
				"group": "DataTransfer"
			}
		}
	],
	"isRelatedTo" : [
		{
			"@class": "Activates",
			"source": {
				"@class": "HostingNode",
				"consistsOf": [
					{
						"@class": "ConsistsOf",
						"target": {
							"@class": "CPUFacet",
							"vendor": "GenuineIntel"
						}
					}
				]
			}
		}
	]
}

In this query apart from the constraints imposed in the previous query we add a constraint in the ConsistsOf relation with the StateFacet, i.e. the propagation constraint must be propagate for add operations. Moreover, the requested EService must run in an HostingNode with a CPU from the vendor known as GenuineIntel.

JSON Query for Facet

The following query returns the StateFacet of any EService identified as DataTransfer:data-transfer-service.

{
	"@class": "StateFacet",
	"_in": {
		"@class": "ConsistsOf",
		"source" : {
			"@class" : "EService",
			"consistsOf": [
				{
					"@class": "IsIdentifiedBy",
					"target": {
						"@class": "SoftwareFacet",
						"name": "data-transfer-service",
						"group": "DataTransfer"
					}
				}
			]
		}
	}
}

To explain the query, think about the instances in the graph we have

EService --ConsistsOf--> StateFacet

The ConsistsOf relation goes OUT from the EService and arrives IN the StateFacet

EService --OUT--ConsistsOf--IN--> StateFacet

This explains why we need to use the keyword _in in the JSON query. Then, ConsistsOf is represented using the usual representation of a relation.

JSON Query Operators

{
	"@class": "StateFacet",
	"value": "down",
	"_in": {
		"@class": "ConsistsOf",
		"source" : {
			"@class" : "EService",
			"header": {
				"$or": [
					{"$and": {
						"uuid" : "aec0ef31-c735-4a4c-b2f4-57dfbd2fe925",
						"createdBy": {"$ne": "luca.frosini"}
					}},
					{"$and": {
						"uuid" : "0255b7ec-e3da-4071-b456-9a2907ece1db",
						"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080"
					}}
				]
			}
		}
	}
}