Difference between revisions of "IS-Client"

From Gcube Wiki
Jump to: navigation, search
(How to get a query object)
(Queries)
 
(38 intermediate revisions by the same user not shown)
Line 1: Line 1:
[https://wiki.gcore.research-infrastructures.eu/gCube/index.php/Advanced_Topics#Interfacing_the_Information_System ISClient Interface] is an interface defined in the context of the gCore Framework to decouple gCube Services from the specific implementation of the [[Information System|Information Service]]. In conjunction with the [[IS-Publisher]] it represents the mediation layer gCube Services will rely on to interact with the [[Information System|Information Service]] as a whole. Such interfaces implement respectively the production/publishing (''[[IS-Publisher]]'') and the consumption/query (''[[IS-Client]]'').
+
== Role ==
  
==== Interface ====
+
The <code>ISClient</code> is set of interfaces, templates and abstract classes defined in the context of the gCore Framework to model the discovery of  resources belonging an infrastructureon the IS.
There are two main methods defined in the ISClient interface:
+
<code>ISClient</code> is also the name of the main interface for retrieving and sending queries.
  
* '''getQuery()''' – which takes as input parameter a message characterising the interface implementation to be used and instructing the framework to use it (by relying on the dynamic class loader mechanism);
+
A reference implementation of the ISClient is provided with the gHN distribution to interact with the concrete IS services (namely the [[IS-Collector|IS-InformationCollector]] service).
* '''execute()''' – which takes as input parameter a message containing a ''query'', a ''query scope'' and a ''context'' the requestor is operating in and returns the list of Information Service entries matching the query and the rest of constraints.
+
  
In addition to such functions the interface predefines the list of query typologies (a.k.a. templates) that must be implemented. Three classes of queries are envisaged:
+
== Design ==
 +
The entry point to the ISClient is the <code>ISClient</code> interface that defines the methods for obtain query objects and send them to the IS-InformationCollector instance in scope:  
  
* ''gCube Resources query'', i.e. a query template to identify gCube Resources by imposing constraints on their profiles. For each existing gCube Resource a query template of this type exists, e.g. there is a GCUBERIQuery for issuing queries on Running Instance Resources, GCUBEGHNQuery for issuing queries on gHN Resources;
+
* <code>getQuery(Class<QUERY> type)</code> – which takes as input parameter the type of the query;
* ''WS-Resource query'', i.e. a query template to identify properties exposed through WS-ResourceProperty;
+
* <code>getQuery(String name)</code> – which takes as input parameter the name of the query;  
* ''generic query'', i.e. a query template to execute custom queries on the entries stored in the Information Service.
+
* <code>execute(ISQuery<RESULT> query, GCUBEScope scope)</code> – which takes as input parameter the ''query'' and the ''scope'' and returns a list of RESULT matching the query.
  
 +
Queries cannot be instantiated with constructors as standard Java objects. They rather need to be obtained from the ISClient. A query object is an instance of a class implementing the <code>org.gcube.common.core.informationsystem.client.ISQuery</code> interface. Implementing classes declare also a type parameter <code>RESULT</code> indicating the type of the expected results. When the query is passed to the execute() method, instances of this type are returned.
  
=== Implementation Overview ===
+
Depending on the query, parameters and/or filters can be set to the query object to add further conditions.
  
The IS-Client component is a Java library implementing the <code>ISClient</code> interface defined in the gCore Framework. Therefore it can be plugged in a gCore distribution to interface the gCube Information System.
+
== Queries ==
This IS-Client implementation reduces possible range of queries (statically implemented), each of them has a template as more generic as possible. This has been thought for covering all the main cases, enabling the user to create dynamically the query as he/she likes better enriching the query with the parameters he/she needs. 
+
  
The following classes of queries can be executed against the IS's content:  
+
There are three types of queries:
* ''GCUBEResourceQuery'', to query the GCUBEResources' profiles
+
* ''WSResourceQuery'', to query WS-ResourceProperty documents
+
* ''GCUBEGenericQuery'', to make custom queries
+
  
All the queries defined in the ISClient Interface are implemented by the library.
+
* ''pre-defined'' (or template) queries (GCUBEResourceQuery or WSResourceQuery)
 +
* ''named'' queries
 +
* caller-defined queries (GCUBEGenericQuery)
  
Moreover, it is possible to define custom queries; for this, the component supports the XQuery dialect offered by the [http://exist.sourceforge.net/ eXist XML Database].
+
Each query is modeled by a class implementing the <code>org.gcube.common.core.informationsystem.client.ISQuery</code> interface. Query objects are not directly instantiated but must be obtained by the ISClient library. To get any of the query objects described in the following, the <code>getQuery()</code> method has to be invoked as follows:
  
==== How to get a query object ====
 
 
To get any of the query objects described in this section, the <code>getQuery</code> method has to be invoked on the ISClient implementation as follows:
 
 
<source lang="java">
 
<source lang="java">
 
  ISClient client = GHNContext.getImplementation(ISClient.class);
 
  ISClient client = GHNContext.getImplementation(ISClient.class);
  [GCUBE...Query] query = client.getQuery([GCUBE...Query].class);     
+
  [GCUBE...Query] query = client.getQuery([GCUBE...Query].class | name);     
...
+
 
</source>
 
</source>
  
Once obtained the query object, the developer can add filters to target the query on his/her needs. The supported filters are:
+
=== Pre-defined Queries: Querying GCUBEResources ===
 +
 
 +
The following queries classes are available to query over [[Reference Model|gCube Resources]]:
 +
 
 +
* <code>GCUBECollectionQuery.class</code>
 +
* <code>GCUBECSInstanceQuery.class</code>
 +
* <code>GCUBECSQuery.class</code>
 +
* <code>GCUBEExternalRIQuery.class</code>
 +
* <code>GCUBEGenericResourceQuery.class</code>
 +
* <code>GCUBEGHNQuery.class</code>
 +
* <code>GCUBEMCollectionQuery.class</code>
 +
* <code>GCUBERIQuery.class</code> ( with the implicit filters that the returned RIs are in the ''ready'' state)
 +
* <code>GCUBEServiceQuery.class</code>
 +
* <code>GCUBETPQuery.class</code>
 +
* <code>GCUBEVREQuery.class</code>
 +
 
 +
All of them return a <code>List</code> of specialized <code>org.gcube.common.core.resources.GCUBEResource</code> objects (e.g. <code>GCUBEServiceQuery</code> returns a list of <code>GCUBEService</code> objects).
 +
 
 +
Once obtained the desired query object, the developer can add filters to better target the query on his needs.  
 +
 
 +
Supported filters are:
 
* ''AtomicCondition''
 
* ''AtomicCondition''
 
** with the atomic conditions can be specified that a node with a determined path *MUST* have a specified value
 
** with the atomic conditions can be specified that a node with a determined path *MUST* have a specified value
 
<source lang="java">
 
<source lang="java">
  ...  new AtomicCondition("//Endpoint/@EntryName","gcube/annotationmanagement/abe/factory")
+
  query.addAtomicConditions(new AtomicCondition("//Endpoint/@EntryName","gcube/annotationmanagement/abe/factory"));
 
</source>
 
</source>
  
Line 48: Line 63:
  
 
<source lang="java">
 
<source lang="java">
   ....addGenericCondition("$result/[path] eq '[something]' or $result/[another path] eq '[something else]'");
+
   query.addGenericCondition("$result/[path] eq '[something]' or $result/[another path] eq '[something else]'");
 
</source>
 
</source>
  
==== How to query over GCUBEResource profiles ====
+
===== Sample Usage =====
Queries over GCUBE Resources:
+
  
*GCUBECollectionQuery
+
1) The following query retrieves all the HostingNode registered in the selected scope:
*GCUBECSInstanceQuery
+
*GCUBECSQuery
+
*GCUBEExternalRIQuery
+
*GCUBEGenericResourceQuery
+
*GCUBEGHNQuery
+
*GCUBEMCollectionQuery
+
*GCUBERIQuery (Return all RI with state equals to ready)
+
*GCUBEServiceQuery
+
*GCUBETPQuery
+
*GCUBEVREQuery
+
  
Any if these queries returns a <code>List</code> of specialized GCUBE Resources.
+
<source lang="java">
 
+
ISClient client = GHNContext.getImplementation(ISClient.class);
===== Usage Examples =====
+
GCUBEGHNQuery GHNquery = client.getQuery(GCUBEGHNQuery.class);
 +
for (GCUBEHostingNode node : client.execute(GHNquery,GCUBEScope.getScope("/gcube/devsec")))
 +
  logger.debug(node.getID()+"("+node.getNodeDescription().getName()+")");
 +
</source>
  
The following query retrieves all the RunningInstances of the Service with ServiceName equals to "ABE" in the selected scope:
+
2) The following query retrieves all the RunningInstances of the Service with ServiceName equals to "ABE" in the selected scope:
  
 
<source lang="java">
 
<source lang="java">
Line 82: Line 89:
 
</source>
 
</source>
  
 
+
3) The following query retrieves all the RunningInstances of the Service with ServiceName equals to "GHNManager" or "SoftwareRepository":  
The following query retrieves all the HostingNode registered in the selected scope:
+
 
+
<source lang="java">
+
ISClient client = GHNContext.getImplementation(ISClient.class);
+
GCUBEGHNQuery GHNquery = client.getQuery(GCUBEGHNQuery.class);
+
for (GCUBEHostingNode node : client.execute(GHNquery,GCUBEScope.getScope("/gcube/devsec")))
+
  logger.debug(node.getID()+"("+node.getNodeDescription().getName()+")");
+
</source>
+
 
+
 
+
The following query retrieves all the RunningInstances of the Service with ServiceName "GHNManager" or "SoftwareRepository":  
+
  
 
<source lang="java">
 
<source lang="java">
Line 103: Line 99:
 
</source>
 
</source>
  
==== How to query over resource property documents ====
+
=== Pre-defined Queries: Querying WS-ResourceProperties Documents ===
 +
 
 
To query over GCUBEWSResources the following query class must be used:
 
To query over GCUBEWSResources the following query class must be used:
 +
<source lang="java">
 +
ISClient client = GHNContext.getImplementation(ISClient.class);
 +
WSResourceQuery query = client.getQuery(WSResourceQuery.class);   
 +
</source>
 +
 +
As for [[IS-Client#Pre-defined_Queries:_Querying_GCUBEResources|GCUBEResourceQuery]], also WSResourceQuery objects can be further refined with <code>AtomicCondition</code> and <code>GenericCondition</code> to better target the query.
  
* WSResourceQuery
+
Once executed, the query returns a <code>List</code> of <code>RPDocument</code> objects matching the query conditions. The RPDocument exposes the following getter methods for retrieving a set of common information about the resource:
 +
* <code>getEndpoint()</code>, returning the source WS-Resource endpoint
 +
* <code>getKey()</code>, returning the source WS-Resource key
 +
* <code>getServiceID()</code>, returning the identifier of the service of the WS-Resource
 +
* <code>getServiceName()</code>, returning the name of the service of origin of the WS-Resource
 +
* <code>getServiceClass()</code>, returning the class of the service of origin of the WS-Resource
 +
* <code>getRIID()</code>, returning the identifier of the running instance of origin of the WS-Resource
 +
* <code>getGHNID()</code>, returning the identifier of the gHN of origin of the WS-Resource
 +
* <code>getScope()</code>, returning the scope(s) of the WS-Resource
 +
* <code>getTerminationTime()</code>, returning the termination time of the WS-ResourceProperties document
  
The query returns a List of <code>RPDocument</code> object. The RPDocuments allows developer to retrieve information on WSResourceProperties or to execute XPath over its content.   
+
Typically, a caller has also to access the values of the Resource Properties inside the document and this can be done by invoking the evaluate() method of the RPDocument object. This method accepts and executes an XPath expression on the WS-ResourceProperties document encapsulated inside the RPDocument.   
  
===== Usage Example =====
+
==== Sample Usage ====
  
The following example returns all the WSResources generated by the services with ServiceClass "Sample":
+
The following example returns all the WSResources generated by the services with ServiceClass equals to "Sample":
  
 
<source lang="java">
 
<source lang="java">
Line 118: Line 130:
 
WSResourceQuery wsquery = client.getQuery(WSResourceQuery.class);
 
WSResourceQuery wsquery = client.getQuery(WSResourceQuery.class);
 
wsquery.addAtomicConditions(new AtomicCondition("//gc:ServiceClass","Samples"));
 
wsquery.addAtomicConditions(new AtomicCondition("//gc:ServiceClass","Samples"));
for (RPDocument d : client.execute(wsquery,GCUBEScope.getScope("/gcube/devsec")))  
+
for (RPDocument d : client.execute(wsquery, GCUBEScope.getScope("/gcube/devsec"))) {
     logger.debug(d.getEndpoint()+":+d.getVO()+":"d.evaluate(\"//MyRP\").get(0));
+
     logger.info("Source EPR: " + d.getEndpoint();
 +
    logger.info("MyRP value:" + d.evaluate(\"//MyRP\").get(0));
 +
}
 
</source>
 
</source>
  
==== Custom queries ====
+
As showed in this example, the query internally defines a ''gc'' namespace for the [[IS-Publisher#Published_Structure_of_an_instance_state|RPs]] added by the IS-Publisher that can be used to create filters on them.
 
+
The library also offers the possibility to execute custom queries: ''GCUBEGenericQuery''.
+
GCUBEGenericQuery allows the developer to set the query expression to execute and to use a predefined set of queries which he should set some parameters on listed below:
+
 
+
*GCUBEResourceQuery:
+
** TYPE
+
** FILTER
+
** RESULT (the default value returns Ids)
+
*GCUBEWSResourceQuery:
+
** FILTER
+
** RESULT (the default value is the entire  Properties Document Data)
+
*RIEndpoint:
+
** NAME (Service name)
+
** CLASS (Service class)
+
** ENTRY (the entry point)
+
*RIOnGHN:
+
** ID (the GHN id)
+
*RISpecificData:
+
** NAME (Service name)
+
** CLASS (Service class)
+
** ENTRY (the entry point)
+
*GHNIDFromHostName:
+
** NAME (GHN name)
+
** RESULT (the default value returns Ids)
+
*InternalCollections
+
*InternalCollectionIDs
+
*UserCollectionIDsFromSchemaURI
+
** URI (the schema uri)
+
*MCollectionIDForCollection
+
** ID (related collection ID)
+
*MCollectionFormatsForCollection
+
** ID (related collection ID)
+
*MCollectionIDFromCollectionIDAndRole
+
** ID (related collection ID)
+
** ROLE (secondary role)
+
*MCollectionIDFromMFLanguage
+
** LANGUAGE (metadata format language)
+
*MCollectionIDFromName
+
** NAME (metadata collection name)
+
*MCollectionIDFromSchemaURI
+
** URI (schema uri)
+
  
 +
=== Named queries ===
  
This class of queries returns a List of XMLResult. The XMLResult object allows the developer to explore the contained document with XPaths.
+
Named queries are widely used queries that are distributed with the ISClient to easy the caller's life. They are identified by a ''name'' and from the implementation point of view they are GCUBEGenericQuery instances with an already injected query expression.
  
To get a predefined generic query:
+
To get a named query:
 
<source lang="java">
 
<source lang="java">
...
 
 
  GCUBEGenericQuery query = client.getQuery("[one of the listed queries]");     
 
  GCUBEGenericQuery query = client.getQuery("[one of the listed queries]");     
...
 
 
</source>
 
</source>
  
to set the parameters:
+
Depending on the query, it is also possible to customize the query by setting specific parameters.  To set a parameters:
 
<source lang="java">
 
<source lang="java">
...
+
query.addParameters(new QueryParameter("NAME","VALUE"));  
query.addParameters(new QueryParameter("[parameter to set]","[value]"), new QueryParameter("[parameter to set]","[value ...]"));
+
...
+
 
</source>
 
</source>
  
===== Usage Example =====
 
  
The first two examples show how to retrieve the IDs of all the profiles stored on the Information System:  
+
The following queries are available with the current implementation of the ISClient:
  
<source lang="java">
+
* ''GCUBEResourceQuery'' allows to query all the gCube Resources
ISClient client = GHNContext.getImplementation(ISClient.class);
+
** parameters:
GCUBEScope scope = GCUBEScope.getScope("/gcube/devsec");
+
*** TYPE
GCUBEGenericQuery query = client.getQuery(GCUBEGenericQuery.class);
+
*** FILTER
query.setExpression("for $Profile in collection(\"/db/Profiles\")//Document/Data/child::*[local-name()='Profile']/Resource return $Profile/ID");
+
*** RESULT (the default value returns IDs)
List<XMLResult> result =client.execute(query, scope);
+
* ''GCUBEWSResourceQuery'' allows to query all the Resource Properties Documents
for (XMLResult resultItem :result ) {
+
** parameters:
  logger.debug(resultItem.evaluate("an XPath ... "));
+
*** FILTER
  logger.debug(resultItem.toString());
+
*** RESULT (the default value is the entire Properties Document Data)
}
+
* ''RIEndpoint'' looks for RI's endpoints
</source>
+
** parameters:
 +
*** NAME filters by the Service name
 +
*** CLASS filters by the Service class
 +
*** ENTRY filters by the entry point
 +
* ''RIOnGHN'' returns all the RIs grouped by the GHN on which they are hosted
 +
** parameters
 +
*** ID filters by the GHN id, i.e. returns the RIs hosted on that GHN
 +
* ''RISpecificData'':
 +
** parameters
 +
*** NAME (Service name)
 +
*** CLASS (Service class)
 +
*** ENTRY (the entry point)
 +
* ''GHNIDFromHostName'':
 +
** parameters
 +
*** NAME (GHN name)
 +
*** RESULT (the default value returns Ids)
 +
* ''InternalCollections''
 +
* ''InternalCollectionIDs''
 +
* ''UserCollectionIDsFromSchemaURI''
 +
** parameters
 +
*** URI (the schema uri)
 +
* ''MCollectionIDForCollection''
 +
** parameters
 +
*** ID (related collection ID)
 +
* ''MCollectionFormatsForCollection''
 +
** parameters
 +
*** ID (related collection ID)
 +
* ''MCollectionIDFromCollectionIDAndRole''
 +
** parameters
 +
*** ID (related collection ID)
 +
*** ROLE (secondary role)
 +
* ''MCollectionIDFromMFLanguage''
 +
** parameters
 +
*** LANGUAGE (metadata format language)
 +
* ''MCollectionIDFromName''
 +
** parameters
 +
*** NAME (metadata collection name)
 +
* ''MCollectionIDFromSchemaURI''
 +
** parameters
 +
*** URI (schema uri)
 +
 
 +
All the queries above return a List of <code>XMLResult</code>. Each XMLResult object allows the caller to explore the resource by invoking the <code>evaluate()</code> method and passing an XPath expression.
 +
 
 +
==== Sample Usage ====
 +
 
 +
The following example shows how to retrieve all the gCube Resources in scope:
  
 
<source lang="java">
 
<source lang="java">
 
ISClient client = GHNContext.getImplementation(ISClient.class);
 
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEScope scope = GCUBEScope.getScope("/gcube/devsec");
+
GCUBEScope scope = ...;
 
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
 
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
 
for (XMLResult result : client.execute(query,scope))  
 
for (XMLResult result : client.execute(query,scope))  
   logger.debug(result.evaluate("/ID/text()"));//displays a singleton list
+
   logger.debug(result.evaluate("/ID/text()"));//get the resource ID
 
</source>
 
</source>
  
 +
This example that shows how to filter the previous query by using the TYPE parameter defined in the query object:
  
This example represents how to retrieve Profiles IDs for all RunningInstances:
 
 
<source lang="java">
 
<source lang="java">
 
ISClient client = GHNContext.getImplementation(ISClient.class);
 
ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEScope scope = GCUBEScope.getScope("/gcube/devsec");
+
GCUBEScope scope = ...;
 
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
 
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
query.addParameters(new QueryParameter("TYPE",GCUBERunningInstance.TYPE));  
+
query.addParameters(new QueryParameter("TYPE", GCUBERunningInstance.TYPE)); //only RunningInstances
 
for (XMLResult result : client.execute(query,scope))  
 
for (XMLResult result : client.execute(query,scope))  
       logger.debug(result.evaluate("/Type/text()"));
+
       logger.debug(result.evaluate("/ID/text()"));  
 
</source>
 
</source>
  
 
+
Finally, a more complete example showing how to filter the same query and customize the results:  
This example describes how to retrieve profiles' Description for all the <code>RunningInstances</code> profiles instance of services with ServiceClass equals to "Annotation":
+
  
 
<source lang="java">
 
<source lang="java">
Line 225: Line 238:
 
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
 
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
 
//introduce a filter (NB. parameters can be added in batches)  
 
//introduce a filter (NB. parameters can be added in batches)  
query.addParameters(new QueryParameter("TYPE",GCUBERunningInstance.TYPE), //ovverride previous setting
+
query.addParameters(new QueryParameter("TYPE", GCUBERunningInstance.TYPE), //override previous setting
     new QueryParameter("FILTER","$result/Profile/ServiceClass/string() eq 'Annotation'"),
+
     new QueryParameter("FILTER","$result/Profile/ServiceClass/string() eq 'Annotation'"), //we want only Annotation RIs
     new QueryParameter ("RESULT", "$result/Profile/Description")); //any Xquery condition on $result would do
+
     new QueryParameter ("RESULT", "$result/Profile/Description")); //we get only the Description element
 
for (XMLResult result : client.execute(query,scope))  
 
for (XMLResult result : client.execute(query,scope))  
 
     logger.debug(result.evaluate("//Description")); //displays a singleton list
 
     logger.debug(result.evaluate("//Description")); //displays a singleton list
Line 233: Line 246:
 
</source>
 
</source>
  
 +
=== Caller-defined queries ===
 +
 +
The library also offers the possibility to execute custom queries by loading a ''GCUBEGenericQuery'' object and then set the whole query expression as follows
 +
 +
<source lang="java">
 +
ISClient client =  GHNContext.getImplementation(ISClient.class);
 +
GCUBEGenericQuery query = client.getQuery(GCUBEGenericQuery.class);
 +
query.setExpression("myqueryexpression");
 +
</source>
 +
 +
Custom queries can be over gCube Resource as well as WS-ResourceProperties documents. However, in order to successfully create them, the client has to be aware of the how the [[IS-Collector#XML_Indexing|XML database organization]] on the IS-InformationCollector in order to target the proper collection or sub-collection of resources.
 +
Moreover, these queries can be used to retrieve [[IS-Collector#Adding_an_XML_document|generic XML Documents]].
 +
 +
==== Sample Usage ====
 +
The following example show how to retrieve the IDs of all the profiles stored on the Information System with a custom query:
 +
 +
<source lang="java">
 +
ISClient client = GHNContext.getImplementation(ISClient.class);
 +
GCUBEScope scope = GCUBEScope.getScope("/gcube/devsec");
 +
GCUBEGenericQuery query = client.getQuery(GCUBEGenericQuery.class);
 +
query.setExpression("for $Profile in collection(\"/db/Profiles\")//Document/Data/child::*[local-name()='Profile']/Resource return $Profile/ID");
 +
List<XMLResult> result =client.execute(query, scope);
 +
for (XMLResult resultItem :result ) {
 +
  logger.debug(resultItem.evaluate("an XPath ... "));
 +
  logger.debug(resultItem.toString());
 +
}
 +
</source>
 +
  
 
[[Category:Information System]]
 
[[Category:Information System]]

Latest revision as of 14:56, 14 April 2011

Role

The ISClient is set of interfaces, templates and abstract classes defined in the context of the gCore Framework to model the discovery of resources belonging an infrastructureon the IS. ISClient is also the name of the main interface for retrieving and sending queries.

A reference implementation of the ISClient is provided with the gHN distribution to interact with the concrete IS services (namely the IS-InformationCollector service).

Design

The entry point to the ISClient is the ISClient interface that defines the methods for obtain query objects and send them to the IS-InformationCollector instance in scope:

  • getQuery(Class<QUERY> type) – which takes as input parameter the type of the query;
  • getQuery(String name) – which takes as input parameter the name of the query;
  • execute(ISQuery<RESULT> query, GCUBEScope scope) – which takes as input parameter the query and the scope and returns a list of RESULT matching the query.

Queries cannot be instantiated with constructors as standard Java objects. They rather need to be obtained from the ISClient. A query object is an instance of a class implementing the org.gcube.common.core.informationsystem.client.ISQuery interface. Implementing classes declare also a type parameter RESULT indicating the type of the expected results. When the query is passed to the execute() method, instances of this type are returned.

Depending on the query, parameters and/or filters can be set to the query object to add further conditions.

Queries

There are three types of queries:

  • pre-defined (or template) queries (GCUBEResourceQuery or WSResourceQuery)
  • named queries
  • caller-defined queries (GCUBEGenericQuery)

Each query is modeled by a class implementing the org.gcube.common.core.informationsystem.client.ISQuery interface. Query objects are not directly instantiated but must be obtained by the ISClient library. To get any of the query objects described in the following, the getQuery() method has to be invoked as follows:

 ISClient client = GHNContext.getImplementation(ISClient.class);
 [GCUBE...Query] query = client.getQuery([GCUBE...Query].class | name);

Pre-defined Queries: Querying GCUBEResources

The following queries classes are available to query over gCube Resources:

  • GCUBECollectionQuery.class
  • GCUBECSInstanceQuery.class
  • GCUBECSQuery.class
  • GCUBEExternalRIQuery.class
  • GCUBEGenericResourceQuery.class
  • GCUBEGHNQuery.class
  • GCUBEMCollectionQuery.class
  • GCUBERIQuery.class ( with the implicit filters that the returned RIs are in the ready state)
  • GCUBEServiceQuery.class
  • GCUBETPQuery.class
  • GCUBEVREQuery.class

All of them return a List of specialized org.gcube.common.core.resources.GCUBEResource objects (e.g. GCUBEServiceQuery returns a list of GCUBEService objects).

Once obtained the desired query object, the developer can add filters to better target the query on his needs.

Supported filters are:

  • AtomicCondition
    • with the atomic conditions can be specified that a node with a determined path *MUST* have a specified value
 query.addAtomicConditions(new AtomicCondition("//Endpoint/@EntryName","gcube/annotationmanagement/abe/factory"));
  • GenericCondition
    • with the generic conditions can be specified an entire condition expression (using $result as starting node of every used path)
  query.addGenericCondition("$result/[path] eq '[something]' or $result/[another path] eq '[something else]'");
Sample Usage

1) The following query retrieves all the HostingNode registered in the selected scope:

ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEGHNQuery GHNquery = client.getQuery(GCUBEGHNQuery.class);
for (GCUBEHostingNode node : client.execute(GHNquery,GCUBEScope.getScope("/gcube/devsec")))
   logger.debug(node.getID()+"("+node.getNodeDescription().getName()+")");

2) The following query retrieves all the RunningInstances of the Service with ServiceName equals to "ABE" in the selected scope:

ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBERIQuery RIquery = client.getQuery(GCUBERIQuery.class);
RIquery.addAtomicConditions(new AtomicCondition("//ServiceName","ABE"));
for (GCUBERunningInstance instance : client.execute(RIquery,GCUBEScope.getScope("/gcube/devsec")))
   logger.debug(instance.getServiceName()+"("+instance.getID()+")");

3) The following query retrieves all the RunningInstances of the Service with ServiceName equals to "GHNManager" or "SoftwareRepository":

ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBERIQuery RIquery = client.getQuery(GCUBERIQuery.class);
RIquery.addGenericCondition("$result/Profile/ServiceName/string() eq 'GHNManager' or $result/Profile/ServiceName/string() eq 'SoftwareRepository'");
for (GCUBERunningInstance instance : client.execute(RIquery,GCUBEScope.getScope("/gcube/devsec")))
    logger.debug(instance.getServiceName()+"("+instance.getID()+")");

Pre-defined Queries: Querying WS-ResourceProperties Documents

To query over GCUBEWSResources the following query class must be used:

 ISClient client = GHNContext.getImplementation(ISClient.class);
 WSResourceQuery query = client.getQuery(WSResourceQuery.class);

As for GCUBEResourceQuery, also WSResourceQuery objects can be further refined with AtomicCondition and GenericCondition to better target the query.

Once executed, the query returns a List of RPDocument objects matching the query conditions. The RPDocument exposes the following getter methods for retrieving a set of common information about the resource:

  • getEndpoint(), returning the source WS-Resource endpoint
  • getKey(), returning the source WS-Resource key
  • getServiceID(), returning the identifier of the service of the WS-Resource
  • getServiceName(), returning the name of the service of origin of the WS-Resource
  • getServiceClass(), returning the class of the service of origin of the WS-Resource
  • getRIID(), returning the identifier of the running instance of origin of the WS-Resource
  • getGHNID(), returning the identifier of the gHN of origin of the WS-Resource
  • getScope(), returning the scope(s) of the WS-Resource
  • getTerminationTime(), returning the termination time of the WS-ResourceProperties document

Typically, a caller has also to access the values of the Resource Properties inside the document and this can be done by invoking the evaluate() method of the RPDocument object. This method accepts and executes an XPath expression on the WS-ResourceProperties document encapsulated inside the RPDocument.

Sample Usage

The following example returns all the WSResources generated by the services with ServiceClass equals to "Sample":

ISClient client = GHNContext.getImplementation(ISClient.class);
WSResourceQuery wsquery = client.getQuery(WSResourceQuery.class);
wsquery.addAtomicConditions(new AtomicCondition("//gc:ServiceClass","Samples"));
for (RPDocument d : client.execute(wsquery, GCUBEScope.getScope("/gcube/devsec"))) {
    logger.info("Source EPR: " + d.getEndpoint();
    logger.info("MyRP value:" + d.evaluate(\"//MyRP\").get(0));
}

As showed in this example, the query internally defines a gc namespace for the RPs added by the IS-Publisher that can be used to create filters on them.

Named queries

Named queries are widely used queries that are distributed with the ISClient to easy the caller's life. They are identified by a name and from the implementation point of view they are GCUBEGenericQuery instances with an already injected query expression.

To get a named query:

 GCUBEGenericQuery query = client.getQuery("[one of the listed queries]");

Depending on the query, it is also possible to customize the query by setting specific parameters. To set a parameters:

query.addParameters(new QueryParameter("NAME","VALUE"));


The following queries are available with the current implementation of the ISClient:

  • GCUBEResourceQuery allows to query all the gCube Resources
    • parameters:
      • TYPE
      • FILTER
      • RESULT (the default value returns IDs)
  • GCUBEWSResourceQuery allows to query all the Resource Properties Documents
    • parameters:
      • FILTER
      • RESULT (the default value is the entire Properties Document Data)
  • RIEndpoint looks for RI's endpoints
    • parameters:
      • NAME filters by the Service name
      • CLASS filters by the Service class
      • ENTRY filters by the entry point
  • RIOnGHN returns all the RIs grouped by the GHN on which they are hosted
    • parameters
      • ID filters by the GHN id, i.e. returns the RIs hosted on that GHN
  • RISpecificData:
    • parameters
      • NAME (Service name)
      • CLASS (Service class)
      • ENTRY (the entry point)
  • GHNIDFromHostName:
    • parameters
      • NAME (GHN name)
      • RESULT (the default value returns Ids)
  • InternalCollections
  • InternalCollectionIDs
  • UserCollectionIDsFromSchemaURI
    • parameters
      • URI (the schema uri)
  • MCollectionIDForCollection
    • parameters
      • ID (related collection ID)
  • MCollectionFormatsForCollection
    • parameters
      • ID (related collection ID)
  • MCollectionIDFromCollectionIDAndRole
    • parameters
      • ID (related collection ID)
      • ROLE (secondary role)
  • MCollectionIDFromMFLanguage
    • parameters
      • LANGUAGE (metadata format language)
  • MCollectionIDFromName
    • parameters
      • NAME (metadata collection name)
  • MCollectionIDFromSchemaURI
    • parameters
      • URI (schema uri)

All the queries above return a List of XMLResult. Each XMLResult object allows the caller to explore the resource by invoking the evaluate() method and passing an XPath expression.

Sample Usage

The following example shows how to retrieve all the gCube Resources in scope:

ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEScope scope = ...;
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
for (XMLResult result : client.execute(query,scope)) 
   logger.debug(result.evaluate("/ID/text()"));//get the resource ID

This example that shows how to filter the previous query by using the TYPE parameter defined in the query object:

ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEScope scope = ...;
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
query.addParameters(new QueryParameter("TYPE", GCUBERunningInstance.TYPE)); //only RunningInstances
for (XMLResult result : client.execute(query,scope)) 
      logger.debug(result.evaluate("/ID/text()"));

Finally, a more complete example showing how to filter the same query and customize the results:

ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEScope scope = GCUBEScope.getScope("/gcube/devsec");
GCUBEGenericQuery query = client.getQuery("GCUBEResourceQuery");
//introduce a filter (NB. parameters can be added in batches) 
query.addParameters(new QueryParameter("TYPE", GCUBERunningInstance.TYPE), //override previous setting
     new QueryParameter("FILTER","$result/Profile/ServiceClass/string() eq 'Annotation'"), //we want only Annotation RIs
     new QueryParameter ("RESULT", "$result/Profile/Description")); //we get only the Description element
for (XMLResult result : client.execute(query,scope)) 
    logger.debug(result.evaluate("//Description")); //displays a singleton list

Caller-defined queries

The library also offers the possibility to execute custom queries by loading a GCUBEGenericQuery object and then set the whole query expression as follows

ISClient client =  GHNContext.getImplementation(ISClient.class);
GCUBEGenericQuery query = client.getQuery(GCUBEGenericQuery.class);
query.setExpression("myqueryexpression");

Custom queries can be over gCube Resource as well as WS-ResourceProperties documents. However, in order to successfully create them, the client has to be aware of the how the XML database organization on the IS-InformationCollector in order to target the proper collection or sub-collection of resources. Moreover, these queries can be used to retrieve generic XML Documents.

Sample Usage

The following example show how to retrieve the IDs of all the profiles stored on the Information System with a custom query:

ISClient client = GHNContext.getImplementation(ISClient.class);
GCUBEScope scope = GCUBEScope.getScope("/gcube/devsec");
GCUBEGenericQuery query = client.getQuery(GCUBEGenericQuery.class);
query.setExpression("for $Profile in collection(\"/db/Profiles\")//Document/Data/child::*[local-name()='Profile']/Resource return $Profile/ID");
List<XMLResult> result =client.execute(query, scope);
for (XMLResult resultItem :result ) {
   logger.debug(resultItem.evaluate("an XPath ... ")); 
   logger.debug(resultItem.toString());
}