Difference between revisions of "Application Support Layer"

From Gcube Wiki
Jump to: navigation, search
(Cacheing for Performance)
(ASL Extensions)
 
(131 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 +
<!-- CATEGORIES -->
 +
[[Category:Developer's Guide]]
 +
<!-- END CATEGORIES -->
 
== Introduction ==
 
== Introduction ==
The Application Support Layer (ASL) is a middleware between gCube Lower level Services and the gCube Presentation Layer. Its main goal is to provide a unified interface for accessing gCube and to allow application developers to deal only with how to render and present the corresponding functionality. Furthermore, ASL is responsible for covering all the application logic needed in order to fulfill users’ requirements. Since ASL aims at addressing a wide audience - not only gCube developers, it is designed to wrap gCube’s complexity by packing and interfacing standard procedures like retrieving service running instances from IS, attaching (or not) caller credential to stubs, and in general, to prepare the environment for a remote call. It should be mentioned that ASL consumers need no knowledge about where the services are running, whether a remote call is required in order to accomplish their goal, etc.  
+
The Application Support Layer (ASL) is a middleware between gCube Lower level Services and the gCube Presentation Layer. Its main goal is to provide a unified interface for accessing gCube and to allow application developers to deal only with how to render and present the corresponding functionality. Furthermore, ASL is responsible for covering all the application logic needed in order to fulfill users’ requirements. Since ASL aims at addressing a wide audience - not only gCube developers, it is designed to wrap gCube’s complexity by packing and interfacing standard procedures like retrieving service running instances from IS or accessing information the services or the IS holds.
In particular, ASL consists of ASL Core and ASL Extensions. ASL Core is the group of basic functionality on which developers can build their own extensions. It provides a session mechanism as well as easy ways to retrieve running instances and invoke services. It also deals with security and authentication. On the other hand, ASL Extensions are libraries that extend ASL in order to cover the usage of other (new / non core) services.  ASL Core functionality facilitates the development of these libraries. They aim to provide the GUI developer with a full package that will cover all the application logic so as to create the corresponding Graphical Interfaces. For each new functionality offered by gCube, a corresponding ASL Extension should be developed.
+
It should be mentioned that ASL users need no knowledge about where the services are running and how to access them in order to accomplish their goal.  
 +
In particular, ASL consists of ASL Core and ASL Extensions. ASL Core is the group of basic functionality on which developers can build their own extensions. It provides a session mechanism as well as easy ways to retrieve running instances and invoke services. It also deals with security and authentication. On the other hand, ASL Extensions are libraries that extend ASL Core in order to cover the usage of other (new / non core) services.  ASL Core functionality facilitates the development of these libraries. They aim to provide the GUI developer with a full package that will cover all the application logic so as to create the corresponding Graphical Interfaces. For each new functionality offered by gCube, a corresponding ASL Extension should be developed.
 
Offering both Java and HTTP APIs, ASL supports multiple ways to contact and interact with gCube lower level services. In essence, ASL acts as a gateway for other technologies to access gCube advanced facilities. This means that it receives all the requests to call gCube services and, acting as a proxy, it invokes the corresponding services.
 
Offering both Java and HTTP APIs, ASL supports multiple ways to contact and interact with gCube lower level services. In essence, ASL acts as a gateway for other technologies to access gCube advanced facilities. This means that it receives all the requests to call gCube services and, acting as a proxy, it invokes the corresponding services.
  
Line 18: Line 22:
 
The aforementioned objectives and design decisions are analyzed in the following sub-sections.  
 
The aforementioned objectives and design decisions are analyzed in the following sub-sections.  
  
[[Image:Asl internalNewer.jpg]]
+
[[Image:Drawing8.png]]
  
  
Line 26: Line 30:
 
=== ASL Core Functionality ===
 
=== ASL Core Functionality ===
 
----
 
----
ASL Core provides the fundamentals for building a gCube Graphical Application. It is the API that ASL consumers use in order to interact with gCube. It acts as a proxy that hides complexity of several steps needed for the invocations. It also contains the application logic for interpreting information received by gCube and transforming it into a presentable form. It also facilitates ASL extension developers by dealing with security issues and user credentials, scoped services calls, session management and retrieval of generic resources.
+
ASL Core provides the fundamentals for building a gCube Graphical Application. It is the API that ASL consumers use in order to interact with gCube. It acts as a proxy that hides complexity of several steps needed for the invocations. It also contains the application logic for interpreting information received by gCube and transforming it into a presentable form. It also facilitates ASL extension developers by dealing with security issues and user credentials, session management and retrieval of generic resources.
  
 
==== Session Management ====
 
==== Session Management ====
 
An important part of ASL Core is the session management. In order to consider ASL as a framework that completely supports users’ needs, it should implement its own mechanisms for providing sessions. Session is of crucial importance for the presentation layer since it provides means of storing information related to each user and means of intercommunication between application components. For this reason, a Session Manager has been implemented, based on the singleton design pattern. Its role is to administrate session objects, and to provide each user with his/her session. By using it, an application component can intercommunicate with another component by storing information in the session, and reading it from the other one. In fact, session is a hash map containing name – value pairs for various properties.
 
An important part of ASL Core is the session management. In order to consider ASL as a framework that completely supports users’ needs, it should implement its own mechanisms for providing sessions. Session is of crucial importance for the presentation layer since it provides means of storing information related to each user and means of intercommunication between application components. For this reason, a Session Manager has been implemented, based on the singleton design pattern. Its role is to administrate session objects, and to provide each user with his/her session. By using it, an application component can intercommunicate with another component by storing information in the session, and reading it from the other one. In fact, session is a hash map containing name – value pairs for various properties.
  
 +
==== Resources Retrieval from IS ====
 +
An functionality offered by the ASL Core, is the retrieval of Generic resources from the IS. It exposes an API to read and write GenericResource objects on the IS. Then, by using extensions the GenericResource content can even be parsed to extract it's information (i.e. the asl content extension offers such a functionality).
  
==== Security ====
+
 
Another significant aspect of ASL Core is security. The gCube system is based on PKI credentials in order to authenticate and authorize users. As a result, creating, retrieving and safely keeping proxy certificates is a central goal. ASL Core transparently retrieves user’s proxy credential and stores it in the session. Additionally, depending on the security type of the active VRE (secure or not), the ASL decides whether or not to attach user’s credential on the service’s stubs in order to make a secure call.
+
The ASL core component can be found at the following maven coordinates:
+
 
Furthermore, ASL Security provides a user authentication mechanism independent from specific applications and authentication providers. It uses a pluggable mechanism to specify “authentication modules” used for authenticating users to the applications interacting with it. In summary, ASL consumers don’t need to have any knowledge about how security is implemented in gCube, how to retrieve credentials, make secure calls to services, etc.
+
<source lang="xml">
 +
<groupId>org.gcube.applicationsupportlayer</groupId>
 +
<artifactId>aslcore</artifactId>
 +
<version>...</version>
 +
</source>
  
 
=== ASL Extensions ===
 
=== ASL Extensions ===
 
----
 
----
==== ASL User Profile Extension ====
 
ASL UserProfile Extension provides additional functionality for managing user profiles. Through this library, the user can access, update, create and remove a profile. In order to retrieve the needed information it contacts the UserProfileAccess service, the ProfileAdministration service and it gets the necessary resources from IS.  As a result, the presentation can be personalized based on information stored in user’s profile.
 
  
==== ASL Search Extension ====
+
==== ASL Content Extension ====
ASL Search Extension supports search functionality in order to query collections and retrieve the results. It contacts the SearchMaster and IS in order to retrieve information about the collections, joining the knowledge acquired from their dynamic and static configuration. Graphical User Interface can build the query step by step by first selecting the collections, then filling in the criteria, and finally submitting the query. Then the query is submitted to the SearchMaster in order to be executed. The results will be retrieved in pages either in a personalized html format or as plain metadata. Additionally, the user can navigate through results be requesting the previous, next or first page.
+
  
 +
ASL Content extension supports the management of Resources and Digital Objects which reside within the IS and hold information regarding all the available collections (data sources) and their linked data. It offers methods to extract information from IS objects, parse the content of gCube collection objects, modify the content and replace it on the IS.
  
==== ASL Content Management Extension ====
+
The ASL Content component can be found at the following maven coordinates:
Content is of crucial importance for a Virtual Research Environment. Users expect to search, discover, manage and present the available content. Thus, it is mandatory that a number of functionalities is being provided in order to access not only the raw content, but also its alternative forms. ASL Content Management extension provides functionality for managing the content. Through this library, a user can access the raw content, its alternative representations of which the most frequently requested is the thumbnail, as well as the corresponding metadata. In addition using this extension the user can also create a new digital object or update the content of an existing one. Furthermore, it provides functionality for managing collections.  Contacting the CMS service, this extension offers an interface for creating or deleting collections and adding or removing elements from them.
+
  
 +
<source lang="xml">
 +
<groupId>org.gcube.applicationsupportlayer</groupId>
 +
<artifactId>aslcontent</artifactId>
 +
<version>...</version>
 +
</source>
 +
 +
==== ASL Search Extension ====
 +
ASL Search Extension supports search functionality in order to query collections and retrieve the results. It contacts the SearchSystem Service and the ResourceRegistry in order to retrieve information about the collections and the available fields, joining the knowledge acquired from their dynamic and static configuration. Graphical User Interface can build the query step by step by first selecting the collections, then filling in the criteria, and finally submitting the query. Once the user's selections are made, a CQL Query is built from within the component, using the GCQLParser library. Then the query is submitted to the SearchMaster in order to be executed. The results will be retrieved in pages either in a personalized html format or as plain metadata (e.g. xml). Additionally, the user can navigate through results be requesting the previous, next or first page.
 +
 +
The ASL search extension can be found at the following maven coordinates:
 +
 +
<source lang="xml">
 +
<groupId>org.gcube.applicationsupportlayer</groupId>
 +
<artifactId>aslsearch</artifactId>
 +
<version>...</version>
 +
</source>
  
 
==== ASL VRE Management Extension ====
 
==== ASL VRE Management Extension ====
 
In order to manage a Virtual Research Environment, ASL VRE Management extension offers a rich API so as to administer the infrastructure. Part of the functionality provided is to create/ update/ delete a Generic Resource on IS, to query IS in order to retrieve information such as running instances, available GHNs, in addition to creating / updating a VRE, and dynamically deploying a service.
 
In order to manage a Virtual Research Environment, ASL VRE Management extension offers a rich API so as to administer the infrastructure. Part of the functionality provided is to create/ update/ delete a Generic Resource on IS, to query IS in order to retrieve information such as running instances, available GHNs, in addition to creating / updating a VRE, and dynamically deploying a service.
  
 +
==== ASL Social Extension ====
 +
gCube applications use a common library for exploiting the Social Data Sharing facilities. gCube Applications do not interact with the Social Library directly. Rather they exploit this ASL-Extension capability.  Please refer to the [http://gcube.wiki.gcube-system.org/gcube/index.php/Social_Networking_Library Social Networking Library] wiki page for more information about how to exploit it.
  
==== Home Library ====
+
==== ASL Access Logger Library ====
http://technical.wiki.d4science.research-infrastructures.eu/documentation/index.php/Home_Library
+
The Access Logger library provides methods in order to log the most common actions that are performed when using the D4Science portal.
 +
The actions that can be logged using the corresponding methods are:
 +
* The login to a VO/VRE
 +
* All types of search (Simple, Advanced and collection Browsing)
 +
* Content Retrieval
  
 +
For any other information the GenericLogger can be used to log any given message
 +
 +
Furthermore portlets can extend AccessLogger's interface and create their own specific entries that will be logged.
 +
 +
===== How to use the Access Logger =====
 +
 +
In order to use the AccessLogger first you need to create an instance of the AccessLogger object that is based on the Singleton resource pattern.
 +
 +
<source lang="java5">
 +
AccessLogger log = AccessLogger.getAccessLogger();
 +
</source>
 +
 +
Then depending on the action you would like to log you need to create an instance of the object that logs the desired action.<br>
 +
The sample code below shows how to log the login to a VO/VRE and a simple search query:
 +
 +
<source lang="java5">
 +
 +
LoginToVreAccessLogEntry loginEntry = new LoginToVreAccessLogEntry();
 +
/*
 +
* The first argument is the username of the user that performs the action
 +
* The second argument is the name of the working VO/VRE
 +
*/
 +
log.logEntry("testUsername", "ECOSYSTEM/TryIt", loginEntry);
 +
 +
String collections[][] = new String[2][2];
 +
collections[0][0] = "Earth images";
 +
collections[0][1] = "12345";
 +
collections[1][0] = "Landsat 7";
 +
collections[1][1] = "54321";
 +
SimpleSearchAccessLogEntry simpleEntry = new SimpleSearchAccessLogEntry(collections, "satellite, sea");
 +
/*
 +
* The first argument is the username of the user that performs the action
 +
* The second argument is the name of the working VO/VRE
 +
*/
 +
log.logEntry("testUsername", "ECOSYSTEM/TryIt", simpleEntry);
 +
 +
</source>
 +
 +
The other actions follow the same pattern.
 +
 +
 +
The logs are saved in the tmp/accessLogs directory. A logger file is created for every day following this pattern: accessLog"DATE".log
 +
 +
===== How to create your own entries by extending the Access Logger =====
 +
 +
The AccessLogger library can be used and extended by any component in order to log its own entries to the access log.
 +
 +
In order to create your own entry you should:
 +
* Create your own class that extends the <b>AccessLogEntry</b> class
 +
* The constructor of your class must invoke the super constructor and pass the name of your entry that represents the Type of the log (see the example below)
 +
* The <b>getLogMessage</b> should return the message that will be logged
 +
 +
<source lang="java5">
 +
public class ContentRetrievalLogEntry extends AccessLogEntry {
 +
 +
private String objectID;
 +
 +
private String objectName;
 +
 +
/**
 +
* Constructor
 +
*
 +
* @param objectID The ID of the object that is retrieved
 +
* @param objectName The name of the object that is retrieved
 +
*/
 +
public ContentRetrievalLogEntry(String objectID, String objectName) {
 +
super(EntryTypeConstants.RETRIEVE_CONTENT_ENTRY);
 +
 +
this.objectID = replaceReservedChars(objectID);
 +
this.objectName = replaceReservedChars(objectName);
 +
}
 +
 +
/**
 +
* @return The log message for a Content retrieval entry
 +
*/
 +
public String getLogMessage() {
 +
String message = "";
 +
message += TemplateConstants.CONTENT_ID + TemplateConstants.eqChar +
 +
this.objectID + TemplateConstants.separateCharacters + TemplateConstants.CONTENT_NAME + 
 +
TemplateConstants.eqChar + this.objectName;
 +
 +
return message;
 +
}
 +
 +
}
 +
</source>
 +
 +
* NOTE: The AccessLogEntry class provides the static method <b>replaceReservedChars</b> that should be invoked on the message to be logged so as to ensure that none of the reserved characters used by the logger will be part of the message
 +
 +
==== Home Library ====
 +
The [[Home Library]] manage and persist the users homes. More informations can be found [[Home Library|here]].
  
 
=== Caching for Performance ===
 
=== Caching for Performance ===
Line 62: Line 182:
 
Cache plays a main role within ASL. Its existence is considered essential in order to improve gCube’s performance and to give the impression to the end-user that the application layer is always ready to promptly respond to their requests. Therefore, a variety of resources that are frequently requested are cached in order to speed up response time. Depending on the type of the cached resource, different refresh and storage policies can be applied. In particular, one can configure the expiration time of the cached resources, the maximum number of these objects in memory, whether or not to support overflow on disk, the maximum size of objects on the disk, etc. Furthermore, examples of resources that are cached are:
 
Cache plays a main role within ASL. Its existence is considered essential in order to improve gCube’s performance and to give the impression to the end-user that the application layer is always ready to promptly respond to their requests. Therefore, a variety of resources that are frequently requested are cached in order to speed up response time. Depending on the type of the cached resource, different refresh and storage policies can be applied. In particular, one can configure the expiration time of the cached resources, the maximum number of these objects in memory, whether or not to support overflow on disk, the maximum size of objects on the disk, etc. Furthermore, examples of resources that are cached are:
  
• The available collections per VRE: ASL Content extension caches the names of the available collections in a hierarchical structure together with information about the available corresponding metadata, and the existence of any special kind of index, like full text, geospatial, or similarity index.
+
• The available collections per VRE: ASL Content extension caches the names of the available collections in a hierarchical structure together with information about the available languages, searchable fields, and the existence of any special kind of index, like full text, geospatial, or similarity index.
  
 
• Content information, it contains information about the digital objects, like their mime type, length, the existence of annotations over the object, the number of associated metadata, etc. This cache is implemented by ASL Content extension.
 
• Content information, it contains information about the digital objects, like their mime type, length, the existence of annotations over the object, the number of associated metadata, etc. This cache is implemented by ASL Content extension.
  
Generic Resources, it caches generic resources from IS since they are frequently requested and yet rarely modified. Examples of such resources are the metadata presentation xslts, the record presentation xslts, etc. This cache is placed in ASL Core, as the generic resources are frequently asked, their use is destinated for a large variety of reasons and they should be provided by the core unit of ASL.
+
Endpoint Resources for various service nodes (e.g. discovered search service endpoints). This cache is implemented by ASL Search extension.
  
Metadata, the metadata are stored in cache so as to be retrieved quickly. In many cases, the user requests to see the metadata of a digital object in a specific schema and then he/she requests this object’s metadata in another schema. So, if the alternative metadata exist in cache, the system responses immediately. This cache is also implemented by ASL Content extension.
+
Generic Resources, it caches generic resources from IS since they are frequently requested and yet rarely modified. Examples of such resources are the metadata presentation xslts, the record presentation xslts, etc. This cache is placed in ASL Core, as the generic resources are frequently asked, their use is destined for a large variety of reasons and they should be provided by the core unit of ASL.
  
 
• Profiles, user’s profile is used in many cases in order to personalize the layout based on user’s preferences. Thus, having a replica in main memory (or in the local disk) speeds up the procedure. This caching mechanism is placed inside ASL User Profile extension.
 
• Profiles, user’s profile is used in many cases in order to personalize the layout based on user’s preferences. Thus, having a replica in main memory (or in the local disk) speeds up the procedure. This caching mechanism is placed inside ASL User Profile extension.
 
• Searchable fields per metadata schema, for each metadata schema the VRE administrator can define a set of fields that the user can search. Typical examples of such fields are the title, the description, and the author. This cache is developed in ASL Search Extension.
 
 
• Thumbnails, they are typically used for presentation reasons when result records are presented. They are stored as alternative representations in Content Management System, and as a result, their retrieval is a big overhead. Therefore, keeping a copy locally improves application’s performance. The caching of the thumbnails is implemented inside ASL Content extension.
 
  
 
== Download ==
 
== Download ==
ASL jar can be found in the [https://grids16.eng.it/BuildReport/builds/recent%20builds/org.gcube.HEAD/index.html ETICS ] latest build.
+
ASL jars can be found in the [https://grids16.eng.it/BuildReport/browse/Recent_Builds ETICS ] latest build.
  
 
== How to use ASL ==
 
== How to use ASL ==
Line 100: Line 216:
 
By using ISInfo class, you can directly query the IS in order to retrieve information. <br>
 
By using ISInfo class, you can directly query the IS in order to retrieve information. <br>
 
Additionally, you can add / remove a GHN and a Running Instance to a specific scope, you can retrieve the profiles of the collections of a given scope, you can get the metadata-collections associated with a given collection as well as the indices associated with a collection or metadata collection.<br>
 
Additionally, you can add / remove a GHN and a Running Instance to a specific scope, you can retrieve the profiles of the collections of a given scope, you can get the metadata-collections associated with a given collection as well as the indices associated with a collection or metadata collection.<br>
 
Below you can see an example of how to query IS:
 
<source lang="java5">
 
String xquery = "";
 
xquery = "declare namespace is = 'http://gcube-system.org/namespaces/informationsystem/registry';"+
 
"for $Resource in collection(\"/db/Profiles\")//Document/Data/is:Profile/Resource" +
 
"where $Resource/ID/string() eq '" + resourceID +"'  return $Resource";
 
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
 
ISInfo is = new ISInfo(aslSession);
 
List<XMLResult> result = null;
 
String transformedXML = "";
 
result = is.queryDIS(xquery);
 
for (XMLResult res: result)
 
{
 
// Do something with the results!
 
}
 
</source>
 
 
Needed imports:
 
<source lang="java5">
 
import org.gcube.application.framework.api.ISInfo;
 
</source>
 
  
 
=== ASL Core - Managing Generic Resources ===
 
=== ASL Core - Managing Generic Resources ===
Line 182: Line 276:
 
</source>
 
</source>
  
 +
Additionally, ASL provides methods to retrieve from IS all tree collections and all Opensearch collections for the current scope.
 +
 +
<source lang="java5">
 +
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
 +
GenericResource gResources = new GenericResource(aslSession);
 +
//retrieve the Generic Resources of all Tree Collections from IS (hashmap of {collectionID,GenericResource})
 +
HashMap <String,org.gcube.common.resources.gcore.GenericResource> treeColGenResource = gResources.getAllTreeCollections(false);
 +
//retrieve the Generic Resources of all OpenSearch Collections from IS (hashmap of {collectionID,GenericResource})
 +
HashMap <String,org.gcube.common.resources.gcore.GenericResource> osColGenResource = gResources.getAllOpenSearchCollections(false);
 +
// retrieve the Cardinality of a Tree Resource (hashmap of {collectionID, cardinallity})
 +
HashMap<String, String> cardinalites = getTreeResourcesCardinalities();
 +
</source>
  
  
 
A sample generic resource:
 
A sample generic resource:
 
<source lang="xml">
 
<source lang="xml">
<?xml version="1.0" encoding="UTF-8"?>
+
 
<Resource>
+
<Resource version="0.4.x">
<ID/>
+
   
<Type>GenericResource</Type>
+
  <ID>666cc610-dab3-11df-9db7-e8211f3b1465</ID>
<Profile>
+
   
<Name/>
+
  <Type>GenericResource</Type>
<Description/>
+
   
<Body>
+
  <Scopes>
<DL geospatial="false" name="/gcube/devsec">
+
       
<collections name="Environment Documents" description="Environment Documents" shortname="docs">
+
      <Scope>/d4science.research-infrastructures.eu/Ecosystem/DRIVER</Scope>
<collection name="FAO test collection" description="FOA" reference="www.fao.org/documents/" shortname="faocdr"/>
+
   
</collections>
+
  </Scopes>
</DL>
+
   
</Body>
+
  <Profile>
</Profile>
+
       
 +
      <SecondaryType>GenericResource</SecondaryType>
 +
       
 +
      <Name>ScenarioCollectionInfo</Name>
 +
       
 +
      <Description>Available collection groups and collections</Description>
 +
       
 +
      <Body>
 +
           
 +
        <VRE name="/d4science.research-infrastructures.eu/Ecosystem/DRIVER">
 +
               
 +
            <collectionsGroup description="" id="ext-gen319" name="DRIVER" reference="">
 +
                   
 +
              <collection creationDate="04-02-2011 06:48:17" description="DRIVER Collection" id="4bc54b10-9661-11e0-b316-9c541a3a1781" name="DRIVER Collection" recno="-1" reference="" />
 +
               
 +
            </collectionsGroup>
 +
           
 +
        </VRE>
 +
       
 +
      </Body>
 +
   
 +
  </Profile>
 +
 
 
</Resource>
 
</Resource>
 +
 
</source>
 
</source>
  
Line 211: Line 340:
 
In order to retrieve the available collections regarding the active VRE, or to retrieve a search query, you have to use the SearchHelper class.
 
In order to retrieve the available collections regarding the active VRE, or to retrieve a search query, you have to use the SearchHelper class.
  
The collections are returned in a hierarchical way. An array of linked lists contains the collections that are organized as level 2 tree. Each list contains a group of collections that are logically packed together. The first element of the list is always the name of the group (together with the description of the group etc). The rest elements represent the actual collections.
+
The collections are returned in a hierarchical way. A HashMap contains the collections that are organized as level 2 tree. Each key of the map containes the id of a collection group that assembles collections logically packed together. The value of each key in the hash map is an array list with the collections belonging to that group.  
  
By using SearchHelper class you can also retrieve the available metadata schemata for querying collections in addition to the search fields that each of them offers. For each metadata schema, a list of the searchable fields is stored in a hasmap having as key the schema name.
+
By using SearchHelper class you can also retrieve the available languages supported by the collections in addition to the searchable and presentable fields that each of them offers. For each field offered by a collection, the languages, the presentable fields and the index capabilities are stored in the model of the internal architecture representing it.  
  
  
Line 223: Line 352:
 
SearchHelper searchH = new SearchHelper(aslSession);
 
SearchHelper searchH = new SearchHelper(aslSession);
 
// Retrieving the available collections:
 
// Retrieving the available collections:
List<CollectionInfo>[] colls = searchH.getAvailableCollections();
+
HashMap<org.gcube.application.framework.search.library.model.CollectionInfo, ArrayList<org.gcube.application.framework.search.library.model.CollectionInfo>> colls = searchH.getAvailableCollections();
 
if(colls != null)
 
if(colls != null)
 
{
 
{
for(int i=0; i<colls.length; i++)
+
for (org.gcube.application.framework.search.library.model.CollectionInfo key:collectionInfos.keySet()) {
{
+
ArrayList<org.gcube.application.framework.search.library.model.CollectionInfo> cols = collectionInfos.get(key);
System.out.println("+ " + colls[i].get(0).getName()); // group name
+
for (int i = 0; i < cols.size(); i++) {
for(int j=1; j< colls[i].size(); j++)
+
org.gcube.application.framework.search.library.model.CollectionInfo col = cols.get(i);
{
+
System.out.println("The collection id is: " + col.getId() + ", the collection name is: " + col.getName() " and the number of contained documents is: " + col.getRecNo());
    System.out.println("|-+ " + colls[i].get(j).getName()); // collection name
+
 
}
 
}
 
}
 
}
Line 251: Line 379:
 
Query queryObj = queryGroup.getQuery(DefaultQuery);  
 
Query queryObj = queryGroup.getQuery(DefaultQuery);  
  
 
// Retrieving the searchable fields for each schema:
 
HashMap<String, List<SearchField>> schemata = searchH.getSchemataInfo();
 
for(String schema: schemata.keySet())
 
{
 
List<SearchField> fields = schemata.get(schema);
 
System.out.println("++++++++++ Searchable fields for schema: " + schema + "++++++++++");
 
for(SearchField fld : fields)
 
{
 
System.out.println(fld.name);
 
}
 
}
 
  
  
Line 271: Line 387:
 
Needed imports:
 
Needed imports:
 
<source lang="java5">
 
<source lang="java5">
import org.gcube.application.framework.search.library.helper.SearchHelper;
+
import org.gcube.application.framework.search.library.impl.SearchHelper;
import org.gcube.application.framework.search.library.model.CollectionInfo;
+
org.gcube.application.framework.search.library.model.CollectionInfo
import org.gcube.application.framework.search.library.model.SearchField;
+
 
</source>
 
</source>
  
Line 303: Line 418:
 
/* Add / remove a new criterion to the query */
 
/* Add / remove a new criterion to the query */
  
queryObj.addCriterion(new Criterion(name,""));
+
queryObj.addCriterion(new Criterion(searchFieldId, searchFieldName, searchFieldValue));
 
queryObj.removeCriterion(searchFieldIntegerNo)
 
queryObj.removeCriterion(searchFieldIntegerNo)
  
Line 312: Line 427:
 
List<String>selectedCollections = queryObj.getSelectedRealCollections();
 
List<String>selectedCollections = queryObj.getSelectedRealCollections();
  
/* Get the selected schema (The schema name and language the user has selected */
 
SchemataInfos schemaInfo = queryObj.getSelectedSchemaInfos();
 
String selectedSchema[][] = new String[1][2];
 
selectedSchema[0][0] = schemaInfo.getName();
 
selectedSchema[0][1] = schemaInfo.getLanguage();
 
  
 
/* Get / set the current selected condition type */
 
/* Get / set the current selected condition type */
Line 322: Line 432:
 
Operator op = queryObj.getOperator();
 
Operator op = queryObj.getOperator();
  
 +
/* Get the Languages for the selected collections */
 +
List<String> languages = queryObj.getAvailableLanguages();
  
/* Get the fields for the selected collection and schema */
+
/* Get the fields for the selected collections */
 
List<SearchField> sFields = queryObj.getAvailableSearchFields();  // searchable fields
 
List<SearchField> sFields = queryObj.getAvailableSearchFields();  // searchable fields
 
List<String> browsableFields = queryObj.getAvailableBrowseFields(); // browsable fields
 
List<String> browsableFields = queryObj.getAvailableBrowseFields(); // browsable fields
Line 333: Line 445:
 
queryObj.updateCriterionName(internalNo, newName);  //update a criterion name
 
queryObj.updateCriterionName(internalNo, newName);  //update a criterion name
 
queryObj.updateCriterionValue(internalNo, newValue); //update a criterion value
 
queryObj.updateCriterionValue(internalNo, newValue); //update a criterion value
 +
queryObj.updateCriterionName(internalNo, newId); //update a criterion id
 +
 +
/* See available indexes */
 +
boolean hasFts = queryObj.isFTSAvailable();
 +
boolean hasGeo = queryObj.isGeoAvailable();
 +
 +
/* Get Query Description - in User friendly language */
 +
String qDescription = queryObj.getQueryDescription();
 +
 +
/* Get Query in CQL */
 +
String qCQL = queryObj.getQueryString();
  
 
</source>
 
</source>
Line 340: Line 463:
 
'''Submit a search Query'''
 
'''Submit a search Query'''
  
Three types of search can be performed through ASL: Simple Search, Advanced Search and Browsing of the collections. For each type of search there is a corresponding way for forming and sumbitting the query. In the examples below the three types of query submissions are displayed:
+
Four types of search can be performed through ASL: Simple Search, Generic Search, Advanced Search and Browsing of the collections. For each type of search there is a corresponding way for forming and submitting the query. In the examples below the three types of query submissions are displayed:
  
 
* Submit a Simple Query
 
* Submit a Simple Query
Line 356: Line 479:
 
int id = shelper.createQuery(shelper.getActiveQueryGroupNo());
 
int id = shelper.createQuery(shelper.getActiveQueryGroupNo());
 
shelper.setActiveQueryGroup(id);
 
shelper.setActiveQueryGroup(id);
 +
</source>
 +
 +
* Submit a Generic Search Query
 +
 +
<source lang="java5">
 +
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
 +
SearchHelper shelper = new SearchHelper(aslSession);
 +
Query q = new Query();
 +
q.setSemanticEnrichment(true); //if true, it returns all presentable fields. Otherwise, it returns only {title,snippet} fields.
 +
List<String> paramsList = new ArrayList<String> ();
 +
paramsList.add("fish"); //set the search term "fish"
 +
ResultSetConsumerI rs = q.genericSearch(aslSession, paramsList);
 +
/*
 +
  do something with the ResultSet consumer
 +
*/
 
</source>
 
</source>
  
Line 365: Line 503:
 
QueryGroup queryGroup = shelper.getActiveQueryGroup();
 
QueryGroup queryGroup = shelper.getActiveQueryGroup();
 
Query queryObj = queryGroup.getQuery(DefaultQuery);
 
Query queryObj = queryGroup.getQuery(DefaultQuery);
queryObj.setSortBy(sortby); //optional
 
queryObj.setOrder(Order.ASC); // or Order.DESC
 
 
 
 
session.setAttribute(SessionConstants.activePresentationQueryNo, new Integer(shelper.getActiveQueryGroupNo()));
 
session.setAttribute(SessionConstants.activePresentationQueryNo, new Integer(shelper.getActiveQueryGroupNo()));
Line 403: Line 539:
 
=== User Profile Extension - Manage User Profile ===
 
=== User Profile Extension - Manage User Profile ===
  
Through ASL you can create and retrieve the user profile. Using the ASL session you can store many of the user's preferences in order for them to be quickly retrieved. In the code bellow you can see some examples of how to get and read the user's profile.
+
Through ASL you can create and retrieve the user profile. Using the ASL session you can store many of the user's preferences in order for them to be quickly retrieved. In the code below you can see some examples of how to get and read the user's profile.
 +
Note that the library caches all UserProfiles, in order to reduce queries to the IS.
  
 
<source lang="java5">
 
<source lang="java5">
Line 410: Line 547:
  
 
// Invoke the createResource method. If there is no profile, it creates a new one for the user.
 
// Invoke the createResource method. If there is no profile, it creates a new one for the user.
 +
String username = "a.user";
 
userProfile.createUserProfile(username);
 
userProfile.createUserProfile(username);
 +
 +
//retrieve the userprofile
 +
userProfile.getUserProfile(username);
 +
 +
// set the profile payload
 +
String profile = "<profile>.....</profile>"; //this is the profile xml as a string
 +
userProfile.setUserProfile(username,profile);
 +
 +
// drop user profile
 +
userProfile.dropUserProfile(username);
 +
 +
//set a default profile on IS
 +
String profile = "<profile>.....</profile>"; //this is going to be set as a default profile on IS
 +
userProfile.setDefaultProfile(profile);
 +
 
</source>
 
</source>
  
Line 423: Line 576:
 
</source>
 
</source>
  
 +
The UserProfile extension of ASL provides also methods to retrieve information from the profile in a structured and organized way. For instance, the chosen metadata xslts or the selected presentation fields per collection can be retrieved in the following manner:
 +
 +
<source lang="java5">
 +
UserProfile userProf = new UserProfile(session);
 +
HashMap<String, ArrayList<String>> collectionsFields = userProf.getPresentationFields(session.getUsername());
 +
 +
HashMap<String, String> xsltNamesIds = userProf.getMetadataXSLTs(session.getUsername);
 +
</source>
  
 
=== Content Extension - Manage Collections and Digital Objects ===
 
=== Content Extension - Manage Collections and Digital Objects ===
  
Through the classes DigitalObject and Collection, ASL Content Management extension supports the retrieval or creation and storage of digital objects in CMS and collections in COLMS. Below you can see examples of usage of their methods:
+
Through the classes DigitalObject and Collection, ASL Content Management extension supports the retrieval or creation and storage of digital objects on the IS. Below you can see examples of usage of their methods:
  
 
<source lang="java5">
 
<source lang="java5">
Line 437: Line 598:
 
colId = Collection.createCollection(collectionName, aslSession, false);
 
colId = Collection.createCollection(collectionName, aslSession, false);
 
//do something with the colId
 
//do something with the colId
 +
 +
/* Get collection's members */
 +
Collection col = new Collection(aslSession, colId);
 +
String[] documents = col.getMemberIDs();
 +
 +
/* Add a document to a collection */
 +
DigitalOBject documentRepresentation = col.addMember(<InputStream with the content>, <String name>, <String mimeType>);
  
 
</source>
 
</source>
 +
  
  
Line 512: Line 681:
 
</source>
 
</source>
  
 
+
When you have created a DigitalObject you can get information about it (about its name, title, metadata, mime type, thumbnail, html representation) using the equivalent class methods.
When you have created a DigitalObject you can get information about it (about its name, title, schema, rank, available schemata, metadata, schema languages, mime type, primary roles, secondary roles, thumbnail, html representation) using the equivalent class methods. In the example below, you can see how you can retrieve the alternative representations for a digital object:
+
 
+
<source lang=java5>
+
HashMap<String, List<String>> primaryRoles = myDigitalObject.getPrimaryRoles();
+
List<String> alternatives = primaryRoles.get("contentmanagement:is-represented-by");
+
</source>
+
  
 
== How to consider an ASL Extension ==
 
== How to consider an ASL Extension ==
Line 524: Line 687:
  
 
===When is an ASL Extension needed===
 
===When is an ASL Extension needed===
ASL Extensions are libraries that extend ASL in order to cover usage of other (new/ non core) services. ASLCore functionality facilitates the development of these libraries by offering standard ways to deal with cache, security and session. The aim of building ASL extensions is to provide the GUI developer with a full package that will cover all the application logic so as to create the corresponding Graphical Interfaces.  
+
ASL Extensions are libraries that extend ASL in order to cover usage of other (new non-core) services. ASLCore functionality facilitates the development of these libraries by offering standard ways to deal with cache, security and session. The aim of building ASL extensions is to provide the GUI developer with a full package that will cover all the application logic so as to create the corresponding Graphical Interfaces.  
 
Practically, an ASL extension is needed when:
 
Practically, an ASL extension is needed when:
 
* A new functionality is added to gCube (e.g. a new service)
 
* A new functionality is added to gCube (e.g. a new service)
 
* The existing ASL Extensions do not cover the functionality requested by users.
 
* The existing ASL Extensions do not cover the functionality requested by users.
 
* Part of a functionality needs to be offered in an alternative way than the existing one (e.g. offer personalized results, http api, etc)
 
* Part of a functionality needs to be offered in an alternative way than the existing one (e.g. offer personalized results, http api, etc)
 
 
  
 
===Conventions===
 
===Conventions===
Line 556: Line 717:
 
* Offer simple interfaces. For example, if you want to retrieve the names of the existing collections, provide a method String[] getCollections()
 
* Offer simple interfaces. For example, if you want to retrieve the names of the existing collections, provide a method String[] getCollections()
 
* Use the functionality already offered by ASL core and the existing ASL extensions.
 
* Use the functionality already offered by ASL core and the existing ASL extensions.
* In order to get the RIs of a service, use the class RIsManager (package: org.gcube.application.framework.core.cache), like the example below:
 
  
<source lang=java5>
+
* Hide all the gCube complexity, like invoking a service, contacting IS, dealing with security, etc.
 
+
/* **** Retrieving RIs for a service **** */
+
EndpointReference[] modelerURIs;
+
ISCache cache = RIsManager.getInstance().getISCache(session.getScope());
+
modelerURIs = cache.getEPRsFor(“VREManagement”, “VREModeler”, SrvType.FACTORY.name());
+
</source>
+
 
+
 
+
* Hide all the gCube complexity, like invoking a service, contacting IS, dealing with security, etc. In the example below, you can see how you can make a remote call to a service:
+
 
+
<source lang=java5>
+
/* **** Preparing for a Remote Call **** */
+
ModelerFactoryPortType mFPType = null;
+
ModelerFactoryServiceAddressingLocator mFSLocator = new ModelerFactoryServiceAddressingLocator();
+
//retrieving randomly one of the available EPRs of VRE modeler service
+
serviceEPR = modelerURIs[new Random().nextInt(modelerURIs.length)];
+
//applying security (and setting scope etc) to the service port-type
+
mFPType = ServiceConextManager.applySecurity(mFSLocator.getModelerFactoryPortTypePort(serviceEPR), session);
+
// … make an actual call to VRE modeler service
+
</source>
+
 
+
Needed imports:
+
<source lang=java5>
+
org.gcube.application.framework.core.cache.RIsManager
+
org.gcube.commons.is.cache.ISCache
+
org.gcube.application.framework.core.security.ServiceContextManager
+
</source>
+
  
* If you need information about the user, the scope etc, you should add the D4ScienceSession as a parameter in the constructor (as a protected member of your class). For example, see the following constructor with a D4ScienceSession:
+
* If you need information about the user, the scope etc, you should add the ASLSession as a parameter in the constructor (as a protected member of your class). For example, see the following constructor with an ASLSession:
  
 
<source lang=java5>
 
<source lang=java5>
 
public class SearchHelper implements SearchInfoI {
 
public class SearchHelper implements SearchInfoI {
D4ScienceSession session;
+
ASLSession session;
Public SearchHelper(D4ScienceSession session) {
+
Public SearchHelper(ASLSession session) {
 
this.session = session;
 
this.session = session;
 
}
 
}
Line 619: Line 752:
 
org.gcube.application.framework.core.cache.CachesManager  
 
org.gcube.application.framework.core.cache.CachesManager  
 
</source>
 
</source>
 
== ASL JavaDocs ==
 
ASL Javadoc can be found in the ASL artifact on ETICS but also in the Distribution Site visiting the following links:
 
http://node1.p.d4science.research-infrastructures.eu:8888/maven/ApplicationSupportLayer/ASLCore/1/00/00/ASLCore/1.00.04/doc/api/index.html (stable release)
 
 
http://dlib05.isti.cnr.it/maven/ApplicationSupportLayer/ASLCore/1/00/00/ASLCore/1.00.04/doc/api/index.html (development release)
 
 
Check the latest build. [https://grids16.eng.it/BuildReport/builds/recent%20builds/org.gcube.HEAD/index.html here]
 
  
 
== ASL HTTP API ==
 
== ASL HTTP API ==
Line 636: Line 761:
 
• VO/VREs Functionality
 
• VO/VREs Functionality
  
• Content Functionality
+
• Content Retrieval Functionality
  
 
• Search Functionality
 
• Search Functionality
Line 650: Line 775:
 
With the basic authorization scheme, the Authorization header contains the string of "username:password" encoded in Base64. For example, the username of "webmaster" with the password "try2guess" is sent in an Authorization header with the value:  
 
With the basic authorization scheme, the Authorization header contains the string of "username:password" encoded in Base64. For example, the username of "webmaster" with the password "try2guess" is sent in an Authorization header with the value:  
  
<source lang="java5"> BASIC d2VibWFzdGVyOnRyeTJndWVTUw" </source>
+
<source lang="text"> BASIC d2VibWFzdGVyOnRyeTJndWVTUw" </source>
  
Here is an example of a URL for a login request: https://hostname/applicationSupportLayerHttp/LoginHandler
+
Here is an example of a URL for a login request: http://hostname:port/aslHttpInfrastructureLogin/Login
  
 
* Session Tracking
 
* Session Tracking
Line 658: Line 783:
  
 
An example of an XML response returning the session id is presented bellow:
 
An example of an XML response returning the session id is presented bellow:
<source lang="java5">  
+
<source lang="xml">  
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
 
     <SessionID>
 
     <SessionID>
 
         <jsessionid>6751BF9588491D6EB853096C84B3671F</jsessionid>
 
         <jsessionid>6751BF9588491D6EB853096C84B3671F</jsessionid>
 
     </SessionID>
 
     </SessionID>
 +
</source>
 +
 +
The login component can be found at the following maven coordinates:
 +
 +
<source lang="xml">
 +
<groupId>org.gcube.applicationsupportlayer</groupId>
 +
<artifactId>aslhttpinfrastructurelogin</artifactId>
 +
<version></version>
 +
<packaging>war</packaging>
 
</source>
 
</source>
  
Line 668: Line 802:
  
 
* Show Available VO/VREs
 
* Show Available VO/VREs
Once logged in, the user can see the VO/VREs to which he/she has access. To this end, the servlet reads from VOMS the groups for the user and then shows all the VREs the user can access and all the VOs to which the user has the role of VO-Admin or VRE-Manager or VRE-Designer or Production Support. In order to ask for the available VO/VREs, the client needs to make a GET request to the “ShowVREs” servlet of ASL HTTP API. An xml file, listing the information about the VO/VREs is sent as a response to the user.
+
Once logged in, the user can see the VO/VREs to which he/she has access. To this end, the servlet reads from VOMS the groups for the user and then shows all the VREs the user can access and all the VOs to which the user has the role of VO-Admin or VRE-Manager or VRE-Designer or Production Support. In order to ask for the available VO/VREs, the client needs to make a GET request to the “ShowVREs” servlet of ASL HTTP API. An xml file, listing the information about the VO/VREs is sent as a response to the user. If the client adds the parameter "details" set to true, he/she will get more information about each virtual environment.
** Parameters needed: '''none'''
+
** Parameters needed: '''details''' (optional)
**  URL request example: https://hostname/applicationSupportLayerHttp/ShowVREs;jsessionid=...
+
**  URL request example: http://hostname:port/aslHttpInfrastructureLogin/ListInfrastructureScopes;jsessionid=37D9E6D381C37777BA312B1242EEADD6
<source lang=java5>
+
 
An example of an XML response, listing the available VO/VREs is presented bellow:
 
An example of an XML response, listing the available VO/VREs is presented bellow:
<source lang=java5><?xml version="1.0" encoding="UTF-8"?>
+
<source lang=xml>
 +
<?xml version="1.0" encoding="UTF-8"?>
 
<VOs-VREs>
 
<VOs-VREs>
<VRE>/d4science.research-infrastructures.eu/EM/Demo</VRE>
+
    <VRE>/gcube/devNext/NextNext</VRE>
<VRE>/d4science.research-infrastructures.eu/FCPPS/Demo</VRE>
+
    <VRE>/gcube/devsec/devVRE</VRE>
<VO>/d4science.research-infrastructures.eu/EM</VO>
+
    <VRE>/d4science.research-infrastructures.eu/gCubeApps/iSearch</VRE>
 +
    <VO>/d4science.research-infrastructures.eu</VO>
 +
    <VO>/gcube/devNext</VO>
 +
    <VO>/gcube/devsec</VO>
 +
    <VO>/d4science.research-infrastructures.eu/gCubeApps</VO>
 +
    <VO>/gcube</VO>
 
</VOs-VREs>
 
</VOs-VREs>
 
</source>
 
</source>
Line 684: Line 823:
 
In order to be able to see the available content of a VO/VRE, a user needs to log into it. To that end, a servlet that logs the user to a virtual research environment is created. A GET method must be made by the client, passing as a value to a “scope” parameter, the name of the corresponding VO/VRE.
 
In order to be able to see the available content of a VO/VRE, a user needs to log into it. To that end, a servlet that logs the user to a virtual research environment is created. A GET method must be made by the client, passing as a value to a “scope” parameter, the name of the corresponding VO/VRE.
 
** ''Parameters needed:'' '''scope''' (the VO/VRE we need to access)
 
** ''Parameters needed:'' '''scope''' (the VO/VRE we need to access)
** URL request example: https://hostname/applicationSupportLayerHttp/LoginVRE;jsessionid=...?scope= /d4science.research-infrastructures.eu/EM/Demo
+
** URL request example: http://hostname:port/aslHttpInfrastructureLogin/LoginScope;jsessionid=37D9E6D381C37777BA312B1242EEADD6?scope=/gcube/devNext/NextNext
 
** ''Response:'' An HTTP OK status code or an HTTP error status code
 
** ''Response:'' An HTTP OK status code or an HTTP error status code
  
 +
The above functionality is offered from the aslhttpinfrastructurelogin component.
 +
It can be found at the following maven coordinates:
 +
 +
<source lang="xml">
 +
<groupId>org.gcube.applicationsupportlayer</groupId>
 +
<artifactId>aslhttpinfrastructurelogin</artifactId>
 +
<version></version>
 +
<packaging>war</packaging>
 +
</source>
  
 
=== Search Functionality ===
 
=== Search Functionality ===
Four different ways to search the content of the VO/VREs are offered through ASL HTTP API: quick search, browse, simple search and combined search. A GET method can be made in the “SearchResults” servlet of the http api, in order to access this functionality. The user can specify the type of search he wishes to perform, by passing the appropriate value to the “searchType” parameter of the request. In the following paragraphs, a detailed analysis of how to search the content through http is presented:
+
Four different ways to search the content of the VO/VREs are offered through ASL HTTP API: quick search, browse, simple search and generic search. A GET method can be made in the “SearchResults” servlet of the http api, in order to access this functionality. The user can specify the type of search he wishes to perform, by passing the appropriate value to the “searchType” parameter of the request. In the following paragraphs, a detailed analysis of how to search the content through http is presented:
 
+
* '''Quick Search'''
+
Quick search enables the user to search all the content for the terms he wishes to find. A simple GET request must be made to the “SearchResults” servlet of the ASL HTTP API, having given as value to the searchType parameter the string “quick”. The second parameter needed for this request is the “searchTerms”, where the user needs to specify the words he wishes to look for inside the content.
+
** ''Parameters needed:'' '''searchType=quick''', '''searchTerms'''(the terms we want to look for)
+
** URL request example: https://hostname/applicationSupportLayerHttp/SearchResults;jsessionid=...?searchType=quick&searchTerms=europe
+
** ''Response:'' XML results
+
 
+
 
+
  
  
 
* '''Browse'''
 
* '''Browse'''
The user can also browse specified collections on a specific browsable field that must be passed to the servlet through the “searchTerms” parameter. The additional parameters needed for this request are the “selectedCollection”, where the user needs to enter the collection ID of the collection he wants to search. The user must also pass the word “browse” as a value to the “searchType” parameter and he can also use two optional parameters in order to further organize his results. The first optional parameter is the “order” parameter, where he needs to enter the “ASC” value if he wishes to see the results in ascending order and correspondingly the “DESC” value for a descending order of the results. The second optional parameter is the “distinct” parameter the value of which (true or false) determines whether the results will come distinctly for each collection or not.  
+
The user can also browse specified collections on a specific browsable field that must be passed to the servlet through the “browseBy” parameter. The additional parameters needed for this request are the “selectedCollections”, where the user needs to enter the collection IDs of the collections he wants to browse. The user must also pass the word “browse” as a value to the “searchType” parameter and he can also use two optional parameters in order to further organize his results. The first optional parameter is the “order” parameter, where he needs to enter the “ASC” value if he wishes to see the results in ascending order and correspondingly the “DESC” value for a descending order of the results. The second optional parameter is the “distinct” parameter the value of which (true or false) determines whether the results will come distinctly for each collection or not.  
** ''Parameters needed:'' '''searchType=browse''', '''selectedCollection''' (the collection ID we want to browse ) , '''searchTerms''' (the browsable field),'''order''' (value: ASC or DESC - optional), '''distinct''' (value: true or false - optional)
+
** ''Parameters needed:'' '''searchType=browse''', '''selectedCollections''' (the collection IDs we want to browse ) , '''browseBy''' (the browsable field), '''distinct''' (value: true or false - optional)
** URL request example: https://hostname/applicationSupportLayerHttp/SearchResults;jsessionid=...?searchType=browse&selectedCollections= 778b3e50-f2a6-11dd-8d14-904a5718339a&searchTerms=satellite
+
** ''Optional Parameters:'''responseType''' (json or xml, default:xml), '''count''' (number of results, default:10)
 +
** URL request example: https://hostname:port/aslHttpInformationRetrieval/Search;jsessionid=...?searchType=browse&selectedCollections= {"SelectedCollections":["CollectionID"]}&searchTerms=satellite
 
** ''Response:'' XML results
 
** ''Response:'' XML results
 
 
  
  
  
 
* '''Simple Search'''
 
* '''Simple Search'''
For simple search, the user needs to give the string “simple” as a value to the “searchType” parameter. Secondly, he must specify the collections he wants to search by giving their IDs as values to the “SelectedCollection” parameter.In simple search, the user also needs to specify the “schema” and the “language” he wants to be used for the presentation of the results. Finally, the user can specify in the “searchTerms” parameter, the terms he needs to look for.  
+
For simple search, the user must specify the collections he wants to search by giving their IDs as values to the “SelectedCollection” parameter. Also, the user must specify in the “searchTerms” parameter, the terms he needs to look for.
** ''Parameters needed:'' '''searchType=simple''', '''selectedCollections''' (the IDs of the collections in which we want to search – multiple values), '''searchTerms''' (the terms we want to look for), '''schema''' (the selected schema), '''language''' (the schema language)
+
** ''Parameters needed:'''selectedCollections''' (the IDs of the collections in which we want to search – in json format), '''searchTerms''' (the terms we want to look for)
** URL request example: https://hostname/applicationSupportLayerHttp/SearchResults;jsessionid=...?selectedCollections=778b3e50-f2a6-11dd-8d14-904a5718339a&selectedCollections=24ce2920-09a8-11de-8d6f-a19cf0b0d020&schema=es&language=en&searchType=simple&searchTerms=europe
+
** ''Optional Parameters:'''responseType''' (json or xml, default:xml), '''count''' (number of results, default:10)
** ''Response:'' XML results
+
** URL request example: http://hostname:port/aslHttpInformationRetrieval/Search;jsessionid=37D9E6D381C37777BA312B1242EEADD6?searchType=simple&selectedCollections={"SelectedCollections":["CollectionID"]}&responseType=xml&searchTerms=fao
  
  
  
 +
* '''Generic Search'''
  
 +
For generic search, the only mandatory parameters are the "searchTerms" and the "responseType". It performs a search for the "searchTerms" provided over all available collections and returns the result into various formats (xml, json).
 +
Other -optional- parameters are:
 +
"allFields" (default value: true)
 +
"count" (default value: 10)
 +
A generic search can be cast without prior logging in, in specific VREs.
  
* '''Combined Search'''
+
A sample request is
In combined search, the user can specify the schema and the language with which he wants to perform the search, as well as many combined search criteria. To this end, he needs to pass as value to the parameter “searchType” the string “combined”, the schema he prefers in the “schema” parameter, the language of the shema in the “language” parameter and the collection IDs of the collections in the “selectedCollections” parameters. Furthermore, he/she can declare one or more advanced criteria specifying the search field name and the search field value in the "criteriaNames" and "criteriaValues" parameters correspondingly.In this parameters, the value of each search Field must be given in the same order as the name of the search field. For example, the user can give as a parameters to the GET request the pair: criteriaNames= Title&criteriaValues=European Agency. From this request, the servlet will know that the search field name is the “Title”, and the value of the field must contain the words “European”, “Agency”. For this type of search, the user can also select a sortBy field, declaring it in the “sortBy” parameter and indicating the field by which the results will be sorted.
+
http://hostname:port/aslHttpInformationRetrieval/GenericSearch?responseType=xml&searchTerms=fao&allFields=true&count=20
** ''Parameters needed:'' '''searchType=combined''', '''selectedCollections''' , '''criteriaNames''' (search field names), '''criteriaValues''' (search fields values), '''schema''', '''language''', '''sortBy''' (the field by which the results will be sorted - optional)
+
** URL request example: https://hostname/applicationSupportLayerHttp/SearchResults;jsessionid=...?selectedCollections=778b3e50-f2a6-11dd-8d14-904a5718339a&selectedCollections=24ce2920-09a8-11de-8d6f-a19cf0b0d020&schema=es&language=en&searchType=combined&searchTerms=Title  europe&sortBy=Title
+
** ''Response:'' XML results
+
  
===== General Parameters =====
 
While performing your search queries using the HTTP API, you can also use a number of general parameters that are listed bellow:
 
 
* '''"count"''' parameter: The number of search results per page desired by the search client
 
 
* '''"startIndex"''' parameter: The index of the first search result desired by the search client.
 
 
* '''"openSearch"''' parameter: Whether the search clients want to get the results in OpenSearch form. This option is available only for quick and simple search.
 
 
In all the types of searches, the client can ask for a specific number of results he desires to see per page, as well as the specific index of the first search result. All the client needs to do is add two more, optional parameters to the request he makes for the search: the “count” and the “startIndex” parameters respectively.
 
The results are returned either in xml form, or in openSearch form depending on the optional “openSearch” parameter.OpenSearch is a collection of simple formats for sharing of search results. It helps search engines and search clients communicate by introducing a common set of formats to perform search requests and syndicate search results. The results that come from ASL Http API can be returned in OpenSearch format, if the parameter “openSearch” has the value “true” in the client’s request.
 
 
 
All the information needed by the search client, in order to perform the queries for searching results (available collections, available schemata, searchable, browsable fields etc.), can be retrieved using the Content functionality of the ASL HTTP API. In the following paragraphs a detailed analysis of this section is presented.
 
  
 
===== Example XML Results =====
 
===== Example XML Results =====
An example of the results returned from a simple search in XML form is presented bellow:
+
An example of the results returned from a generic search in XML form is presented below:
  
<source lang=java5>
+
<source lang=xml>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<?xml version="1.0" encoding="UTF-8"?>
 
<Results>
 
<Results>
<RSRecord CollID="94d02c10-f2eb-11dd-a6f4-add312924299" DocID="921fcc30-f2b6-11dd-8d16-904a5718339a" RankID="0.4768992">
+
  <RSRecord>
<mc:metadata…>
+
    <field>
<mc:header>
+
      <fieldId>gDocCollectionID</fieldId>
<mc:OID>
+
      <fieldValue>4997f130-dcd7-11e2-82e2-9415b2540510</fieldValue>
ed5a0900-f2eb-11dd-8d16-904a5718339a
+
      <fieldName>gDocCollectionID</fieldName>
</mc:OID>
+
    </field>
<mc:targetOID>
+
    <field>
921fcc30-f2b6-11dd-8d16-904a5718339a
+
      <fieldId>ObjectID</fieldId>
</mc:targetOID>
+
      <fieldValue>http://www.ecoscope.org/ontologies/resources/catalogGeonetWorkSouthAfrica</fieldValue>
<mc:memberOf>
+
      <fieldName>ObjectID</fieldName>
<mc:ID>94d02c10-f2eb-11dd-a6f4-add312924299</mc:ID>
+
    </field>
</mc:memberOf>
+
    <field>
<mc:creation>2009-02-04:07:42:40.CET</mc:creation>
+
      <fieldId>1219dd0a-04aa-4890-bbca-6f8065cb18c3</fieldId>
<mc:lastUpdate>2009-02-04:07:42:40.CET</mc:lastUpdate>
+
      <fieldValue>A COMPLETER ...</fieldValue>
</mc:header>
+
      <fieldName>S</fieldName>
<mc:body><RECORD> <image_id>1858</image_id>   <title>Western Europe</title>   <caption>Envisat capture……. </mc:body>
+
    </field>
</mc:metadata>
+
    <field>
+
      <fieldId>e095a0a0-2202-4106-94a9-f3e66d5741da</fieldId>
</RSRecord>
+
      <fieldValue>Catalogues de ressources informationelles de l'XXX, Afrique du Sud</fieldValue>
<RSRecord CollID="94d02c10-f2eb-11dd-a6f4-add312924299" DocID="3334fa20-f2e7-11dd-8d16-904a5718339a" RankID="0.4702071">
+
      <fieldName>title</fieldName>
+
    </field>
</RSRecord>
+
  </RSRecord>
+
 
</Results>
 
</Results>
 
</source>
 
</source>
  
The meaning of each id presented in the XML results is listed bellow:
+
The gDocCollectionID and ObjectID fields are rendered by default and represent the id of the gCube collection to which the document belongs and the id of the document respectively. The rest of the fields are the defined by the administrator (and selected by the user) presentation fields of the relative gCube collection.
 
+
    CollID:  The metadata Collection id
+
 
+
    DocID: The object id
+
 
+
    mc:OID: The metadata object id
+
 
+
    mc:targetOID: The object id
+
 
+
    mc:ID: The metadata Collection id
+
 
+
    mc:creation: The creation date of the object
+
+
 
+
    Mc:Body: actual metadata of the object for the specified schema
+
  
 +
The above Search functionality over http requests is offered by the aslHttpInformationRetrieval component at the maven coordinates:
  
 +
<source lang="xml">
 +
<groupId>org.gcube.applicationsupportlayer</groupId>
 +
<artifactId>asl-http-information-retrieval</artifactId>
 +
<version>1.4.0-SNAPSHOT</version>
 +
<packaging>war</packaging>
 +
</source>
  
 
=== Content Functionality ===
 
=== Content Functionality ===
  
* '''Get Available Collections'''
+
* '''Show Collections'''
Once logged in to a VO/VRE, the user is able to see the available collections in the corresponding scope. Using the “ShowCollections” servlet of the ASL Http API, the user can retrieve an XML with the necessary information about the names and the IDs of the collections he can access.
+
Once logged in to a VO/VRE through the Login Http Interface, the user is able to see the available collections in the corresponding scope. Using the “ShowCollections” servlet of the ASL Http API, the user can retrieve the necessary information about the names and the IDs of the collections he can access.
 
** ''Parameters needed:'' '''none'''
 
** ''Parameters needed:'' '''none'''
** URL request example: https://hostname/applicationSupportLayerHttp/ShowCollections;jsessionid=...
+
** ''Optional Parameters:'' '''scope'''
** ''Response:'' An example response of available collections is presented bellow:
+
** URL request example: http://hostname:port/aslHttpInformationRetrieval/ShowCollections
<source lang=java5>
+
** ''Response:'' The information returned in json(default) or XML contains a list with the scopes and the available collections.
<?xml version="1.0" encoding="UTF-8"?>
+
<Collections>
+
<CollectionGroup name="Images">
+
<Collection>
+
<name>EM ESA Earth Images</name>
+
<colId>778b3e50-f2a6-11dd-8d14-904a5718339a</colId>
+
</Collection>
+
</CollectionGroup>
+
<CollectionGroup name = name="European Environment Agency Reports“>
+
+
</CollectionGroup>
+
</Collections>
+
</source>
+
  
  
 
+
* '''Show Collection Info'''
* '''Show Collection Infos'''
+
The users can choose one or more collections and retrieve information about them, using the “CollectionInfos” servlet. The input parameters to this query are the ids of the collections. The response to this query is an xml file containing information about those collections, like the available languages and the browsable fields. If the user also passes a selected language using the “language” parameter, then he can also get the searchable and the sortable fields for the corresponding collections.
The users can choose one or more collections and retrieve information about them, using the “ContentInfos” servlet. The input parameters to this query are the ids of the collections he has chosen. The response to this query is an xml file containing information about those collections, like the available schemata and the browsable fields. If the user also passes a selected schema, using the “schema”, “language” parameters, then he can also get the searchable and the sortable fields for the corresponding collections.
+
** ''Parameters needed:'' '''selectedCollections'''
** ''Parameters needed:'' '''selectedCollections''' (collection IDs – multiple values), '''schema''' (optional), '''language''' (optional)
+
** ''Optional Parameters:'' '''responseType''' , '''language'''
** URL request example: https://hostname/applicationSupportLayerHttp/CollectionInfos;jsessionid=...?selectedCollections= 778b3e50-f2a6-11dd-8d14-904a5718339a
+
** URL request example: http://hostname:port/aslHttpInformationRetrieval/CollectionInfos?selectedCollections={"SelectedCollections":["A_Collection_ID"]}
** ''Response:'' An example response of the information returned is presented bellow:
+
** ''Response:'' The information returned in json(default) or XML contains a list with the scopes and the available collections.
<source lang=java5>
+
<?xml version="1.0" encoding="UTF-8"?>
+
<CollectionsInfos>
+
<AvailableSchemata>
+
<schema>
+
<name>eiDB</name>
+
<language>en</language>
+
</schema>
+
+
</AvailableSchemata>
+
<AvailableBrowseFields>
+
<browseField>satellite</browseField>
+
+
</AvailableBrowseFields>
+
</CollectionsInfos>
+
</source>
+
 
+
  
  
* '''Get Content Infos'''
+
* '''Get Content Info'''
 
Once having retrieved the results from a search query, the client disposes the IDs of the information objects, the metadata objects and the collections. By passing as values to the “CID” and “OID” parameters in the “ContentInfos” servlet, the collection ID and the object ID of an object respectively, the client can get information about this digital object.  The information retrieved includes: the name, the mime type, the length of the object, the primary roles, the secondary roles and the available schemata for this object.
 
Once having retrieved the results from a search query, the client disposes the IDs of the information objects, the metadata objects and the collections. By passing as values to the “CID” and “OID” parameters in the “ContentInfos” servlet, the collection ID and the object ID of an object respectively, the client can get information about this digital object.  The information retrieved includes: the name, the mime type, the length of the object, the primary roles, the secondary roles and the available schemata for this object.
** ''Parameters needed:'' '''CID'''(collection ID), '''OID''' (object id)
+
** ''Parameters needed:'' '''documentURI''' (the uri of the object, with the scope appended), '' '''username'''
** URL request example: https://hostname/applicationSupportLayerHttp/CollectionInfos;jsessionid=...?selectedCollections= 778b3e50-f2a6-11dd-8d14-904a5718339a
+
** URL request example: http://hostname:port/aslHttpContentAccess/ContentInfo?username=userUser&documentURI=http://data.d4science.org/tree/FAOFishFinderFactsheeets/CRQ?scope=/d4science.research-infrastructures.eu/gCubeApps
 
** ''Response:'' The information returned in XML form contains:  
 
** ''Response:'' The information returned in XML form contains:  
- Name
+
* Name
- Object ID
+
* Object ID
- Mime Type
+
* Collection ID
- Length (bytes)
+
* Mime Type
- Primary Roles
+
* Length (bytes)
- Secondary Roles
+
- Available Schemata – Corresponding Metadata Collection IDs
+
  
  
 +
* '''View Content'''
  
 +
It retrieves the content of the corresponding digital object.The required parameter is the “documentURI” of the object. The “ContentViewer” servlet that is responsible for the content retrieval, renders the content depending on the mime type of the digital object.
 +
** ''Parameters needed:'' '''documentURI''' (the uri of the object, with the scope appended), '' '''username'''
 +
** URL request example: http://hostname:port/aslHttpContentAccess/ContentViewer;jsessionid=.....?username=user.user&documentURI=http://gcube.data.d4science.org/tree/FIGIS/RRU?scope=/gcube/devNext
 +
** ''Response:'' According to the mime type of the object, the content is delivered appropriately.
  
* '''Get Metadata Infos'''
+
The above Content functionality is offered by the component aslHttpContentAccess at the maven coordinates:
  
Having the collection id, the object id and the schemata, or the metadata collection id corresponding to a digital object, the client can ask for information about the object in another schema. In that case, the MetadataViewer serlvet can be used, that needs to receive as parameters the collection ID (“CID”), the object ID (“OID”) and the schema of the metadata that must be shown (“schema” and “language” parameters), or the id of the corresponding metadata collection (“MID”). As a response, an xml file describing the metadata in the specified schema is returned.
+
<source lang="xml">  
** ''Parameters needed:'' '''CID'''(collection ID), '''OID''' (object id), '''MID''' (metadata collection ID) or metadata '''schema''' and '''language'''
+
<groupId>org.gcube.applicationsupportlayer</groupId>
** URL request example: https://hostname/applicationSupportLayerHttp/MetadataInfos;jsessionid=...?CID= 778b3e50-f2a6-11dd-8d14-904a5718339a&OID=921fcc30-f2b6-11dd-8d16-904a5718339a&MID= b6c5bf00-f440-11dd-a6ff-add312924299
+
<artifactId>asl-http-content-access</artifactId>
** ''Response:'' An example of the information returned in XML form is presented bellow:
+
<version>1.2.0-SNAPSHOT</version>
<source lang=java5>
+
<packaging>war</packaging>
    <mc:metadata xmlns:mc="http://gcube-system.org/namespaces/metadatamanagement/mm/model">
+
        <mc:header>
+
            <mc:OID>3901be10-f441-11dd-8d17-904a5718339a</mc:OID><mc:targetOID>921fcc30-f2b6-11dd-8d16-904a5718339a</mc:targetOID>                <mc:generatedBy>ed5a0900-f2eb-11dd-8d16-904a5718339a</mc:generatedBy>
+
            <mc:memberOf>
+
                <mc:ID>b6c5bf00-f440-11dd-a6ff-add312924299</mc:ID>
+
            </mc:memberOf>
+
                <mc:creation>2009-02-06T01:25:33</mc:creation>
+
        <mc:lastUpdate>2009-02-06T01:25:33</mc:lastUpdate>
+
        </mc:header>
+
        <mc:body>
+
            <esTemplate>
+
                <esObject><title>Western Europe</title>
+
                    <description>Envisat captures)</description>
+
                    <purpose/>
+
                    <provenance>
+
                        <creator>ESA</creator>
+
                    </provenance>
+
                    <type/>
+
                    <descKeys>
+
                        <keyword/>
+
                    </descKeys>
+
                    <timeFrame><begin/><end>2008-09-28</end></timeFrame>
+
                    <location><width>1165</width>
+
                        <centerLat>47.01</centerLat>
+
                        <centerLon>2.77</centerLon>
+
                        <westBL/>
+
                        <eastBL/>
+
                        <southBL/>
+
                        <northBL/>
+
                    </location>
+
                    <suppInfo/>
+
                </esObject>
+
            </esTemplate>
+
        </mc:body>
+
    </mc:metadata>
+
 
</source>
 
</source>
 
 
* '''Deliver Content'''
 
It retrieves the content of the corresponding digital object.The required parameter is the “OID” of the object, The user can also optionally choose whether to save or not the content by using the “save” parameter. The “ContentViewer” servlet that is responsible for the contetnt retrieval, renders the content depending on the mime type of the digital object.
 
** ''Parameters needed:'' '''OID''' (object id), '''save''' (values: true or false – optional)
 
** URL request example: https://hostname/applicationSupportLayerHttp/ContentViewer;jsessionid=...?OID=921fcc30-f2b6-11dd-8d16-904a5718339a&save=true
 
** ''Response:'' According to the mime type of the object, the content is delivered appropriately.
 
 
 
 
  
 
=== Installation Instructions ===
 
=== Installation Instructions ===
Line 927: Line 974:
 
'''Step 2: Create a standard JAAS configuration file with the following content and place it in $CATALINA_HOME/conf/'''
 
'''Step 2: Create a standard JAAS configuration file with the following content and place it in $CATALINA_HOME/conf/'''
  
<source lang=java5>
+
<source lang=text>
 
Gridsphere {
 
Gridsphere {
 
org.jboss.security.auth.spi.LdapExtLoginModule required
 
org.jboss.security.auth.spi.LdapExtLoginModule required
Line 954: Line 1,001:
 
'''Step 3: Modify $CATALINA_HOME/bin/catalina.sh to include the following:'''
 
'''Step 3: Modify $CATALINA_HOME/bin/catalina.sh to include the following:'''
  
<source lang=java5>
+
<source lang=text>
 
echo "Using JAAS Authentication $CATALINA_HOME/conf/jaas.config"
 
echo "Using JAAS Authentication $CATALINA_HOME/conf/jaas.config"
 
JAVA_OPTS="$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_HOME/conf/jaas.config"
 
JAVA_OPTS="$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_HOME/conf/jaas.config"
Line 960: Line 1,007:
  
 
You should place that two lines of code anywhere but make sure the $CATALINA_HOME is defined already, a good place would be after this piece of code:
 
You should place that two lines of code anywhere but make sure the $CATALINA_HOME is defined already, a good place would be after this piece of code:
<source lang=java5>
+
<source lang=text>
 
.
 
.
 
.
 
.
Line 982: Line 1,029:
 
Step 4: Restart Tomcat'''
 
Step 4: Restart Tomcat'''
 
This concludes the installation of the ASL LDAP Authorization. You have just to startup the tomcat container.
 
This concludes the installation of the ASL LDAP Authorization. You have just to startup the tomcat container.
 +
 +
=== Anonymous Access in gCube System ===
 +
 +
Anonymous Access is available for all the functionality offered by the HTTP API. The anonymous access is configurable based on the installation. To allow or prevent users to connect anonymously, the administrator has to register a generic resource in the gCube IS under the relative scope, called OpenAccessConfiguration. An example of the contents of this configuration resource is the following:
 +
 +
<source lang=text>
 +
/** Configuration file for anonymous access - D4Science **/
 +
 +
<Functions>
 +
               
 +
            <ShowCollectionInfos>true</ShowCollectionInfos>
 +
   
 +
            <ShowContentInfos>true</ShowContentInfos>
 +
   
 +
            <GetContent>true</GetContent>
 +
   
 +
            <GetMetadata>true</GetMetadata>
 +
   
 +
            <ShowCollections>true</ShowCollections>
 +
   
 +
            <Search>true</Search>
 +
   
 +
            <GetThumbnails>true</GetThumbnails>
 +
   
 +
            <ShowVREs>true</ShowVREs>
 +
   
 +
</Functions>
 +
 +
</source>
 +
 +
 +
The values can be set to true or false according to the administrator's wish to allow or deny anonymous access to the corresponding functionality. More specifically:
 +
 +
* If '''ShowCollectionInfos''' is set to true, the users can see collection infos, such as available schemata, searchable and browsable fields etc anonymously.
 +
* If '''ShowContentInfos''' is set to true, the users can see information about the content, such as the corresponding metadata anonymously.
 +
* If '''GetContent''' is set to true, the users will be able to download and see content anonymously.
 +
* If '''GetMetadata''' is set to true, the users will be able to see information about the metadata, anonymously.
 +
* If '''Search''' is set to true, the users will be able to search using the D4Science search engine anonymously.
 +
* If '''GetThumbnails''' is set to true, the users will be able to retrieve the thumbnails of the objects.
 +
* If '''ShowVREs''' is set to true, the users will be able to see the available VO/VREs, to which they can login with anonymous access.
 +
 +
 +
Finally, ASL uses the UsersManagement service to retrieve information about the scopes, the users, their roles etc. To locate the service a configuration file named '''UMServiceLocation.config''' that contains the endpoint reference of the service should placed under $CATALINA_HOME/shared/d4s folder.
 +
 +
<font color="red">'''Important!'''</font>
 +
In order to use anonymous access, all the corresponding requests '''must''' include one more parameter, the one for the selected scope. To this end the '''"scope"''' parameter must be also set, having as value the VO/VRE through which the anonymous user makes the requests.
 +
 +
=== OAI-PMH Interface ===
 +
ASL HTTP API provides an OAI-PMH interface for exposing gCube metadata. The details of the implementation are described [[ASL: OAI-PMH Implementation|here]]
 +
 +
=== OAI-ORE Interface ===
 +
ASL HTTP API provides an OAI-ORE interface for disseminating gCube documents as OAI-ORE Resource Maps. The details of the implementation are described [[HTTP Front End: OAI-ORE Implementation|here]]

Latest revision as of 14:22, 2 February 2016

Introduction

The Application Support Layer (ASL) is a middleware between gCube Lower level Services and the gCube Presentation Layer. Its main goal is to provide a unified interface for accessing gCube and to allow application developers to deal only with how to render and present the corresponding functionality. Furthermore, ASL is responsible for covering all the application logic needed in order to fulfill users’ requirements. Since ASL aims at addressing a wide audience - not only gCube developers, it is designed to wrap gCube’s complexity by packing and interfacing standard procedures like retrieving service running instances from IS or accessing information the services or the IS holds. It should be mentioned that ASL users need no knowledge about where the services are running and how to access them in order to accomplish their goal. In particular, ASL consists of ASL Core and ASL Extensions. ASL Core is the group of basic functionality on which developers can build their own extensions. It provides a session mechanism as well as easy ways to retrieve running instances and invoke services. It also deals with security and authentication. On the other hand, ASL Extensions are libraries that extend ASL Core in order to cover the usage of other (new / non core) services. ASL Core functionality facilitates the development of these libraries. They aim to provide the GUI developer with a full package that will cover all the application logic so as to create the corresponding Graphical Interfaces. For each new functionality offered by gCube, a corresponding ASL Extension should be developed. Offering both Java and HTTP APIs, ASL supports multiple ways to contact and interact with gCube lower level services. In essence, ASL acts as a gateway for other technologies to access gCube advanced facilities. This means that it receives all the requests to call gCube services and, acting as a proxy, it invokes the corresponding services.

Reference Architecture

Asl.jpg


In brief, the design of ASL is motivated by the following objectives:

  • To remove the application logic from the presentation layer.
  • To enable external developers to create Graphical User Interfaces (GUIs) for gCube system without any knowledge of its internal design and architecture.
  • To speed up gCube system’s performance by caching frequently used, and/or rarely modified resources.
  • To provide an easy way to manage credentials.
  • To offer a global session management that enforces interoperability and intercommunication between application components.


The aforementioned objectives and design decisions are analyzed in the following sub-sections.

Drawing8.png


As it is depicted in the figure above, ASL consists of two main sections: ASL Core and ASL Extensions. ASL core is internally organized in three main groups: session management, cache, and the core functionality. ASL extensions currently contain the packages for ASL UserProfile and ASL Search.


ASL Core Functionality


ASL Core provides the fundamentals for building a gCube Graphical Application. It is the API that ASL consumers use in order to interact with gCube. It acts as a proxy that hides complexity of several steps needed for the invocations. It also contains the application logic for interpreting information received by gCube and transforming it into a presentable form. It also facilitates ASL extension developers by dealing with security issues and user credentials, session management and retrieval of generic resources.

Session Management

An important part of ASL Core is the session management. In order to consider ASL as a framework that completely supports users’ needs, it should implement its own mechanisms for providing sessions. Session is of crucial importance for the presentation layer since it provides means of storing information related to each user and means of intercommunication between application components. For this reason, a Session Manager has been implemented, based on the singleton design pattern. Its role is to administrate session objects, and to provide each user with his/her session. By using it, an application component can intercommunicate with another component by storing information in the session, and reading it from the other one. In fact, session is a hash map containing name – value pairs for various properties.

Resources Retrieval from IS

An functionality offered by the ASL Core, is the retrieval of Generic resources from the IS. It exposes an API to read and write GenericResource objects on the IS. Then, by using extensions the GenericResource content can even be parsed to extract it's information (i.e. the asl content extension offers such a functionality).


The ASL core component can be found at the following maven coordinates:

 
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslcore</artifactId>
<version>...</version>

ASL Extensions


ASL Content Extension

ASL Content extension supports the management of Resources and Digital Objects which reside within the IS and hold information regarding all the available collections (data sources) and their linked data. It offers methods to extract information from IS objects, parse the content of gCube collection objects, modify the content and replace it on the IS.

The ASL Content component can be found at the following maven coordinates:

 
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslcontent</artifactId>
<version>...</version>

ASL Search Extension

ASL Search Extension supports search functionality in order to query collections and retrieve the results. It contacts the SearchSystem Service and the ResourceRegistry in order to retrieve information about the collections and the available fields, joining the knowledge acquired from their dynamic and static configuration. Graphical User Interface can build the query step by step by first selecting the collections, then filling in the criteria, and finally submitting the query. Once the user's selections are made, a CQL Query is built from within the component, using the GCQLParser library. Then the query is submitted to the SearchMaster in order to be executed. The results will be retrieved in pages either in a personalized html format or as plain metadata (e.g. xml). Additionally, the user can navigate through results be requesting the previous, next or first page.

The ASL search extension can be found at the following maven coordinates:

 
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslsearch</artifactId>
<version>...</version>

ASL VRE Management Extension

In order to manage a Virtual Research Environment, ASL VRE Management extension offers a rich API so as to administer the infrastructure. Part of the functionality provided is to create/ update/ delete a Generic Resource on IS, to query IS in order to retrieve information such as running instances, available GHNs, in addition to creating / updating a VRE, and dynamically deploying a service.

ASL Social Extension

gCube applications use a common library for exploiting the Social Data Sharing facilities. gCube Applications do not interact with the Social Library directly. Rather they exploit this ASL-Extension capability. Please refer to the Social Networking Library wiki page for more information about how to exploit it.

ASL Access Logger Library

The Access Logger library provides methods in order to log the most common actions that are performed when using the D4Science portal. The actions that can be logged using the corresponding methods are:

  • The login to a VO/VRE
  • All types of search (Simple, Advanced and collection Browsing)
  • Content Retrieval

For any other information the GenericLogger can be used to log any given message

Furthermore portlets can extend AccessLogger's interface and create their own specific entries that will be logged.

How to use the Access Logger

In order to use the AccessLogger first you need to create an instance of the AccessLogger object that is based on the Singleton resource pattern.

AccessLogger log = AccessLogger.getAccessLogger();

Then depending on the action you would like to log you need to create an instance of the object that logs the desired action.
The sample code below shows how to log the login to a VO/VRE and a simple search query:

LoginToVreAccessLogEntry loginEntry = new LoginToVreAccessLogEntry();
/*
* The first argument is the username of the user that performs the action
* The second argument is the name of the working VO/VRE
*/
log.logEntry("testUsername", "ECOSYSTEM/TryIt", loginEntry);
 
String collections[][] = new String[2][2];
collections[0][0] = "Earth images";
collections[0][1] = "12345";
collections[1][0] = "Landsat 7";
collections[1][1] = "54321";
SimpleSearchAccessLogEntry simpleEntry = new SimpleSearchAccessLogEntry(collections, "satellite, sea");
/*
* The first argument is the username of the user that performs the action
* The second argument is the name of the working VO/VRE
*/
log.logEntry("testUsername", "ECOSYSTEM/TryIt", simpleEntry);

The other actions follow the same pattern.


The logs are saved in the tmp/accessLogs directory. A logger file is created for every day following this pattern: accessLog"DATE".log

How to create your own entries by extending the Access Logger

The AccessLogger library can be used and extended by any component in order to log its own entries to the access log.

In order to create your own entry you should:

  • Create your own class that extends the AccessLogEntry class
  • The constructor of your class must invoke the super constructor and pass the name of your entry that represents the Type of the log (see the example below)
  • The getLogMessage should return the message that will be logged
public class ContentRetrievalLogEntry extends AccessLogEntry {
 
	private String objectID;
 
	private String objectName;
 
	/**
	 * Constructor 
	 * 
	 * @param objectID The ID of the object that is retrieved
	 * @param objectName The name of the object that is retrieved
	 */
	public ContentRetrievalLogEntry(String objectID, String objectName) {
		super(EntryTypeConstants.RETRIEVE_CONTENT_ENTRY);
 
		this.objectID = replaceReservedChars(objectID);
		this.objectName = replaceReservedChars(objectName);
	}
 
	/**
	 * @return The log message for a Content retrieval entry
	 */
	public String getLogMessage() {
		String message = "";
		message += TemplateConstants.CONTENT_ID + TemplateConstants.eqChar + 
			this.objectID + TemplateConstants.separateCharacters + TemplateConstants.CONTENT_NAME +  
			TemplateConstants.eqChar + this.objectName;
 
		return message;
	}
 
}
  • NOTE: The AccessLogEntry class provides the static method replaceReservedChars that should be invoked on the message to be logged so as to ensure that none of the reserved characters used by the logger will be part of the message

Home Library

The Home Library manage and persist the users homes. More informations can be found here.

Caching for Performance

Cache plays a main role within ASL. Its existence is considered essential in order to improve gCube’s performance and to give the impression to the end-user that the application layer is always ready to promptly respond to their requests. Therefore, a variety of resources that are frequently requested are cached in order to speed up response time. Depending on the type of the cached resource, different refresh and storage policies can be applied. In particular, one can configure the expiration time of the cached resources, the maximum number of these objects in memory, whether or not to support overflow on disk, the maximum size of objects on the disk, etc. Furthermore, examples of resources that are cached are:

• The available collections per VRE: ASL Content extension caches the names of the available collections in a hierarchical structure together with information about the available languages, searchable fields, and the existence of any special kind of index, like full text, geospatial, or similarity index.

• Content information, it contains information about the digital objects, like their mime type, length, the existence of annotations over the object, the number of associated metadata, etc. This cache is implemented by ASL Content extension.

• Endpoint Resources for various service nodes (e.g. discovered search service endpoints). This cache is implemented by ASL Search extension.

• Generic Resources, it caches generic resources from IS since they are frequently requested and yet rarely modified. Examples of such resources are the metadata presentation xslts, the record presentation xslts, etc. This cache is placed in ASL Core, as the generic resources are frequently asked, their use is destined for a large variety of reasons and they should be provided by the core unit of ASL.

• Profiles, user’s profile is used in many cases in order to personalize the layout based on user’s preferences. Thus, having a replica in main memory (or in the local disk) speeds up the procedure. This caching mechanism is placed inside ASL User Profile extension.

Download

ASL jars can be found in the ETICS latest build.

How to use ASL

ASL Core - Retrieving Session

Graphical User Interface developers should use the ASL internal session in order to store information. In order to use the ASL's session, you need to take an instance of the SessionManager object that is based on the Singleton resource pattern. Through this instance a unique session for each user can be retrieved. If GUI is a Web Application (portlet, servlet, jsp etc), then the proposed way to retrieve user's session is:

ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);

Where session is either a portlet-session or a servlet-session, and username is the username of the logged in user.

Needed imports:

import org.gcube.application.framework.session.ASLSession;
import org.gcube.application.framework.session.SessionManager;

Once you have the ASLSession object, you can use ASL API to communicate with gCube infrastructure.

VRE Management extension - Querying IS

By using ISInfo class, you can directly query the IS in order to retrieve information.
Additionally, you can add / remove a GHN and a Running Instance to a specific scope, you can retrieve the profiles of the collections of a given scope, you can get the metadata-collections associated with a given collection as well as the indices associated with a collection or metadata collection.

ASL Core - Managing Generic Resources

You can manage gCube generic resource by using the GenericResource class of ASL. Through this class you can create, update, delete and retrieve a generic resource from IS.

The sample code below represents how you can create, update and delete a generic resource:

ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
GenericResource gR = new GenericResource(aslSession);
ISGenericResource genResource = new ISGenericResource();
try {
	genResource.setName(SessionConstants.ScenarioSchemaInfo);
	genResource.setDescription("Bla foo test");
	genResource.setBody("<DL>the dl :-)</DL>");
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (Exception e) {
	e.printStackTrace();
}		
try {
	gR.createGenericResource(genResource); // Creating the generic resource!!!
	genResource.setDescription("this is different description!!!"); // Changing the description (locally)
	gR.updateDiligentGenericResourceByID(genResource); // Updating the generic resource on IS
	gR.remove(genResource); // Removing the generic resource
} catch (RemoteException e) {
		e.printStackTrace();
	}
}


The sample code below represents how you can retrieve information for generic resources:

/* Get the "name - id" pairs of the available generic resources */
 
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
 
LinkedHashMap<String,String> existingGRs = new LinkedHashMap<String,String>();
GenericResource gResources = new GenericResource(aslSession);
List<Pair> pairs = gResources.getAvailableGenericResourceNames();
 
for (int i=0; i<pairs.size(); i++) {
        String GRID = pairs.get(i).getValue();
        String GRName = pairs.get(i).getName();
        existingGRs.put(GRID, GRName);
}
/* Retrieve the list of the generic resources with the given name / id */
 
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
GenericResource gResources = new GenericResource(aslSession);
 
List<ISGenericResource> genericResources = gResources.getGenericResourceByID(“resourceId”);
 
genericResources = gResources.getGenericResourceByName(“resourceName”);

Additionally, ASL provides methods to retrieve from IS all tree collections and all Opensearch collections for the current scope.

ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
GenericResource gResources = new GenericResource(aslSession);
//retrieve the Generic Resources of all Tree Collections from IS (hashmap of {collectionID,GenericResource})
HashMap <String,org.gcube.common.resources.gcore.GenericResource> treeColGenResource = gResources.getAllTreeCollections(false);
//retrieve the Generic Resources of all OpenSearch Collections from IS (hashmap of {collectionID,GenericResource})
HashMap <String,org.gcube.common.resources.gcore.GenericResource> osColGenResource = gResources.getAllOpenSearchCollections(false);
// retrieve the Cardinality of a Tree Resource (hashmap of {collectionID, cardinallity})
HashMap<String, String> cardinalites = getTreeResourcesCardinalities();


A sample generic resource:

<Resource version="0.4.x">
 
   <ID>666cc610-dab3-11df-9db7-e8211f3b1465</ID>
 
   <Type>GenericResource</Type>
 
   <Scopes>
 
      <Scope>/d4science.research-infrastructures.eu/Ecosystem/DRIVER</Scope>
 
   </Scopes>
 
   <Profile>
 
      <SecondaryType>GenericResource</SecondaryType>
 
      <Name>ScenarioCollectionInfo</Name>
 
      <Description>Available collection groups and collections</Description>
 
      <Body>
 
         <VRE name="/d4science.research-infrastructures.eu/Ecosystem/DRIVER">
 
            <collectionsGroup description="" id="ext-gen319" name="DRIVER" reference="">
 
               <collection creationDate="04-02-2011 06:48:17" description="DRIVER Collection" id="4bc54b10-9661-11e0-b316-9c541a3a1781" name="DRIVER Collection" recno="-1" reference="" />
 
            </collectionsGroup>
 
         </VRE>
 
      </Body>
 
   </Profile>
 
</Resource>

Note:

Generic Reources are cached so as to avoid multiple calls to IS in order to retrieve the same resource many times.

Search Extension - Getting available Collections & Search Queries

In order to retrieve the available collections regarding the active VRE, or to retrieve a search query, you have to use the SearchHelper class.

The collections are returned in a hierarchical way. A HashMap contains the collections that are organized as level 2 tree. Each key of the map containes the id of a collection group that assembles collections logically packed together. The value of each key in the hash map is an array list with the collections belonging to that group.

By using SearchHelper class you can also retrieve the available languages supported by the collections in addition to the searchable and presentable fields that each of them offers. For each field offered by a collection, the languages, the presentable fields and the index capabilities are stored in the model of the internal architecture representing it.


How to retrieve available collections, search query and search fields per metadata schema:

ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
 
 
SearchHelper searchH = new SearchHelper(aslSession);
// Retrieving the available collections:
HashMap<org.gcube.application.framework.search.library.model.CollectionInfo, ArrayList<org.gcube.application.framework.search.library.model.CollectionInfo>> colls = searchH.getAvailableCollections();
if(colls != null)
{
	for (org.gcube.application.framework.search.library.model.CollectionInfo key:collectionInfos.keySet()) {
		ArrayList<org.gcube.application.framework.search.library.model.CollectionInfo> cols = collectionInfos.get(key);
		for (int i = 0; i < cols.size(); i++) {
			org.gcube.application.framework.search.library.model.CollectionInfo col = cols.get(i);
			System.out.println("The collection id is: " + col.getId() + ", the collection name is: " + col.getName() " and the number of contained documents is: " + col.getRecNo());
		}
	}
}
 
 
/** The queries are organized in "query groups". 
 * A query group actually contains the main query, but more queries can be added later
 * to the group that are corresponding to the initial query. For example when a user submits
 * a query and chooses to perform the search "by collection", then a set of queries will be
 * performed, one for every different collection. All those queries will belong to the same
 * query group. When asking for the "default" query, you actually get the first (and maybe only)
 * query of the group */
 
// Retrieving the first query (from a set of open queries):
// Get the current query group
QueryGroup queryGroup = sHelper.getActiveQueryGroup();
// Get the first query of the current group. 
Query queryObj = queryGroup.getQuery(DefaultQuery);


Needed imports:

import org.gcube.application.framework.search.library.impl.SearchHelper;
org.gcube.application.framework.search.library.model.CollectionInfo

Search Extension - Building & Submitting a Search Query

Once having created or obtained the query object you can form or update it, performing operations on the selected collections, the criteria set by the user, the selected schema, the condition type and the sorting order.

ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
SearchHelper sHelper = new SearchHelper(aslSession);
 
 
/* Refresh the information for the available collections */
 
// The information about the collections is retrieved directly from the gCube system
shelper.refreshAvailableCollections();
 
 
// Get the current query group
QueryGroup queryGroup = sHelper.getActiveQueryGroup();
// Get the first query of the current group. 
Query queryObj = queryGroup.getQuery(DefaultQuery);
 
/* Add new collections to the selected ones */
/* Set second parameter to true if you want to select the collections or false if you want to deselect them */
queryObj.selectCollections(collections, true, session);
 
 
/* Add / remove a new criterion to the query */
 
queryObj.addCriterion(new Criterion(searchFieldId, searchFieldName, searchFieldValue));
queryObj.removeCriterion(searchFieldIntegerNo)
 
/* Reset all the current criteria */
queryObj.reset();
 
/* Get the selected real collections (the selected collections without the collection groups) */
List<String>selectedCollections = queryObj.getSelectedRealCollections();
 
 
/* Get / set the current selected condition type */
queryObj.setOperator(Operator.AND); //or Operator.OR
Operator op = queryObj.getOperator();
 
/* Get the Languages for the selected collections */
List<String> languages = queryObj.getAvailableLanguages();
 
/* Get the fields for the selected collections */
List<SearchField> sFields = queryObj.getAvailableSearchFields();  // searchable fields
List<String> browsableFields = queryObj.getAvailableBrowseFields(); // browsable fields
List<String> sortFields = queryObj.getAvailableSortFields();  //sortable fields
 
 
/* Update a crierion */
List<Criterion> criteria = queryObj.getCriteria();
queryObj.updateCriterionName(internalNo, newName);  //update a criterion name
queryObj.updateCriterionValue(internalNo, newValue); //update a criterion value
queryObj.updateCriterionName(internalNo, newId); //update a criterion id
 
/* See available indexes */
boolean hasFts = queryObj.isFTSAvailable();
boolean hasGeo = queryObj.isGeoAvailable();
 
/* Get Query Description - in User friendly language */
String qDescription = queryObj.getQueryDescription();
 
/* Get Query in CQL */
String qCQL = queryObj.getQueryString();

Using the asl session you can set the current active query group, store and retrieve previous queries to update them performing the above operations. In this way you can achieve intercommunication between your application components and reuse previous stored information while the search is taking place and the user changes his/her search preferences.

Submit a search Query

Four types of search can be performed through ASL: Simple Search, Generic Search, Advanced Search and Browsing of the collections. For each type of search there is a corresponding way for forming and submitting the query. In the examples below the three types of query submissions are displayed:

  • Submit a Simple Query
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
SearchHelper shelper = new SearchHelper(aslSession);
QueryGroup queryGroup = shelper.getActiveQueryGroup();
Query queryObj = queryGroup.getQuery(DefaultQuery);
queryObj.setTerm(fts);		//The keyword to search for
session.setAttribute(SessionConstants.activePresentationQueryNo, new Integer(shelper.getActiveQueryGroupNo()));
 
queryObj.search(session, true);	//set second parameter to true, indicating the search is simple
 
int id = shelper.createQuery(shelper.getActiveQueryGroupNo());
shelper.setActiveQueryGroup(id);
  • Submit a Generic Search Query
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
SearchHelper shelper = new SearchHelper(aslSession);
Query q = new Query();
q.setSemanticEnrichment(true); //if true, it returns all presentable fields. Otherwise, it returns only {title,snippet} fields.
List<String> paramsList = new ArrayList<String> (); 
paramsList.add("fish"); //set the search term "fish"
ResultSetConsumerI rs = q.genericSearch(aslSession, paramsList);
/*
   do something with the ResultSet consumer
*/
  • Submit an Advanced Query
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
SearchHelper shelper = new SearchHelper(aslSession);
QueryGroup queryGroup = shelper.getActiveQueryGroup();
Query queryObj = queryGroup.getQuery(DefaultQuery);
 
session.setAttribute(SessionConstants.activePresentationQueryNo, new Integer(shelper.getActiveQueryGroupNo()));
// If the user wants to search per collection, separate queries must be constructed in the query group each for one collection, 
// and they must be separately submitted
 
queryObj.search(session, false);	//query submission
 
// After performing a search create a new query. It will actually clone the current query
int id = shelper.createQuery(shelper.getActiveQueryGroupNo());
shelper.setActiveQueryGroup(id);
  • Submit a Browse Query
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
 
SearchHelper shelper = new SearchHelper(aslSession);
QueryGroup queryGroup = shelper.getActiveQueryGroup();
Query queryObj = queryGroup.getQuery(DefaultQuery);
queryObj.setSortBy(sortBy);
queryObj.setOrder(Order.ASC); // or Order.DESC
 
// browse the contents of the collection
queryObj.setDistinct(false);
// or browse a specific field of a collection (distinct values)
queryObj.setDistinct(true);		
session.setAttribute(SessionConstants.activePresentationQueryNo, new Integer(shelper.getActiveQueryGroupNo()));
 
queryObj.browse(session);		
 
int id = shelper.createQuery(shelper.getActiveQueryGroupNo(), false);
shelper.setActiveQueryGroup(id);

User Profile Extension - Manage User Profile

Through ASL you can create and retrieve the user profile. Using the ASL session you can store many of the user's preferences in order for them to be quickly retrieved. In the code below you can see some examples of how to get and read the user's profile. Note that the library caches all UserProfiles, in order to reduce queries to the IS.

ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
UserProfile userProfile = new UserProfile(aslSession);
 
// Invoke the createResource method. If there is no profile, it creates a new one for the user.	
String username = "a.user";
userProfile.createUserProfile(username);
 
//retrieve the userprofile
userProfile.getUserProfile(username);
 
// set the profile payload
String profile = "<profile>.....</profile>"; //this is the profile xml as a string
userProfile.setUserProfile(username,profile);
 
// drop user profile
userProfile.dropUserProfile(username);
 
//set a default profile on IS
String profile = "<profile>.....</profile>"; //this is going to be set as a default profile on IS
userProfile.setDefaultProfile(profile);
/* Get specific elements from the user profile */
 
//get all the xslts
String[]  prXSLTs = userProfile.getElement(username, "/userprofile/preferences/xslts/presentationxslt/xslt");
 
//get the language the user has selected
String lang = userProfile.getElementValue(username, "/userprofile/preferences/defLanguage");

The UserProfile extension of ASL provides also methods to retrieve information from the profile in a structured and organized way. For instance, the chosen metadata xslts or the selected presentation fields per collection can be retrieved in the following manner:

UserProfile userProf = new UserProfile(session);
HashMap<String, ArrayList<String>> collectionsFields = userProf.getPresentationFields(session.getUsername());
 
HashMap<String, String> xsltNamesIds = userProf.getMetadataXSLTs(session.getUsername);

Content Extension - Manage Collections and Digital Objects

Through the classes DigitalObject and Collection, ASL Content Management extension supports the retrieval or creation and storage of digital objects on the IS. Below you can see examples of usage of their methods:

/* Retrieve or Create a Collection */
ASLSession aslSession = SessionManager.getInstance().getASLSession(session.getId(), username);
String colId = new String();
// find out if a collection with this name already exists
colId = Collection.getCollectionByName(collectionName, aslSession);
if (colId == null) 
	colId = Collection.createCollection(collectionName, aslSession, false);
//do something with the colId
 
/* Get collection's members */
Collection col = new Collection(aslSession, colId);
String[] documents = col.getMemberIDs();
 
/* Add a document to a collection */
DigitalOBject documentRepresentation = col.addMember(<InputStream with the content>, <String name>, <String mimeType>);


/* Retrieve and Update a Digital Object or Create a new Digital Object containing text in XML language */
String d_o = new String();
d_o = DigitalObject.findObjectByName(vreName, colId, aslSession);
if (d_o == null) {
	// create the object and store it
	DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
	DocumentBuilder docBuilder = null;
	try {
		docBuilder =  dbfac.newDocumentBuilder();
	} catch (ParserConfigurationException e) {
		//do something with exception
	}
	byte content[] = null;
	Document doc = docBuilder.newDocument();
	//  create the document
	// …
	// create string from xml tree
	String nodeString;
	TransformerFactory tFactory = TransformerFactory.newInstance();
	Transformer transformer = null;
	try {
		transformer = tFactory .newTransformer();
	} catch (TransformerConfigurationException e) {
		// do something with exception
	}
	transformer.setOutputProperty(“omit-xml-declaration”,”yes”);
	StringWriter sw = new StringWriter();
	StreamResult result = new StreamResult(sw);
	DOMSource source = new DOMSource(doc);
	try {
		transformer.transform(source, result);
	} catch (TransformerException e) {
		//do something with exception
	}
	nodeString = sw.getBuffer().toString();
	content = nodeString.getBytes();
	ByteArrayInputStream inputStr = new ByteArrayInputStream(content);
 
	String mimeType = “plain/text”;
	DigitalObject dobj = DigitalObject.createNewDigitalObject(colId, inputStr, vreName, aslSession, mimeType);
}
// retrieve and update the content
else {
	DigitalObject dobj = new DigitalObject(aslSession, d_o, colId);
	InputStream cont = dObj.getObject();
	if (cont != null) {
		DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
		Document doc = null;
 
		byte content[] = null;
		try {
			doc = dfactory.newDocumentBuilder().parse(cont);
		} catch (SAXException e) {
			// do something with exception
		} catch (IOException e) {
			//do something with exception
		} catch (ParserConfigurationExcetpion e) {
			//do something with exception
		}
		// update the document// create string from xml tree// update the content
		dObj.updateContent(aslSession, content);
	}
}

When you have created a DigitalObject you can get information about it (about its name, title, metadata, mime type, thumbnail, html representation) using the equivalent class methods.

How to consider an ASL Extension

When is an ASL Extension needed

ASL Extensions are libraries that extend ASL in order to cover usage of other (new non-core) services. ASLCore functionality facilitates the development of these libraries by offering standard ways to deal with cache, security and session. The aim of building ASL extensions is to provide the GUI developer with a full package that will cover all the application logic so as to create the corresponding Graphical Interfaces. Practically, an ASL extension is needed when:

  • A new functionality is added to gCube (e.g. a new service)
  • The existing ASL Extensions do not cover the functionality requested by users.
  • Part of a functionality needs to be offered in an alternative way than the existing one (e.g. offer personalized results, http api, etc)

Conventions

  • When creating a project destinated for an ASL Extension, it is recommended to name it with the following pattern:

"applicationSupportLayerNameOfTheExtension"

, where you can replace the "NameOfTheExtension" string with the name of your extension. For example the projects for the UserProfile and Search extensions are named respectively: applicationSupportLayerUserProfile and applicationSupportLayerSearch.

  • When creating a package inside an ASL Extension project, you should name it using the following naming convention:

org.gcube.application.framework.extensionRelatedName.packageRelatedName

For example the names of two of the packages inside Search extension project are:

org.gcube.application.framework.search.exception
org.gcube.application.framework.search.library.model
  • Another convention used for the API of ASL is the use of a package that includes the interface and a separate one for the implementation. This pattern is used in both ASL core and the existing ASL extensions. For example, in UserProfile extension the package "org.gcube.application.framework.userprofiles.library" includes the interface of the classes that are implemented in the package "org.gcube.application.framework.userprofiles.library.impl".


Basic Guidelines

In order to create an ASL Extension you should follow some basic guidelines that are listed below:

  • Offer simple interfaces. For example, if you want to retrieve the names of the existing collections, provide a method String[] getCollections()
  • Use the functionality already offered by ASL core and the existing ASL extensions.
  • Hide all the gCube complexity, like invoking a service, contacting IS, dealing with security, etc.
  • If you need information about the user, the scope etc, you should add the ASLSession as a parameter in the constructor (as a protected member of your class). For example, see the following constructor with an ASLSession:
public class SearchHelper implements SearchInfoI {
	ASLSession session;
	Public SearchHelper(ASLSession session) {
		this.session = session;
	}
}


  • Retrieving a cached object
public List<CollectionInfo>[] getAvailableCollections() {
	List<CollectionInfo>[] collections = (List<CollectionInfo>[])session.getAttribute(SessionConstants.Collections);
	if(collections == null)
	{	//Retrieve Available Collections from cache:
		collections = (List<CollectionInfo>[]) 
CachesManager.getInstance().getCollectionCache().get(session.getScopeName()).getValue();
		session.setAttribute(SessionConstants.Collections, collections);
	}
	return collections;
}

Needed imports:

org.gcube.application.framework.core.cache.CachesManager

ASL HTTP API

HTTP API offers a subset of Java API, mostly the fundamental functionality needed by simple end-users. It is planned to be extended based on users’ needs and requirements. It consists of a set of servlets that support both GET and POST http methods depending on what functionality is requested. The functionality offered by this api concerns four sections:

• User Authentication

• VO/VREs Functionality

• Content Retrieval Functionality

• Search Functionality

In detail, it currently provides support for the following functionality:


User Authentication

  • Login - Logout

The corresponding servlet receives the user’s credential (username – password) and communicates with LDAP in order to authenticate the user. It makes use of status codes and HTTP headers to manage the security policy. In case of denied credentials it returns an SC_UNAUTHORIZED status code to the client. Both BASIC and Form – based authentication methods are implemented to this end. In order to login, using ASL HTTP API, a GET or POST request needs to be made to the servlet with the name “LoginHandler”.

With the basic authorization scheme, the Authorization header contains the string of "username:password" encoded in Base64. For example, the username of "webmaster" with the password "try2guess" is sent in an Authorization header with the value:

 BASIC d2VibWFzdGVyOnRyeTJndWVTUw"

Here is an example of a URL for a login request: http://hostname:port/aslHttpInfrastructureLogin/Login

  • Session Tracking

ASL HTTP makes use of the built in session tracking mechanisms of the servlets. Consequently, the user’s session can be tracked either with the use of persistent cookies, where the session ID is saved on the client in a cookie called JSESSIONID, or with URL rewriting. URL rewriting can be used by clients that don’t support cookies by sending the sessionID as part of a rewritten URL, encoded using a jsessionid path parameter. The session is returned once the user logs in the system inside an XML response, and all the following URL – encoded requests must contain it. By offering a session tracking mechanism, ASL allows the user to make subsequent requests without having to log in every time he asks for a resource.

An example of an XML response returning the session id is presented bellow:

 
<?xml version="1.0" encoding="UTF-8"?>
    <SessionID>
        <jsessionid>6751BF9588491D6EB853096C84B3671F</jsessionid>
    </SessionID>

The login component can be found at the following maven coordinates:

 
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslhttpinfrastructurelogin</artifactId>
<version></version>
<packaging>war</packaging>

VO/VREs Functionality

  • Show Available VO/VREs

Once logged in, the user can see the VO/VREs to which he/she has access. To this end, the servlet reads from VOMS the groups for the user and then shows all the VREs the user can access and all the VOs to which the user has the role of VO-Admin or VRE-Manager or VRE-Designer or Production Support. In order to ask for the available VO/VREs, the client needs to make a GET request to the “ShowVREs” servlet of ASL HTTP API. An xml file, listing the information about the VO/VREs is sent as a response to the user. If the client adds the parameter "details" set to true, he/she will get more information about each virtual environment.

An example of an XML response, listing the available VO/VREs is presented bellow:

<?xml version="1.0" encoding="UTF-8"?>
<VOs-VREs>
    <VRE>/gcube/devNext/NextNext</VRE>
    <VRE>/gcube/devsec/devVRE</VRE>
    <VRE>/d4science.research-infrastructures.eu/gCubeApps/iSearch</VRE>
    <VO>/d4science.research-infrastructures.eu</VO>
    <VO>/gcube/devNext</VO>
    <VO>/gcube/devsec</VO>
    <VO>/d4science.research-infrastructures.eu/gCubeApps</VO>
    <VO>/gcube</VO>
</VOs-VREs>
  • Login to a VO/VRE:

In order to be able to see the available content of a VO/VRE, a user needs to log into it. To that end, a servlet that logs the user to a virtual research environment is created. A GET method must be made by the client, passing as a value to a “scope” parameter, the name of the corresponding VO/VRE.

The above functionality is offered from the aslhttpinfrastructurelogin component. It can be found at the following maven coordinates:

 
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>aslhttpinfrastructurelogin</artifactId>
<version></version>
<packaging>war</packaging>

Search Functionality

Four different ways to search the content of the VO/VREs are offered through ASL HTTP API: quick search, browse, simple search and generic search. A GET method can be made in the “SearchResults” servlet of the http api, in order to access this functionality. The user can specify the type of search he wishes to perform, by passing the appropriate value to the “searchType” parameter of the request. In the following paragraphs, a detailed analysis of how to search the content through http is presented:


  • Browse

The user can also browse specified collections on a specific browsable field that must be passed to the servlet through the “browseBy” parameter. The additional parameters needed for this request are the “selectedCollections”, where the user needs to enter the collection IDs of the collections he wants to browse. The user must also pass the word “browse” as a value to the “searchType” parameter and he can also use two optional parameters in order to further organize his results. The first optional parameter is the “order” parameter, where he needs to enter the “ASC” value if he wishes to see the results in ascending order and correspondingly the “DESC” value for a descending order of the results. The second optional parameter is the “distinct” parameter the value of which (true or false) determines whether the results will come distinctly for each collection or not.


  • Simple Search

For simple search, the user must specify the collections he wants to search by giving their IDs as values to the “SelectedCollection” parameter. Also, the user must specify in the “searchTerms” parameter, the terms he needs to look for.


  • Generic Search

For generic search, the only mandatory parameters are the "searchTerms" and the "responseType". It performs a search for the "searchTerms" provided over all available collections and returns the result into various formats (xml, json). Other -optional- parameters are: "allFields" (default value: true) "count" (default value: 10) A generic search can be cast without prior logging in, in specific VREs.

A sample request is http://hostname:port/aslHttpInformationRetrieval/GenericSearch?responseType=xml&searchTerms=fao&allFields=true&count=20


Example XML Results

An example of the results returned from a generic search in XML form is presented below:

<?xml version="1.0" encoding="UTF-8"?>
<Results>
  <RSRecord>
    <field>
      <fieldId>gDocCollectionID</fieldId>
      <fieldValue>4997f130-dcd7-11e2-82e2-9415b2540510</fieldValue>
      <fieldName>gDocCollectionID</fieldName>
    </field>
    <field>
      <fieldId>ObjectID</fieldId>
      <fieldValue>http://www.ecoscope.org/ontologies/resources/catalogGeonetWorkSouthAfrica</fieldValue>
      <fieldName>ObjectID</fieldName>
    </field>
    <field>
      <fieldId>1219dd0a-04aa-4890-bbca-6f8065cb18c3</fieldId>
      <fieldValue>A COMPLETER ...</fieldValue>
      <fieldName>S</fieldName>
    </field>
    <field>
      <fieldId>e095a0a0-2202-4106-94a9-f3e66d5741da</fieldId>
      <fieldValue>Catalogues de ressources informationelles de l'XXX, Afrique du Sud</fieldValue>
      <fieldName>title</fieldName>
    </field>
  </RSRecord>
</Results>

The gDocCollectionID and ObjectID fields are rendered by default and represent the id of the gCube collection to which the document belongs and the id of the document respectively. The rest of the fields are the defined by the administrator (and selected by the user) presentation fields of the relative gCube collection.

The above Search functionality over http requests is offered by the aslHttpInformationRetrieval component at the maven coordinates:

 
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>asl-http-information-retrieval</artifactId>
<version>1.4.0-SNAPSHOT</version>
<packaging>war</packaging>

Content Functionality

  • Show Collections

Once logged in to a VO/VRE through the Login Http Interface, the user is able to see the available collections in the corresponding scope. Using the “ShowCollections” servlet of the ASL Http API, the user can retrieve the necessary information about the names and the IDs of the collections he can access.


  • Show Collection Info

The users can choose one or more collections and retrieve information about them, using the “CollectionInfos” servlet. The input parameters to this query are the ids of the collections. The response to this query is an xml file containing information about those collections, like the available languages and the browsable fields. If the user also passes a selected language using the “language” parameter, then he can also get the searchable and the sortable fields for the corresponding collections.


  • Get Content Info

Once having retrieved the results from a search query, the client disposes the IDs of the information objects, the metadata objects and the collections. By passing as values to the “CID” and “OID” parameters in the “ContentInfos” servlet, the collection ID and the object ID of an object respectively, the client can get information about this digital object. The information retrieved includes: the name, the mime type, the length of the object, the primary roles, the secondary roles and the available schemata for this object.


  • View Content

It retrieves the content of the corresponding digital object.The required parameter is the “documentURI” of the object. The “ContentViewer” servlet that is responsible for the content retrieval, renders the content depending on the mime type of the digital object.

The above Content functionality is offered by the component aslHttpContentAccess at the maven coordinates:

 
<groupId>org.gcube.applicationsupportlayer</groupId>
<artifactId>asl-http-content-access</artifactId>
<version>1.2.0-SNAPSHOT</version>
<packaging>war</packaging>

Installation Instructions

  • Take the war file that is deployed in ETICS and place it in a simple web server that acts as a servlet engine for HTTP servlets (i.e Tomcat).
  • Dependencies:

- ASL and its dependencies - gCore

  • Configure LDAP Authentication from ASL

- ASL uses the JBoss JAAS LdapExtLoginModule to authenticate with a LDAP server. The necessary classes are contained in the jboss-common.jar and jbosssx.jar included with a standard JBoss Application Server. Step 1: Copy jboss-common.jar and jbosssx.jar in folder $CATALINA_HOME/shared/lib

With these libraries in our class path, we then need to create a standard JAAS confiburation file. This file can be arbitrary named and can be placed anywhere. We call it jaas.config and we place it into the configuration directory of our Application Server.

Step 2: Create a standard JAAS configuration file with the following content and place it in $CATALINA_HOME/conf/

Gridsphere {
	org.jboss.security.auth.spi.LdapExtLoginModule required
        java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
        java.naming.provider.url="ldap://ldap.research-infrastructures.eu/"
        java.naming.security.authentication=simple
        bindDN="cn=anonymous,ou=System,dc=research-infrastructures,dc=eu"
        bindCredential=freeToSearch
        baseCtxDN="ou=Organizations,dc=research-infrastructures,dc=eu"
        baseFilter="(uid={0})"
        rolesCtxDN="ou=Groups,ou=DevelopmentPortal,ou=D4Science,ou=Applications,dc=research-infrastructures,dc=eu"
        roleFilter="(uniqueMember={1})"
        roleAttributeID="cn"
        roleRecursion="-1"
	;
      };

Name it "jaas.config". (You may want to name it differently, the important thing is that in step 3 you use the same file name) This file contains everything is needed to communicate with the D4Science LDAP Server, be careful not to change anything in this file, copy and paste as it is in the frame above.


- Make the JVM load the ASL JAAS configuration

Now we have to make the JVM load our JAAS configuration at the time that Tomcat is started. This is done with the java.security.auth.login.config system property.

Step 3: Modify $CATALINA_HOME/bin/catalina.sh to include the following:

echo "Using JAAS Authentication $CATALINA_HOME/conf/jaas.config"
JAVA_OPTS="$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_HOME/conf/jaas.config"

You should place that two lines of code anywhere but make sure the $CATALINA_HOME is defined already, a good place would be after this piece of code:

.
.
. 
 
# Only set CATALINA_HOME if not already set
[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." ; pwd`
 
if [ -r "$CATALINA_BASE"/bin/setenv.sh ]; then
  . "$CATALINA_BASE"/bin/setenv.sh
elif [ -r "$CATALINA_HOME"/bin/setenv.sh ]; then
  . "$CATALINA_HOME"/bin/setenv.sh
fi
.
.
##Place the two lines here##
echo "Using JAAS Authentication $CATALINA_HOME/conf/jaas.config"
JAVA_OPTS="$JAVA_OPTS -Djava.security.auth.login.config==$CATALINA_HOME/conf/jaas.config"

Step 4: Restart Tomcat This concludes the installation of the ASL LDAP Authorization. You have just to startup the tomcat container.

Anonymous Access in gCube System

Anonymous Access is available for all the functionality offered by the HTTP API. The anonymous access is configurable based on the installation. To allow or prevent users to connect anonymously, the administrator has to register a generic resource in the gCube IS under the relative scope, called OpenAccessConfiguration. An example of the contents of this configuration resource is the following:

/** Configuration file for anonymous access - D4Science **/
 
<Functions>
 
            <ShowCollectionInfos>true</ShowCollectionInfos>
 
            <ShowContentInfos>true</ShowContentInfos>
 
            <GetContent>true</GetContent>
 
            <GetMetadata>true</GetMetadata>
 
            <ShowCollections>true</ShowCollections>
 
            <Search>true</Search>
 
            <GetThumbnails>true</GetThumbnails>
 
            <ShowVREs>true</ShowVREs>
 
</Functions>


The values can be set to true or false according to the administrator's wish to allow or deny anonymous access to the corresponding functionality. More specifically:

  • If ShowCollectionInfos is set to true, the users can see collection infos, such as available schemata, searchable and browsable fields etc anonymously.
  • If ShowContentInfos is set to true, the users can see information about the content, such as the corresponding metadata anonymously.
  • If GetContent is set to true, the users will be able to download and see content anonymously.
  • If GetMetadata is set to true, the users will be able to see information about the metadata, anonymously.
  • If Search is set to true, the users will be able to search using the D4Science search engine anonymously.
  • If GetThumbnails is set to true, the users will be able to retrieve the thumbnails of the objects.
  • If ShowVREs is set to true, the users will be able to see the available VO/VREs, to which they can login with anonymous access.


Finally, ASL uses the UsersManagement service to retrieve information about the scopes, the users, their roles etc. To locate the service a configuration file named UMServiceLocation.config that contains the endpoint reference of the service should placed under $CATALINA_HOME/shared/d4s folder.

Important! In order to use anonymous access, all the corresponding requests must include one more parameter, the one for the selected scope. To this end the "scope" parameter must be also set, having as value the VO/VRE through which the anonymous user makes the requests.

OAI-PMH Interface

ASL HTTP API provides an OAI-PMH interface for exposing gCube metadata. The details of the implementation are described here

OAI-ORE Interface

ASL HTTP API provides an OAI-ORE interface for disseminating gCube documents as OAI-ORE Resource Maps. The details of the implementation are described here