Difference between revisions of "Resource Registry Service - Query & Access"

From Gcube Wiki
Jump to: navigation, search
(JSON Query Operators)
(JSON Query via REST API)
 
(46 intermediate revisions by the same user not shown)
Line 14: Line 14:
 
Query & Access exposes the safe methods available in the dedicated collection plus 2 APIs dedicated to query the instances.
 
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;
+
*  Access To Contexts:
* '''Read Context''': it allows to read a context;
+
** '''List Contexts''': it allows enumerating the contexts;
* '''Read''': it allows reading a Type. This API allows also the listing of type and its subtypes by indicating the query parameter polymorphic=true.
+
** '''Exist Context''': it allows checking if a context exists.
* '''List Instances''': it allows to list instances of a certain type;
+
** '''Read Context''': it allows reading a context.
* '''Exists Instance''': it allows to check if an instance exists in a certain context;
+
* Access To Types:
* '''Read Instace''': it allows to get the representation of the requested instance in a certain context;
+
** '''Exist Type''': it allows checking a type exists.
* '''Get Instance Contexts''': it allows to get the list of contexts an instance belongs to;
+
** '''Read Type''': it allows reading a type. This API also allows listing type and its subtypes by indicating the query parameter polymorphic=true.
* '''Prepared Query''': it allows to query the graph in respect to the model;
+
*  Access To Instances :
* '''Raw Query''': it allows to query the raw graph used to represent the model in the backend.
+
** '''List Instances''': it allows listing instances of a specific type;
 +
** '''Exist Instance''': it allows checking if an instance exists in a specific context;
 +
** '''Read Instace''': it allows getting the representation of the requested instance in a specific context;
 +
** '''Get Instance Contexts''': it allows getting the list of contexts an instance belongs to.
 +
*  Access To Query Templates:
 +
** '''List Query Templates''': it allows listing query templates;
 +
** '''Exist Query Template''': it allows checking if a specific query template exists;
 +
** '''Read Query Template''': it allows reading a specific query template;
 +
** '''Run Query Template''': it allows to run a query template by providing the template variable values.
 +
* Query:
 +
** '''Prepared Query''': it allows querying the graph in respect to the model;
 +
** '''Raw Query''': it allows querying the raw graph used to represent the model in the backend;
 +
** '''JSON Query''': it allows querying the raw graph in respect to the model using a JSON representation of the query.
  
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.
+
This page will not present the APIs already available in the dedicated collection. Please check the dedicated page.
 +
The reason to expose the safe method already available in the dedicated collection is security reasons.
  
 
== Query & Access Collection ==
 
== Query & Access Collection ==
Line 35: Line 48:
 
|-
 
|-
 
| List Contexts || GET || <code>/access/contexts</code>
 
| List Contexts || GET || <code>/access/contexts</code>
 +
|-
 +
| Exist Context || HEAD || <code>/access/contexts/{UUID}</code>
 
|-
 
|-
 
| Read Context || GET || <code>/access/contexts/{UUID}</code>
 
| Read Context || GET || <code>/access/contexts/{UUID}</code>
 
|-
 
|-
 
! style="text-align:center; font-weight:bold;" colspan=3 | Access To Types
 
! style="text-align:center; font-weight:bold;" colspan=3 | Access To Types
 +
|-
 +
| Exist Type || HEAD || <code>/access/types/{TYPE_NAME}</code>
 
|-
 
|-
 
| Read Type || GET || <code>/access/types/{TYPE_NAME}[?polymorphic=true]</code>
 
| Read Type || GET || <code>/access/types/{TYPE_NAME}[?polymorphic=true]</code>
Line 46: Line 63:
 
| List Instances || GET || <code>/access/instances/{TYPE_NAME}[?polymorphic=true]</code>
 
| List Instances || GET || <code>/access/instances/{TYPE_NAME}[?polymorphic=true]</code>
 
|-
 
|-
| Exists Instance || HEAD| <code>/access/instances/{TYPE_NAME}/{UUID}</code>
+
| Exist Instance || HEAD || <code>/access/instances/{TYPE_NAME}/{UUID}</code>
 
|-
 
|-
 
| Read Instace || GET || <code>/access/instances/{TYPE_NAME}/{UUID}</code>
 
| Read Instace || GET || <code>/access/instances/{TYPE_NAME}/{UUID}</code>
Line 55: Line 72:
 
|-
 
|-
 
| List Query Templates || GET || <code>/access/query-templates</code>
 
| List Query Templates || GET || <code>/access/query-templates</code>
 +
|-
 +
| Exist Query Template || HEAD || <code>/access/query-templates/{QUERY_TEMPLATE_NAME}</code>
 
|-
 
|-
 
| Read Query Template || GET || <code>/access/query-templates/{QUERY_TEMPLATE_NAME}</code>
 
| Read Query Template || GET || <code>/access/query-templates/{QUERY_TEMPLATE_NAME}</code>
 +
|-
 +
| Run Query Template || POST || <code>/access/query-templates/{QUERY_TEMPLATE_NAME}</code>
 
|-
 
|-
 
! style="text-align:center; font-weight:bold;" colspan=3 | Query
 
! style="text-align:center; font-weight:bold;" colspan=3 | Query
Line 62: Line 83:
 
| Prepared Query || GET || <code>/access/query/{RESOURCE_TYPE_NAME}/{RELATION_TYPE_NAME}/{ENTITY_TYPE_NAME}[?reference={REFERENCE_ENTITY_UUID}&polymorphic=true&direction=out]</code>
 
| Prepared Query || GET || <code>/access/query/{RESOURCE_TYPE_NAME}/{RELATION_TYPE_NAME}/{ENTITY_TYPE_NAME}[?reference={REFERENCE_ENTITY_UUID}&polymorphic=true&direction=out]</code>
 
|-
 
|-
| Query || GET || <code>/access/query?q={QUERY}</code>
+
| Raw Query || GET || <code>/access/query?q={QUERY}</code>
 
|-  
 
|-  
 
| JSON Query || POST || <code>/access/query</code>  
 
| JSON Query || POST || <code>/access/query</code>  
Line 101: Line 122:
  
 
==== Prepared Query via Java client ====
 
==== Prepared Query via Java client ====
 +
 +
'''Signature'''
  
 
<source lang="java">
 
<source lang="java">
Line 417: Line 440:
  
 
=== Raw Query ===
 
=== Raw Query ===
 +
 +
'''DISCLAMER'''
 +
This API must be used for development purposes only because the way to represent the [[Facet_Based_Resource_Model#IS_Model|IS Model]] concepts can change at any time or can change the database persistence.
  
 
This API provides a way to query the underlying database persistence by using the persistence query language dialect.  
 
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 [[Facet_Based_Resource_Model#IS_Model|IS Model]] concepts.
+
The result of this API does not guarantee consistency with the [[Facet_Based_Resource_Model#IS_Model|IS Model]] concepts.
 
The result is related to how the service decide to represent the [[Facet_Based_Resource_Model#IS_Model|IS Model]] concepts on the persistence data model.
 
The result is related to how the service decide to represent the [[Facet_Based_Resource_Model#IS_Model|IS Model]] concepts on the persistence data model.
  
 
At the time of writing the underlying database, persistence is [http://orientdb.com/docs/last/ OrientDB].
 
At the time of writing the underlying database, persistence is [http://orientdb.com/docs/last/ OrientDB].
It should be used only for development purposes only because the way to represent the [[Facet_Based_Resource_Model#IS_Model|IS Model]] concepts can change at any time or can change the database persistence.
 
 
 
At the time of writing the query language supported is [http://orientdb.com/docs/3.0.x/sql/SQL-Introduction.html OrientDB SQL Dialect].
 
At the time of writing the query language supported is [http://orientdb.com/docs/3.0.x/sql/SQL-Introduction.html OrientDB SQL Dialect].
  
 
==== Raw Query via Java Client ====
 
==== Raw Query via Java Client ====
 +
 +
'''Signature'''
  
 
<source lang="java">
 
<source lang="java">
public String query(final String query, final int limit, final String fetchPlan) throws InvalidQueryException, ResourceRegistryException;
+
public String rawQuery(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;
+
public String rawQuery(final String query, final int limit, final String fetchPlan, boolean raw) throws InvalidQueryException, ResourceRegistryException;
 
</source>
 
</source>
  
Line 444: Line 470:
 
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
  
String jsonString = resourceRegistryClient.query("SELECT FROM SoftwareFacet", 1, null, true);
+
String jsonString = resourceRegistryClient.rawQuery("SELECT FROM SoftwareFacet", 1, null, true);
 
</source>
 
</source>
  
Line 456: Line 482:
 
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
  
String jsonString = resourceRegistryClient.query("SELECT FROM SoftwareFacet", 1, null);
+
String jsonString = resourceRegistryClient.rawQuery("SELECT FROM SoftwareFacet", 1, null);
 
List<SoftwareFacet> list = ElementMapper.unmarshalList(SoftwareFacet.class, jsonString);
 
List<SoftwareFacet> list = ElementMapper.unmarshalList(SoftwareFacet.class, jsonString);
 
</source>
 
</source>
Line 490: Line 516:
 
     {
 
     {
 
         "@class": "SoftwareFacet",
 
         "@class": "SoftwareFacet",
        "name": "WhnManager",
 
        "description": "Web Hosting Node Service",
 
 
         "header": {
 
         "header": {
 
             "@class": "Header",
 
             "@class": "Header",
Line 500: Line 524:
 
             "lastUpdateTime": "2021-07-01 12:35:26.274 +0200"
 
             "lastUpdateTime": "2021-07-01 12:35:26.274 +0200"
 
         },
 
         },
 +
        "group": "VREManagement",
 +
        "version": "2.0.0-4.15.0-132431",
 +
        "name": "WhnManager",
 +
        "description": "Web Hosting Node Service",
 
         "optional": false,
 
         "optional": false,
 
         "_allow": [
 
         "_allow": [
Line 514: Line 542:
 
             "#4:14"
 
             "#4:14"
 
         ],
 
         ],
        "version": "2.0.0-4.15.0-132431",
+
 
 
         "in_IsIdentifiedBy": [
 
         "in_IsIdentifiedBy": [
 
             "#839:0"
 
             "#839:0"
         ],
+
         ]
        "group": "VREManagement"
+
 
     }
 
     }
 
]
 
]
 
</source>
 
</source>
  
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.
+
As you can see the response contains a lot of database-specific information and others are missing, e.g., ''@superClasses'' proeprty. You cannot use or rely on them to interact with the resource registry service.
  
 
===== Raw Query via REST API  Example 2 =====
 
===== Raw Query via REST API  Example 2 =====
Line 540: Line 567:
 
[
 
[
 
     {
 
     {
         "name": "WhnManager",
+
         "@class": "SoftwareFacet",
         "description": "Web Hosting Node Service",
+
         "@superClasses": ["Facet"],
 
         "header": {
 
         "header": {
 
             "@class": "Header",
 
             "@class": "Header",
Line 550: Line 577:
 
             "lastUpdateTime": "2021-07-01 12:35:26.274 +0200"
 
             "lastUpdateTime": "2021-07-01 12:35:26.274 +0200"
 
         },
 
         },
        "optional": "false",
 
        "version": "2.0.0-4.15.0-132431",
 
 
         "group": "VREManagement",
 
         "group": "VREManagement",
         "@class": "SoftwareFacet",
+
         "name": "WhnManager",
         "@superClasses": [
+
         "version": "2.0.0-4.15.0-132431",
            "Facet"
+
        "description": "Web Hosting Node Service",
         ]
+
         "optional": "false"
 
     }
 
     }
 
]
 
]
 
</source>
 
</source>
 
  
 
=== JSON Query ===
 
=== JSON Query ===
 +
 +
==== How to create a 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.
 
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 ====
+
To help the reader to understand the JSON query it will be used the following graph instances.
 +
 
 +
[[File:Example-for-json-query.png]]
  
Let's imagine you want to get the '''EService''' representing the '''down''' instances of the service identified as '''DataTransfer:data-transfer-service'''.
+
The following is the representation of the ''EService'' instance for the '''DataTransfer''' service running on '''pc-frosini.isti.cnr.it''' ''HostingNode''.
 +
It will be the result of all the presented examples [[#JSON Query for Resources | JSON Query for Resources]].
  
 
<source lang="JavaScript">
 
<source lang="JavaScript">
 
{
 
{
 
"@class": "EService",
 
"@class": "EService",
 +
"@superClasses": [ "Service", "GCubeResource", "Resource" ],
 +
"header": {
 +
"@class": "Header",
 +
"creationTime": "2021-08-25 14:33:16.280 +0200",
 +
"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
 +
"uuid": "0255b7ec-e3da-4071-b456-9a2907ece1db",
 +
"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
 +
"lastUpdateTime": "2021-08-25 15:41:23.091 +0200"
 +
},
 
"consistsOf": [
 
"consistsOf": [
 
{
 
{
 
"@class": "IsIdentifiedBy",
 
"@class": "IsIdentifiedBy",
 +
"@superClasses": [ "ConsistsOf" ],
 +
"header": { ... },
 +
"propagationConstraint": {
 +
"@class": "PropagationConstraint",
 +
"add": "propagate",
 +
"remove": "cascade"
 +
},
 
"target": {
 
"target": {
 
"@class": "SoftwareFacet",
 
"@class": "SoftwareFacet",
 +
"@superClasses": [ "Facet" ],
 +
"header": {
 +
"@class": "Header",
 +
"creationTime": "2021-08-25 14:33:16.250 +0200",
 +
"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
 +
"uuid": "c1f13895-f3a5-4b49-b459-15fd5bbe07d6",
 +
"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
 +
"lastUpdateTime": "2021-08-25 15:41:23.042 +0200"
 +
},
 +
"group": "DataTransfer",
 
"name": "data-transfer-service",
 
"name": "data-transfer-service",
"group": "DataTransfer"
+
"version": "2.0.0-SNAPSHOT",
 +
"description": "Data Tansfer Service",
 +
"optional": "false"
 
}
 
}
}
+
},
 
{
 
{
 
"@class": "ConsistsOf",
 
"@class": "ConsistsOf",
 +
"@superClasses": [],
 +
"header": { ... },
 +
"propagationConstraint": { ... },
 +
"target": {
 +
"@class": "AccessPointFacet",
 +
"@superClasses": [ "Facet" ],
 +
"header": { ... },
 +
"endpoint": "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/resource",
 +
"entryName": "data-transfer-service-remote-management",
 +
"authorization": {
 +
"@class": "ValueSchema",
 +
"schema": null,
 +
"value": "gcube-token"
 +
}
 +
}
 +
},
 +
{
 +
"@class": "ConsistsOf",
 +
"@superClasses": [],
 +
"header": { ... },
 +
"propagationConstraint": { ... },
 +
"target": {
 +
"@class": "AccessPointFacet",
 +
"@superClasses": [ "Facet" ],
 +
"header": { ... },
 +
"endpoint": "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service",
 +
"entryName": "org.gcube.data.transfer.service.DTService",
 +
"authorization": { ... }
 +
}
 +
},
 +
{
 +
"@class": "ConsistsOf",
 +
"@superClasses": [],
 +
"header": { ... },
 +
"propagationConstraint": { ... },
 
"target": {
 
"target": {
 
"@class": "StateFacet",
 
"@class": "StateFacet",
"value": "down"
+
"@superClasses": [ "Facet" ]
 +
"header": {
 +
"@class": "Header",
 +
"uuid": "bc303636-f85f-4ea1-9d85-7188acb4cac2",
 +
"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
 +
"creationTime": "2021-08-25 14:33:16.269 +0200",
 +
"lastUpdateTime": "2021-08-25 15:46:18.682 +0200",
 +
"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080"
 +
},
 +
"value": "down",
 +
 
 
}
 
}
 
},
 
},
+
{
 +
"@class": "ConsistsOf",
 +
"@superClasses": [],
 +
"header": { ... },
 +
"propagationConstraint": { ... },
 +
"target": {
 +
"@class": "EventFacet",
 +
"@superClasses": [ "Facet" ]
 +
"header": { ... },
 +
"event": "started",
 +
"date": "2021-08-25 15:41:22.760 +0200"
 +
}
 +
},
 +
{
 +
"@class": "ConsistsOf",
 +
"@superClasses": [],
 +
"header": { ... },
 +
"propagationConstraint": { ... },
 +
"target": {
 +
"@class": "EventFacet",
 +
"@superClasses": [ "Facet" ]
 +
"header": { ... },
 +
"event": "ready",
 +
"date": "2021-08-25 15:41:23.587 +0200"
 +
}
 +
},
 +
{
 +
 
 +
"@class": "ConsistsOf",
 +
"@superClasses": [],
 +
"header": { ... },
 +
"propagationConstraint": { ... },
 +
"target": {
 +
"@class": "EventFacet",
 +
"@superClasses": [ "Facet" ]
 +
"header": { ... },
 +
"event": "down",
 +
"date": "2021-08-25 15:46:18.743 +0200"
 +
}
 +
}
 
]
 
]
 
}
 
}
 
</source>
 
</source>
  
As you can notice the JSON query has exactly the same shape of each instance of the result.
 
  
 +
===== Query for Resources =====
  
Even more complex queries are really simple:
+
Let's imagine you want to get the '''EService''' representing the service identified as 'group'':'''DataTransfer''' (the serviceClass in the OLD gCore IS Model) and 'name'': '''data-transfer-service''' (the serviceName in the OLD gCore IS Model) which state is '''down'''.
  
 
<source lang="JavaScript">
 
<source lang="JavaScript">
Line 603: Line 744:
 
"@class": "EService",
 
"@class": "EService",
 
"consistsOf": [
 
"consistsOf": [
 +
{
 +
"@class": "IsIdentifiedBy",
 +
"target": {
 +
"@class": "SoftwareFacet",
 +
"group": "DataTransfer",
 +
"name": "data-transfer-service"
 +
}
 +
}
 
{
 
{
 
"@class": "ConsistsOf",
 
"@class": "ConsistsOf",
"propagationConstraint" : {
 
"add": "propagate"
 
},
 
 
"target": {
 
"target": {
 
"@class": "StateFacet",
 
"@class": "StateFacet",
Line 613: Line 759:
 
}
 
}
 
},
 
},
 +
 +
]
 +
}
 +
</source>
 +
 +
As you can notice the JSON query has exactly the same shape as the EService instance presented above.
 +
 +
 +
Even more complex queries are really simple:
 +
 +
<source lang="JavaScript">
 +
{
 +
"@class": "EService",
 +
"consistsOf": [
 
{
 
{
 
"@class": "IsIdentifiedBy",
 
"@class": "IsIdentifiedBy",
 
"target": {
 
"target": {
 
"@class": "SoftwareFacet",
 
"@class": "SoftwareFacet",
"name": "data-transfer-service",
 
 
"group": "DataTransfer"
 
"group": "DataTransfer"
 +
"name": "data-transfer-service"
 +
}
 +
},
 +
{
 +
"@class": "ConsistsOf",
 +
"propagationConstraint" : {
 +
"add": "propagate"
 +
},
 +
"target": {
 +
"@class": "StateFacet",
 +
"value": "down"
 
}
 
}
 
}
 
}
Line 642: Line 812:
 
</source>
 
</source>
  
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.
+
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'''.
+
Moreover, the requested ''EService'' is activated by (''Activates'') an ''HostingNode'' with a CPU (''CPUFacet'') from the ''vendor'' known as '''GenuineIntel'''.
  
==== JSON Query for Facet ====
+
===== JSON Query for Facet =====
  
 
The following query returns the StateFacet of any EService identified as '''DataTransfer:data-transfer-service'''.
 
The following query returns the StateFacet of any EService identified as '''DataTransfer:data-transfer-service'''.
Line 661: Line 831:
 
"target": {
 
"target": {
 
"@class": "SoftwareFacet",
 
"@class": "SoftwareFacet",
"name": "data-transfer-service",
 
 
"group": "DataTransfer"
 
"group": "DataTransfer"
 +
"name": "data-transfer-service"
 
}
 
}
 
}
 
}
Line 681: Line 851:
 
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.
 
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 ====
+
The obtained result will be.
 +
 
 +
<source lang="JavaScript">
 +
{
 +
"@class": "StateFacet",
 +
"@superClasses": [ "Facet" ]
 +
"header": {
 +
"@class": "Header",
 +
"uuid": "bc303636-f85f-4ea1-9d85-7188acb4cac2",
 +
"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
 +
"creationTime": "2021-08-25 14:33:16.269 +0200",
 +
"lastUpdateTime": "2021-08-25 15:46:18.682 +0200",
 +
"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080"
 +
},
 +
"value": "down",
 +
}
 +
</source>
 +
 
 +
===== JSON Query Operators =====
 +
 
 +
====== JSON Query Conditional Operators ======
  
 
JSON queries support the following operators:
 
JSON queries support the following operators:
  
 
{| class="wikitable"
 
{| class="wikitable"
! Opertor || Description
+
! Comparison Operator || Description
 
|-
 
|-
 
|<code>$eq</code> || Matches values that are equal to a specified value.
 
|<code>$eq</code> || Matches values that are equal to a specified value.
Line 702: Line 892:
 
|<code>$in</code> || Matches any of the values specified in an array.
 
|<code>$in</code> || Matches any of the values specified in an array.
 
|}
 
|}
 +
 +
====== JSON Query Logical Operators ======
 +
 +
{| class="wikitable"
 +
! Logical Operator || Description
 +
|-
 +
|<code>$and</code> || true if both the conditions are true.
 +
|-
 +
|<code>$or</code> || true if at least one of the condition is true.
 +
|-
 +
|<code>$not</code> || true if the condition is false.
 +
|}
 +
 +
====== JSON Query Operators Usage Example ======
  
 
The following JSON query shows an example of the usage of the query operators:
 
The following JSON query shows an example of the usage of the query operators:
Line 729: Line 933:
 
}
 
}
 
</source>
 
</source>
 +
 +
The query returns the StateFacet with ''value'' to '''down''' of any EService which has
 +
* ''uuid''='''0255b7ec-e3da-4071-b456-9a2907ece1db''' AND ''createdBy''='''DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080'''
 +
OR
 +
* ''uuid''='''aec0ef31-c735-4a4c-b2f4-57dfbd2fe925''' AND ''createdBy''!='''luca.frosini'''
 +
 +
 +
 +
One of the obtained ''StateFacet'' in the result will be:
 +
 +
 +
<source lang="JavaScript">
 +
{
 +
"@class": "StateFacet",
 +
"@superClasses": [ "Facet" ]
 +
"header": {
 +
"@class": "Header",
 +
"uuid": "bc303636-f85f-4ea1-9d85-7188acb4cac2",
 +
"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
 +
"creationTime": "2021-08-25 14:33:16.269 +0200",
 +
"lastUpdateTime": "2021-08-25 15:46:18.682 +0200",
 +
"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080"
 +
},
 +
"value": "down",
 +
}
 +
</source>
 +
 +
 +
==== JSON Query via Java Client ====
 +
 +
'''Signature'''
 +
 +
<source lang="java">
 +
public String jsonQuery(final String query) throws InvalidQueryException, ResourceRegistryException;
 +
 +
public <E extends Entity> List<E> jsonQuery(final JsonNode jsonNode) throws InvalidQueryException, ResourceRegistryException;
 +
</source>
 +
 +
===== JSON Query via Java Client Example =====
 +
 +
<source lang="java">
 +
 +
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 +
 +
String jsonQuery = "{\n"
 +
+ " \"@class\": \"EService\",\n"
 +
+ " \"consistsOf\": [\n"
 +
+ " {\n"
 +
+ " \"@class\": \"IsIdentifiedBy\",\n"
 +
+ " \"target\": {\n"
 +
+ " \"@class\": \"SoftwareFacet\",\n"
 +
+ " \"group\": \"DataTransfer\",\n"
 +
+ " \"name\": \"data-transfer-service\"\n"
 +
+ " }\n"
 +
+ " }\n"
 +
+ " {\n"
 +
+ " \"@class\": \"ConsistsOf\",\n"
 +
+ " \"target\": {\n"
 +
+ " \"@class\": \"StateFacet\",\n"
 +
+ " \"value\": \"down\"\n"
 +
+ " }\n"
 +
+ " },\n"
 +
+ " \n"
 +
+ " ]\n"
 +
+ "}";
 +
 +
String jsonString = resourceRegistryClient.jsonQuery(jsonQuery);
 +
List<EService> list = ElementMapper.unmarshalList(EService.class, jsonString);
 +
</source>
 +
 +
==== JSON Query via REST API ====
 +
 +
'''Request URL'''
 +
 +
<pre>POST /access/query</pre>
 +
 +
'''Request Body'''
 +
<source lang="JavaScript">
 +
{
 +
"@class": "EService",
 +
"consistsOf": [
 +
{
 +
"@class": "IsIdentifiedBy",
 +
"target": {
 +
"@class": "SoftwareFacet",
 +
"group": "DataTransfer",
 +
"name": "data-transfer-service"
 +
}
 +
}
 +
{
 +
"@class": "ConsistsOf",
 +
"target": {
 +
"@class": "StateFacet",
 +
"value": "down"
 +
}
 +
},
 +
 +
]
 +
}
 +
</source

Latest revision as of 14:37, 9 February 2022

Contents

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.

  • Access To Contexts:
    • List Contexts: it allows enumerating the contexts;
    • Exist Context: it allows checking if a context exists.
    • Read Context: it allows reading a context.
  • Access To Types:
    • Exist Type: it allows checking a type exists.
    • Read Type: it allows reading a type. This API also allows listing type and its subtypes by indicating the query parameter polymorphic=true.
  • Access To Instances :
    • List Instances: it allows listing instances of a specific type;
    • Exist Instance: it allows checking if an instance exists in a specific context;
    • Read Instace: it allows getting the representation of the requested instance in a specific context;
    • Get Instance Contexts: it allows getting the list of contexts an instance belongs to.
  • Access To Query Templates:
    • List Query Templates: it allows listing query templates;
    • Exist Query Template: it allows checking if a specific query template exists;
    • Read Query Template: it allows reading a specific query template;
    • Run Query Template: it allows to run a query template by providing the template variable values.
  • Query:
    • Prepared Query: it allows querying the graph in respect to the model;
    • Raw Query: it allows querying the raw graph used to represent the model in the backend;
    • JSON Query: it allows querying the raw graph in respect to the model using a JSON representation of the query.


This page will not present the APIs already available in the dedicated collection. Please check the dedicated page. The reason to expose the safe method already available in the dedicated collection is security reasons.

Query & Access Collection

Operation HTTP Method URL
Access To Contexts
List Contexts GET /access/contexts
Exist Context HEAD /access/contexts/{UUID}
Read Context GET /access/contexts/{UUID}
Access To Types
Exist Type HEAD /access/types/{TYPE_NAME}
Read Type GET /access/types/{TYPE_NAME}[?polymorphic=true]
Access To Instances
List Instances GET /access/instances/{TYPE_NAME}[?polymorphic=true]
Exist Instance HEAD /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
Exist Query Template HEAD /access/query-templates/{QUERY_TEMPLATE_NAME}
Read Query Template GET /access/query-templates/{QUERY_TEMPLATE_NAME}
Run Query Template POST /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]
Raw 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

Signature

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

DISCLAMER This API must be used for development purposes only because the way to represent the IS Model concepts can change at any time or can change the database persistence.

This API provides a way to query the underlying database persistence by using the persistence query language dialect. The result of 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. At the time of writing the query language supported is OrientDB SQL Dialect.

Raw Query via Java Client

Signature

public String rawQuery(final String query, final int limit, final String fetchPlan) throws InvalidQueryException, ResourceRegistryException;
 
public String rawQuery(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.rawQuery("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.rawQuery("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",
        "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"
        },
        "group": "VREManagement",
        "version": "2.0.0-4.15.0-132431",
        "name": "WhnManager",
        "description": "Web Hosting Node Service",
        "optional": false,
        "_allow": [
            "#4:15",
            "#4:13",
            "#4:11",
            "#4:9",
            "#5:12"
        ],
        "_allowRead": [
            "#4:12",
            "#4:10",
            "#4:16",
            "#4:14"
        ],
 
        "in_IsIdentifiedBy": [
            "#839:0"
        ]
    }
]

As you can see the response contains a lot of database-specific information and others are missing, e.g., @superClasses proeprty. 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

[
    {
        "@class": "SoftwareFacet",
        "@superClasses": ["Facet"],
        "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"
        },
        "group": "VREManagement",
        "name": "WhnManager",
        "version": "2.0.0-4.15.0-132431",
        "description": "Web Hosting Node Service",
        "optional": "false"
    }
]

JSON Query

How to create a 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.

To help the reader to understand the JSON query it will be used the following graph instances.

Example-for-json-query.png

The following is the representation of the EService instance for the DataTransfer service running on pc-frosini.isti.cnr.it HostingNode. It will be the result of all the presented examples JSON Query for Resources.

{
	"@class": "EService",
	"@superClasses": [ "Service", "GCubeResource", "Resource" ],
	"header": {
		"@class": "Header",
		"creationTime": "2021-08-25 14:33:16.280 +0200",
		"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
		"uuid": "0255b7ec-e3da-4071-b456-9a2907ece1db",
		"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
		"lastUpdateTime": "2021-08-25 15:41:23.091 +0200"
	},
	"consistsOf": [
		{
			"@class": "IsIdentifiedBy",
			"@superClasses": [ "ConsistsOf" ],
			"header": { ... },
			"propagationConstraint": {
				"@class": "PropagationConstraint",
				"add": "propagate",
				"remove": "cascade"
			},
			"target": {
				"@class": "SoftwareFacet",
				"@superClasses": [ "Facet" ],
				"header": {
					"@class": "Header",
					"creationTime": "2021-08-25 14:33:16.250 +0200",
					"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
					"uuid": "c1f13895-f3a5-4b49-b459-15fd5bbe07d6",
					"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
					"lastUpdateTime": "2021-08-25 15:41:23.042 +0200"
				},
				"group": "DataTransfer",
				"name": "data-transfer-service",
				"version": "2.0.0-SNAPSHOT",
				"description": "Data Tansfer Service",
				"optional": "false"
			}
		},
		{
			"@class": "ConsistsOf",
			"@superClasses": [],
			"header": { ... },
			"propagationConstraint": { ... },
			"target": {
				"@class": "AccessPointFacet",
				"@superClasses": [ "Facet" ],
				"header": { ... },
				"endpoint": "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/resource",
				"entryName": "data-transfer-service-remote-management",
				"authorization": {
					"@class": "ValueSchema",
					"schema": null,
					"value": "gcube-token"
				}
			}
		},
		{
			"@class": "ConsistsOf",
			"@superClasses": [],
			"header": { ... },
			"propagationConstraint": { ... },
			"target": {
				"@class": "AccessPointFacet",
				"@superClasses": [ "Facet" ],
				"header": { ... },
				"endpoint": "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service",
				"entryName": "org.gcube.data.transfer.service.DTService",
				"authorization": { ... }
			}
		},
		{
			"@class": "ConsistsOf",
			"@superClasses": [],
			"header": { ... },
			"propagationConstraint": { ... },
			"target": {
				"@class": "StateFacet",
				"@superClasses": [ "Facet" ]
				"header": {
					"@class": "Header",
					"uuid": "bc303636-f85f-4ea1-9d85-7188acb4cac2",
					"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
					"creationTime": "2021-08-25 14:33:16.269 +0200",
					"lastUpdateTime": "2021-08-25 15:46:18.682 +0200",
					"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080"
				},
				"value": "down",
 
			}
		},
		{
			"@class": "ConsistsOf",
			"@superClasses": [],
			"header": { ... },
			"propagationConstraint": { ... },
			"target": {
				"@class": "EventFacet",
				"@superClasses": [ "Facet" ]
				"header": { ... },
				"event": "started",
				"date": "2021-08-25 15:41:22.760 +0200"
			}
		},
		{
			"@class": "ConsistsOf",
			"@superClasses": [],
			"header": { ... },
			"propagationConstraint": { ... },
			"target": {
				"@class": "EventFacet",
				"@superClasses": [ "Facet" ]
				"header": { ... },
				"event": "ready",
				"date": "2021-08-25 15:41:23.587 +0200"
			}
		},
		{
 
			"@class": "ConsistsOf",
			"@superClasses": [],
			"header": { ... },
			"propagationConstraint": { ... },
			"target": {
				"@class": "EventFacet",
				"@superClasses": [ "Facet" ]
				"header": { ... },
				"event": "down",
				"date": "2021-08-25 15:46:18.743 +0200"
			}
		}
	]
}


Query for Resources

Let's imagine you want to get the EService representing the service identified as 'group:DataTransfer (the serviceClass in the OLD gCore IS Model) and 'name: data-transfer-service (the serviceName in the OLD gCore IS Model) which state is down.

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

As you can notice the JSON query has exactly the same shape as the EService instance presented above.


Even more complex queries are really simple:

{
	"@class": "EService",
	"consistsOf": [
		{
			"@class": "IsIdentifiedBy",
			"target": {
				"@class": "SoftwareFacet",
				"group": "DataTransfer"
				"name": "data-transfer-service"
			}
		},
		{
			"@class": "ConsistsOf",
			"propagationConstraint" : {
				"add": "propagate"
			},
			"target": {
				"@class": "StateFacet",
				"value": "down"
			}
		}
	],
	"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 is activated by (Activates) an HostingNode with a CPU (CPUFacet) 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",
						"group": "DataTransfer"
						"name": "data-transfer-service"
					}
				}
			]
		}
	}
}

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.

The obtained result will be.

{
	"@class": "StateFacet",
	"@superClasses": [ "Facet" ]
	"header": {
		"@class": "Header",
		"uuid": "bc303636-f85f-4ea1-9d85-7188acb4cac2",
		"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
		"creationTime": "2021-08-25 14:33:16.269 +0200",
		"lastUpdateTime": "2021-08-25 15:46:18.682 +0200",
		"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080"
	},
	"value": "down",
}
JSON Query Operators
JSON Query Conditional Operators

JSON queries support the following operators:

Comparison Operator Description
$eq Matches values that are equal to a specified value.
$gt Matches values that are greater than a specified value.
$gte Matches values that are greater than or equal to a specified value.
$lt Matches values that are less than a specified value.
$lte Matches values that are less than or equal to a specified value.
$ne Matches all values that are not equal to a specified value.
$in Matches any of the values specified in an array.
JSON Query Logical Operators
Logical Operator Description
$and true if both the conditions are true.
$or true if at least one of the condition is true.
$not true if the condition is false.
JSON Query Operators Usage Example

The following JSON query shows an example of the usage of the 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"
					}}
				]
			}
		}
	}
}

The query returns the StateFacet with value to down of any EService which has

  • uuid=0255b7ec-e3da-4071-b456-9a2907ece1db AND createdBy=DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080

OR

  • uuid=aec0ef31-c735-4a4c-b2f4-57dfbd2fe925 AND createdBy!=luca.frosini


One of the obtained StateFacet in the result will be:


{
	"@class": "StateFacet",
	"@superClasses": [ "Facet" ]
	"header": {
		"@class": "Header",
		"uuid": "bc303636-f85f-4ea1-9d85-7188acb4cac2",
		"createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080",
		"creationTime": "2021-08-25 14:33:16.269 +0200",
		"lastUpdateTime": "2021-08-25 15:46:18.682 +0200",
		"lastUpdateBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080"
	},
	"value": "down",
}


JSON Query via Java Client

Signature

public String jsonQuery(final String query) throws InvalidQueryException, ResourceRegistryException;
 
public <E extends Entity> List<E> jsonQuery(final JsonNode jsonNode) throws InvalidQueryException, ResourceRegistryException;
JSON Query via Java Client Example
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory.create();
 
String jsonQuery = "{\n"
	+ "	\"@class\": \"EService\",\n"
	+ "	\"consistsOf\": [\n"
	+ "		{\n"
	+ "			\"@class\": \"IsIdentifiedBy\",\n"
	+ "			\"target\": {\n"
	+ "				\"@class\": \"SoftwareFacet\",\n"
	+ "				\"group\": \"DataTransfer\",\n"
	+ "				\"name\": \"data-transfer-service\"\n"
	+ "			}\n"
	+ "		}\n"
	+ "		{\n"
	+ "			\"@class\": \"ConsistsOf\",\n"
	+ "			\"target\": {\n"
	+ "				\"@class\": \"StateFacet\",\n"
	+ "				\"value\": \"down\"\n"
	+ "			}\n"
	+ "		},\n"
	+ " \n"
	+ "	]\n"
	+ "}";
 
String jsonString = resourceRegistryClient.jsonQuery(jsonQuery);
List<EService> list = ElementMapper.unmarshalList(EService.class, jsonString);

JSON Query via REST API

Request URL

POST /access/query

Request Body

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