Difference between revisions of "GeoNetwork library"

From Gcube Wiki
Jump to: navigation, search
(Using the library)
(Usage)
(32 intermediate revisions by 2 users not shown)
Line 1: Line 1:
A library to interact with GeoNetwork's REST Interface to publish/modify/delete and search for Metadata.The library is designed on top of [https://github.com/geosolutions-it/geoserver-manager/wiki geoserver-manager library], developed by [http://www.geo-solutions.it/ GeoSolutions]. Metadata objects managed by the library are compliant to standard specification [[ISO 19115:2003/19139]]. Default configuration of the library interacts exploits [[Featherweight Stack]] functionalities to discover geonetwork available in the infrastructure.
+
<!-- CATEGORIES -->
 +
[[Category:Developer's Guide]][[Category: gCube Spatial Data Infrastructure]]
 +
<!-- CATEGORIES -->
 +
 
 +
<!-- END CATEGORIES -->
 +
A library to interact with GeoNetwork's REST Interface to publish/modify/delete and search for Metadata.The library is designed on top of [https://github.com/geosolutions-it/geonetwork-manager geoserver-manager library], developed by [http://www.geo-solutions.it/ GeoSolutions]. Metadata objects managed by the library are compliant to standard specification [[ISO 19115:2003/19139]]. Default configuration of the library interacts exploits [[Featherweight Stack]] functionalities to discover geonetwork available in the infrastructure.
  
 
=Module overview=
 
=Module overview=
Line 43: Line 48:
 
</source>
 
</source>
  
=Using the library=
+
==Using the library==
  
 
The library acts as a wrapper to the functionalities exposed by the ''geonetwork-manager'' library.
 
The library acts as a wrapper to the functionalities exposed by the ''geonetwork-manager'' library.
The methods offered by the library are splitted in two different interfaces :  
+
The methods offered by the library are splitted in three different interfaces :  
  
 
* ''org.gcube.spatial.data.geonetwork.GeoNetworkReader'' : declares methods to access metadata stored in geonetwork
 
* ''org.gcube.spatial.data.geonetwork.GeoNetworkReader'' : declares methods to access metadata stored in geonetwork
 
* ''org.gcube.spatial.data.geonetwork.GeoNetworkPublisher'' : extends ''GeoNetworkReader'', and declares methods to publish/update/delete metadata in geonetwork
 
* ''org.gcube.spatial.data.geonetwork.GeoNetworkPublisher'' : extends ''GeoNetworkReader'', and declares methods to publish/update/delete metadata in geonetwork
 +
* ''org.gcube.spatial.data.geonetwork.GeoNetworkAdministration'' : extends ''GeoNetworkPublisher'', and declares methods to manage users and groups on GeoNetwork ('''available from 3.0.0''')
 +
  
 
The class ''org.gcube.spatial.data.geonetwork.GeoNetwork'' offers two static members to obtain implementations of the above interfaces :
 
The class ''org.gcube.spatial.data.geonetwork.GeoNetwork'' offers two static members to obtain implementations of the above interfaces :
  
* ''public static GeoNetworkPublisher get() throws Exception'' : uses the current settings of ''ConfigurationManager'' to get a ''Configuration'' implementation.
+
* ''public static GeoNetworkAdministration get() throws Exception'' : uses the current settings of ''ConfigurationManager'' to get a ''Configuration'' implementation.
* ''public static GeoNetworkPublisher get(Configuration config)'' : uses the passed ''Configuration'' implementation.
+
* ''public static GeoNetworkAdministration get(Configuration config)'' : uses the passed ''Configuration'' implementation.
  
 
See [[#Configuration]] to get more information.
 
See [[#Configuration]] to get more information.
  
==Security==
+
 
 +
==Changes in 3.0.0==
 +
Along with gcube 4.0, comes a new version of the library : 3.0.0.
 +
Basic usage of the library remains at most the same, even if some important feature have changed, thus some refactoring might be needed anyway.
 +
The following is a list of the main changes in the library, please refer to the rest of this page for more detailed information
 +
 
 +
* Introduced ''GeoNetworkAdministration'' interface to manage groups and users on GeoNetwork
 +
* Configuration compliant with gcube 4.0.0 SDI publishing policies
 +
* Automatic generation of scope configuration if none is present
 +
* Improved publishing checks against current configuration
 +
* Improved model and faults management
 +
 
 +
 
 +
=User management=
 +
==Library version 2.0==
  
 
From version 2.0.0 the library refers to the guidelines stated in [[GeoNetwork administration]] in particular :  
 
From version 2.0.0 the library refers to the guidelines stated in [[GeoNetwork administration]] in particular :  
Line 82: Line 103:
 
see [[#Configuration]] for details on how the related credentials are used.
 
see [[#Configuration]] for details on how the related credentials are used.
  
==Configuration==
+
==Library Version 3.0==
 +
From version '''3.0.0''' the publication guidelines suggest that:
 +
* metadata that should be visible only inside the current scope  : use current scope's private group on GeoNetwork
 +
* metadata that should be visible in the current scope and in parent ones : use current scope's public group on GeoNetwork
 +
 
 +
 
 +
===Login===
 +
 
 +
Unless the client calls the method '' public void login(LoginLevel level)throws AuthorizationException'' declared by ''GeoNetworkReader'' interface, all calls to geonetwork are sent without login thus :
 +
 
 +
* queries return only public metadata
 +
* access to metadata with no public access will fail
 +
* methods which change the current geonetwork state will fail
 +
 
 +
Please note that by calling ''login'' method, the user specifies publishing behavior according to the current scope configuration involving the target group to use:
 +
 
 +
* DEFAULT : uses ''<SCOPE_USER>'' and publish into the default publishing group for the current scope;
 +
* SCOPE : uses ''<SCOPE_USER>'' and publish into the ''<PUBLIC_GROUP>'' for the current scope;
 +
* PRIVATE : uses ''<SCOPE_USER>'' and publish into the ''<PRIVATE_GROUP>'' for the current scope;
 +
* ADMIN : uses administration privileges, thus no check/ constraint are performed;
 +
* CKAN : uses '''read-only''' ckan user for that scope;
 +
 
 +
see [[#Configuration]] for details on how the related credentials are used.
 +
 
 +
=Geonetwork instances discovery=
  
 
The geonetwork library relies on instances of ''org.gcube.spatial.data.geonetwork.configuration.Configuration'' interface in order to retrieve needed information to interact with geonetwork REST interface.
 
The geonetwork library relies on instances of ''org.gcube.spatial.data.geonetwork.configuration.Configuration'' interface in order to retrieve needed information to interact with geonetwork REST interface.
Line 116: Line 161:
 
The convention used by this implementation are the one stated in [https://gcube.wiki.gcube-system.org/gcube/index.php/RuntimeResourceClassification#Geo_Network_Runtime_Resource GeoNetwork Runtime Resource Definition].
 
The convention used by this implementation are the one stated in [https://gcube.wiki.gcube-system.org/gcube/index.php/RuntimeResourceClassification#Geo_Network_Runtime_Resource GeoNetwork Runtime Resource Definition].
  
==Example Code==
+
==== Changes in 3.0.0 ====
 +
From version '''3.0.0''' the interface ''org.gcube.spatial.data.geonetwork.configuration.Configuration'' has been completely changed in order to manage gcube4.0.0 SDI publishing policies as described in [https://gcube.wiki.gcube-system.org/gcube/index.php/RuntimeResourceClassification#Geo_Network_Runtime_Resource GeoNetwork Runtime Resource Definition].
 +
 
 +
=Metadata generation facilities=
 +
Instances of ''org.opengis.metadata.Metadata'' interface can be generated in very different ways. However, we identified a common set of information which every application should include in its published metadata. Providing a common way to generate these metadata entry aims to :
 +
 
 +
* Reduce the needed effort to generate metadata from the developer's point of view;
 +
* Reuse of code;
 +
* Common behavior to gather common information (see [[#Infrastructure configuration]]);
 +
* Simplification of ISO Model (see [[#Metadata Descriptor]]);
 +
 
 +
==Metadata Descriptor==
 +
''org.gcube.spatial.data.geonetwork.iso.tpl.MetadataDescriptor'' is a Java class representing a simplified version of the ISO XML Model. The underlying logic will apply the model to XML templates in order to enforce the production of INSPIRE -compliant metadata throughout the infrastructure.
 +
 
 +
===Usage===
 +
 
 +
Following is an example snippet showing how to properly instantiate the class
 +
<source lang="java">
 +
MetadataDescriptor desc=new MetadataDescriptor();
 +
 
 +
//Setting Title
 +
desc.setTitle("...");
 +
 
 +
//Setting Identifier
 +
desc.setUUIDIdentifier(UUID.randomUUID().toString());
 +
 
 +
//Setting Purpose
 +
desc.setPurpose("...");
 +
 
 +
//Setting Abstract
 +
desc.setAbstractField("...");
 +
 
 +
//Setting Credits
 +
desc.addCredits("...");
 +
 
 +
// Setting Responsible Parties
 +
desc.addResponsibleParty(new ResponsibleParty("Author name","Author organization",
 +
ResponsiblePartyRole.AUTHOR,new Contact("author.mail@some.place.com","www.myorganization.com")));
 +
 +
//Setting Dataset Creation Time
 +
desc.setCreationTime(new GregorianCalendar().getTime());
 +
 
 +
 
 +
//Setting Spatial Representation
 +
VectorRepresentation representation=new VectorRepresentation(
 +
TopologyLevel.GEOMETRY_ONLY, 1000, GeometricObjectType.POINT);
 +
desc.setSpatialRepresentation(representation);
 +
 
 +
//Setting INSPIRE THEME(s)
 +
desc.addKeywordSet(new KeywordSet(
 +
KeywordType.THEME,
 +
Collections.singleton("Species distribution"),
 +
Thesaurus.INSPIRE_THEMES));
 +
 
 +
//Setting arbitrary keywords
 +
desc.addKeywordSet(new KeywordSet(Collections.singleton("...")));
 +
 
 +
//Setting Extent
 +
desc.getExtent().addGeographicExtent(BoundingBox.WORLD_EXTENT);
 +
 +
//Utility method for setting GeoServer Distribution Info
 +
desc.setGeoServerDistributionInfo("http://geoserver.d4science.org/geoserver",
 +
"ws","wmpa", "speciesProb", "EPSG:4326",BoundingBox.WORLD_EXTENT);
 +
 +
//Setting Spatial Resolution
 +
desc.setSpatialResolution(0.5d);
 +
 
 +
//Setting Usage and Access Constraints
 +
desc.setConstraints(new ResourceConstraints("...",
 +
new LegalConstraints(RestrictionCode.LICENSE,"CC-BY-SA"),
 +
new LegalConstraints(RestrictionCode.LICENSE,"CC-BY-SA")));
 +
 +
//Setting Topic Category
 +
desc.addTopicCategory(TopicCategory.ENVIRONMENT);
 +
 
 +
//Setting the Lineage Statement
 +
desc.setLineageStatement("...");
 +
 +
//Obtaining the metadata file
 +
File metaFile=ISOMetadataByTemplate.createXML(desc);
 +
</source>
 +
 
 +
==GcubeISOMetadata class==
 +
<pre style="color: red"> Please note that this class is deprecated and won't be supported in upcoming versions. See the MetadataDescriptor section in this page.</pre>
 +
The utility class ''org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata'' lets developers to simply specify the metadata information strictly needed for the generation, relying on internal logic for generic behavior.
 +
===Instantiating===
 +
A GcubeISOMetadata instance should be generated for each publishing request, but this behavior depends on the caller application logic.
 +
At construction time, common information fetched from the gCube IS is loaded. Queries to IS are done via the [[ic-client]], so be sure that a proper scope is setted via ''org.gcube.common.scope.api.ScopeProvider''.
 +
Loaded configuration is represented by instances of the class ''org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration'' see [[#EnvironmentConfiguration class]].
 +
<source lang="java">
 +
 
 +
import org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration;
 +
import org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata;
 +
import org.gcube.common.scope.api.ScopeProvider;
 +
....
 +
ScopeProvider.instance.set(...);
 +
GcubeISOMetadata meta=new GcubeISOMetadata();
 +
EnvironmentConfiguration configuration = meta.getConfig();
 +
System.out.println("Current configuration is "+configuration);
 +
</source>
 +
 
 +
===Filling parameters===
 +
 
 +
The GcubeISOMetadata class exposes setter/add methods to let users specify metadata information. The following is a list of attributes that can be set along with their cardinality. Attributes which cardinality can be more then 1 are setted via the related ''addXXX()'' method, while ''setXXX()'' methods are provided for the other ones.
 +
 
 +
{|border="1" cellpadding="5" cellspacing="0"
 +
!Attribute Name
 +
!Type
 +
!Cardinality
 +
|-
 +
|User
 +
|java.lang.String
 +
| 1
 +
 
 +
 
 +
|-
 +
|Title
 +
|java.lang.String
 +
|1
 +
 
 +
|-
 +
|Date
 +
|java.lang.Date
 +
|1
 +
 
 +
|-
 +
|Presentation Form
 +
|org.opengis.metadata.citation.PresentationForm
 +
|1
 +
 
 +
|-
 +
|Abstract
 +
|java.lang.String
 +
|1
 +
 
 +
|-
 +
|Purpose
 +
|java.lang.String
 +
|1
 +
 
 +
|-
 +
|Credits
 +
|java.lang.String
 +
|1..N
 +
 
 +
|-
 +
|Descriptive Keyword
 +
|java.lang.String
 +
|1..N
 +
 
 +
|-
 +
|Topic Category
 +
|org.opengis.metadata.identification.TopicCategory
 +
|1..N
 +
 
 +
|-
 +
|Extent
 +
|org.geotoolkit.metadata.iso.extent.DefaultExtent
 +
|1
 +
 
 +
|-
 +
|Geometric Object Type
 +
|org.opengis.metadata.spatial.GeometricObjectType
 +
|1
 +
 
 +
|-
 +
|Geometry Count
 +
|int
 +
|1
 +
 
 +
|-
 +
|Topology Level
 +
|org.opengis.metadata.spatial.TopologyLevel
 +
|1
 +
 
 +
|-
 +
|Resolution
 +
|double
 +
|1
 +
 
 +
|-
 +
|Graphic Overview
 +
|String
 +
|0..N
 +
|}
 +
 
 +
The following snippets shows how this parameters are set :
 +
 
 +
<source lang="java">
 +
import org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration;
 +
import org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata;
 +
import org.gcube.spatial.data.geonetwork.iso.Thesaurus;
 +
import org.geotoolkit.metadata.iso.extent.DefaultExtent;
 +
import org.opengis.metadata.citation.PresentationForm;
 +
import org.opengis.metadata.identification.TopicCategory;
 +
import org.opengis.metadata.spatial.GeometricObjectType;
 +
import org.opengis.metadata.spatial.TopologyLevel;
 +
 
 +
...
 +
 
 +
GcubeISOMetadata meta=new GcubeISOMetadata();
 +
//Setter methods
 +
meta.setAbstractField(...);
 +
meta.setCreationDate(...);
 +
meta.setExtent(DefaultExtent.WORLD);
 +
meta.setGeometricObjectType(GeometricObjectType.SURFACE);
 +
meta.setPresentationForm(PresentationForm.MAP_DIGITAL);
 +
meta.setPurpose(...);
 +
meta.setResolution(...);
 +
meta.setTitle(..);
 +
meta.setTopologyLevel(TopologyLevel.GEOMETRY_ONLY);
 +
meta.setUser(...);
 +
 
 +
//Add methods
 +
meta.addCredits(..);
 +
meta.addGraphicOverview(...);
 +
 
 +
//Need to get keywords referred Thesaurus
 +
Thesaurus generalThesaurus=meta.getConfig().getThesauri().get(...);
 +
meta.addKeyword(..., generalThesaurus);
 +
meta.addKeyword(..., generalThesaurus);
 +
 
 +
 
 +
meta.addTopicCategory(TopicCategory.BIOTA);
 +
</source>
 +
 
 +
===Getting the metadata===
 +
Once the metadata information have been set to the GCubeISOMetadata instance, the caller can obtain the metadata to publish just by calling its '''public org.opengis.metadata.Metadata getMetadata()''' method. In case any mandatory value is missing a ''MissingInformationException'' is thrown.
 +
 
 +
<source lang="java">
 +
ScopeProvider.instance.set("/gcube/devsec");
 +
GcubeISOMetadata meta=new GcubeISOMetadata();
 +
 
 +
// Set information
 +
....
 +
 
 +
// Print out the metadata
 +
XML.marshal(meta.getMetadata(),System.out);
 +
 
 +
</source>
 +
 
 +
===Extending default behaviour===
 +
''GCubeISOMetadata'' class can be extended in order to enhance its purpose and behaviour.
 +
In the following example we define our ''MyApplicationIsoMetadata'' class in order to :
 +
 
 +
* Automatically set application default values when instatiating;
 +
* Add new mandatory fields to generate data quality information to our metadata, via :
 +
** Adding new member to our class
 +
** Override of protected method '''checkConstraints'''
 +
** Override of public method '''getMetadata()'''
 +
 
 +
 
 +
<source lang="java">
 +
 
 +
import org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata;
 +
import org.gcube.spatial.data.geonetwork.iso.MissingInformationException;
 +
import org.opengis.metadata.Metadata;
 +
 
 +
//Extends org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata
 +
public class MyApplicationIsoMetadata extends GcubeISOMetadata {
 +
 +
//We want this citation to be automatically added to credits
 +
private static final String applicationCitation="....";
 +
 
 +
 +
//Our mandatory field
 +
private String mandatoryField=null;
 +
 +
public MyApplicationIsoMetadata() throws Exception {
 +
//Let the super class initialize itself
 +
super();
 +
//Let's add our citation to credits
 +
this.getCredits().add(applicationCitation);
 +
}
 +
 +
@Override
 +
protected void checkConstraints() throws MissingInformationException {
 +
// We let the super class to perform its checks before continuing
 +
super.checkConstraints();
 +
// Custom check against mandatoryField
 +
if(mandatoryField==null) throw new MissingInformationException();
 +
}
 +
 +
@Override
 +
public Metadata getMetadata() throws URISyntaxException,MissingInformationException {
 +
Metadata toReturn=super.getMetadata();
 +
//We set our mandatory field to the metadata
 +
                ........
 +
return toReturn;
 +
}
 +
 
 +
public String getMandatoryField() {
 +
return mandatoryField;
 +
}
 +
 
 +
public void setMandatoryField(String mandatoryField) {
 +
this.mandatoryField = mandatoryField;
 +
}
 +
}
 +
</source>
 +
 
 +
==EnvironmentConfiguration class==
 +
Common metadata values (i.e. project citation, project name etc.) are loaded from a gCube generic resource that must be accessible in the current scope.
 +
The given generic resource's body must contain an XML Serialization of ''org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration'' class.
 +
 
 +
===Configuration retrieval===
 +
The gcube generic resource is found submitting a query to the [[ic-client]] with the following parameters.
 +
 
 +
*Secondary Type [default value = '''ISO''']
 +
*Resource Name [default value = '''MetadataConstants''']
 +
 
 +
The Generic resource is cached to avoid overhead in querying the IS.
 +
The cache TTL, along with the query parameters value can be configured by editing the [[#Properties file]].
 +
 
 +
===Configure environment===
 +
''Geonetwork'' library allows administrator to easily configure their environment constants. The following snippets shows how :
 +
<source lang="java">
 +
import org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration;
 +
import org.gcube.common.scope.api.ScopeProvider;
 +
import org.gcube.common.resources.gcore.GenericResource;
 +
....
 +
//Create the configuration
 +
EnvironmentConfiguration config=new EnvironmentConfiguration();
 +
//Set all the values in the configuration
 +
...
 +
//We set the scope where to Publish the configuration
 +
ScopeProvider.instance.set(...);
 +
//Let's actually publish the configuration
 +
GenericResource res=config.publish();
 +
//Just some output log here
 +
String id=res.id();
 +
System.out.println("Published configuration [res ID = "+id+"] under scope "+ScopeProvider.instance.get());
 +
</source>
 +
 
 +
The method ''config.publish()'' creates and publishes a generic resource with the configured name and secondary type (see [[#Properties file]]).
 +
 
 +
===Configuration parameters===
 +
{|border="1" cellpadding="5" cellspacing="0"
 +
!Property
 +
!Type
 +
!Cardinality
 +
 
 +
|-
 +
|colspan="3" bgcolor=lightgrey |'''Protocol declarations'''
 +
|-
 +
|WMS protocol||java.lang.String||0..1
 +
|-
 +
|WFS protocol||java.lang.String||0..1
 +
|-
 +
|WCS protocol||java.lang.String||0..1
 +
|-
 +
|HTTP protocol||java.lang.String||0..1
 +
 
 +
|-
 +
|colspan="3" bgcolor=lightgrey |'''Project citation'''
 +
|-
 +
|Project Name||java.lang.String||0..1
 +
|-
 +
|Project Citation||java.lang.String||0..1
 +
 
 +
 
 +
|-
 +
|colspan="3" bgcolor=lightgrey |'''Distributor Role'''
 +
|-
 +
|Distributor individual name||java.lang.String||0..1
 +
|-
 +
|Distributor e-mail||java.lang.String||0..1
 +
|-
 +
|Distributor organization name||java.lang.String||0..1
 +
|-
 +
|Distributor web site||java.lang.String||0..1
 +
 
 +
 
 +
|-
 +
|colspan="3" bgcolor=lightgrey |'''Provider Role'''
 +
|-
 +
|Provider individual name||java.lang.String||0..1
 +
|-
 +
|Provider e-mail||java.lang.String||0..1
 +
|-
 +
|Provider organization name||java.lang.String||0..1
 +
|-
 +
|Provider web site||java.lang.String||0..1
 +
 
 +
|-
 +
|colspan="3" bgcolor=lightgrey |'''License'''
 +
|-
 +
|License||java.lang.String||0..1
 +
 
 +
|-
 +
|colspan="3" bgcolor=lightgrey |'''Thesauri Map'''
 +
|-
 +
|Theaurus||org.gcube.spatial.data.geonetwork.iso.Thesaurus||0..N
 +
|}
 +
 
 +
==Thesaurus class==
 +
''Thesaurus'' class represents a thesaurus declaration for a given keyword set in ISO metadata (see [[ISO 19115:2003/19139]]).
 +
 
 +
The following is the list of its members.
 +
{|border="1" cellpadding="5" cellspacing="0"
 +
!Property
 +
!Type
 +
!Cardinality
 +
 
 +
|-
 +
|Type||org.opengis.metadata.identification.KeywordType||1
 +
|-
 +
|Title||java.lang.String||1
 +
|-
 +
|Citation date||java.util.Date||1
 +
|-
 +
|Citation description||java.lang.String||0..1
 +
|-
 +
|Citation uri||java.lang.String||0..1
 +
|-
 +
|Citation organization||java.lang.String||0..1
 +
|-
 +
|Authored || boolean||1
 +
 
 +
|}
 +
 
 +
=Example Code=
 
====Querying for metadata====
 
====Querying for metadata====
 
<source lang="Java">
 
<source lang="Java">
Line 136: Line 602:
 
...
 
...
 
//Get the result representation
 
//Get the result representation
GNSearchResponse resp=gn.query(req);
+
GNSearchResponse resp=reader.query(req);
 
...
 
...
 
//Iterate through results and access found metadata  
 
//Iterate through results and access found metadata  
Line 144: Line 610:
 
}
 
}
 
</source>
 
</source>
 +
 
====Publishing metadata====
 
====Publishing metadata====
 
<source lang="java">
 
<source lang="java">
Line 161: Line 628:
 
...
 
...
 
//Configure publish request
 
//Configure publish request
GNInsertConfiguration config=new GNInsertConfiguration("5", "datasets", "_none_", true);
+
GNInsertConfiguration config=publisher..getCurrentUserConfiguration("dataset", "_none_");
...
+
 
 +
 
 
//Publish Metadata object
 
//Publish Metadata object
 
Metadata toPublish=....
 
Metadata toPublish=....
Line 171: Line 639:
 
long publishedFileId=publisher.insertMetadata(config, myMetadataFile);
 
long publishedFileId=publisher.insertMetadata(config, myMetadataFile);
 
</source>
 
</source>
 +
 +
====Publishing from 3.0.0====
 +
From '''3.0.0''' the library performs various checks on ''GNInsertConfiguration'' values. In order to publish with a valid configuration (compliant with gcube4.0.0 policies) users can and are encouraged to use the following snippet code instead of creating a new instance of the class ''GNInsertConfiguration''.
 +
<source lang="Java">
 +
...
 +
//Get the publisher
 +
GeoNetworkPublisher publisher=GeoNetwork.get();
 +
...
 +
//Cannot publish without logging in
 +
publisher.login(...);
 +
...
 +
//Get publish configuration
 +
GNInsertConfiguration config=publisher.getCurrentUserConfiguration("datasets", "_none_");
 +
...
 +
</source>
 +
 
====Change Metadata Privileges====
 
====Change Metadata Privileges====
 
<source lang="Java">
 
<source lang="Java">

Revision as of 16:08, 23 October 2019


A library to interact with GeoNetwork's REST Interface to publish/modify/delete and search for Metadata.The library is designed on top of geoserver-manager library, developed by GeoSolutions. Metadata objects managed by the library are compliant to standard specification ISO 19115:2003/19139. Default configuration of the library interacts exploits Featherweight Stack functionalities to discover geonetwork available in the infrastructure.

Module overview

The library is distributed as the artifact

<dependency>
  <groupId>org.gcube.spatial.data</groupId>
  <artifactId>geonetwork</artifactId>
  <version>...</version>
</dependency>


ISO 19115:2003 metadata compliance

Metadata objects used by the libraries implement GeoAPI interfaces, which are fully compliant to ISO 19115:2003/19139. Current implementation is based on GeoToolkit Metadata module.

Dependecies

The library declares these dependecies to external third parties artifacts

<dependency>
        <groupId>it.geosolutions</groupId>
	<artifactId>geonetwork-manager</artifactId>
	<version>1.1</version>
</dependency>
<dependency>
	<groupId>org.geotoolkit</groupId>
	<artifactId>geotk-metadata</artifactId>
	<version>3.20-geoapi-3.0</version>
</dependency>
<dependency>
	<groupId>org.w3c</groupId>
	<artifactId>dom</artifactId>
	<version>2.3.0-jaxb-1.0.6</version>
</dependency>
<dependency>
	<groupId>org.geotoolkit</groupId>
	<artifactId>geotk-referencing</artifactId>
	<version>3.20-geoapi-3.0</version>
</dependency>

Using the library

The library acts as a wrapper to the functionalities exposed by the geonetwork-manager library. The methods offered by the library are splitted in three different interfaces :

  • org.gcube.spatial.data.geonetwork.GeoNetworkReader : declares methods to access metadata stored in geonetwork
  • org.gcube.spatial.data.geonetwork.GeoNetworkPublisher : extends GeoNetworkReader, and declares methods to publish/update/delete metadata in geonetwork
  • org.gcube.spatial.data.geonetwork.GeoNetworkAdministration : extends GeoNetworkPublisher, and declares methods to manage users and groups on GeoNetwork (available from 3.0.0)


The class org.gcube.spatial.data.geonetwork.GeoNetwork offers two static members to obtain implementations of the above interfaces :

  • public static GeoNetworkAdministration get() throws Exception : uses the current settings of ConfigurationManager to get a Configuration implementation.
  • public static GeoNetworkAdministration get(Configuration config) : uses the passed Configuration implementation.

See #Configuration to get more information.


Changes in 3.0.0

Along with gcube 4.0, comes a new version of the library : 3.0.0. Basic usage of the library remains at most the same, even if some important feature have changed, thus some refactoring might be needed anyway. The following is a list of the main changes in the library, please refer to the rest of this page for more detailed information

  • Introduced GeoNetworkAdministration interface to manage groups and users on GeoNetwork
  • Configuration compliant with gcube 4.0.0 SDI publishing policies
  • Automatic generation of scope configuration if none is present
  • Improved publishing checks against current configuration
  • Improved model and faults management


User management

Library version 2.0

From version 2.0.0 the library refers to the guidelines stated in GeoNetwork administration in particular :

  • applications should publish their metadata in the current scope group
  • applications should publish as <SCOPE_PUBLIC_USER> metadata with scope visibility
  • applications should publish as <SCOPE_PRIVATE_USER> metadata with private (per user) visibility

Login

Unless the client calls the method public void login(LoginLevel level)throws AuthorizationException declared by GeoNetworkReader interface, all calls to geonetwork are sent without login thus :

  • queries return only public metadata
  • access to metadata with no public access will fail
  • methods which change the current geonetwork state will fail

The following LoginLevels are defined :

  • DEFAULT
  • SCOPE
  • PRIVATE

see #Configuration for details on how the related credentials are used.

Library Version 3.0

From version 3.0.0 the publication guidelines suggest that:

  • metadata that should be visible only inside the current scope  : use current scope's private group on GeoNetwork
  • metadata that should be visible in the current scope and in parent ones : use current scope's public group on GeoNetwork


Login

Unless the client calls the method public void login(LoginLevel level)throws AuthorizationException declared by GeoNetworkReader interface, all calls to geonetwork are sent without login thus :

  • queries return only public metadata
  • access to metadata with no public access will fail
  • methods which change the current geonetwork state will fail

Please note that by calling login method, the user specifies publishing behavior according to the current scope configuration involving the target group to use:

  • DEFAULT : uses <SCOPE_USER> and publish into the default publishing group for the current scope;
  • SCOPE : uses <SCOPE_USER> and publish into the <PUBLIC_GROUP> for the current scope;
  • PRIVATE : uses <SCOPE_USER> and publish into the <PRIVATE_GROUP> for the current scope;
  • ADMIN : uses administration privileges, thus no check/ constraint are performed;
  • CKAN : uses read-only ckan user for that scope;

see #Configuration for details on how the related credentials are used.

Geonetwork instances discovery

The geonetwork library relies on instances of org.gcube.spatial.data.geonetwork.configuration.Configuration interface in order to retrieve needed information to interact with geonetwork REST interface. The following snippets show how to set Configuration implementation to be used by the library :

Implicit Configuration

Using ConfigurationManager to set the class implementing Configuration. Every following instantiation of GeoNetworkReader will use a new object of the given Configuration implementing class.

//MyConfiguration must implement org.gcube.spatial.data.geonetwork.configuration.Configuration
ConfigurationManager.setConfiguration(MyConfiguration.class);
...
GeoNetworkReader    reader1=GeoNetwork.get();
...
GeoNetworkReader    reader2=GeoNetwork.get();
...
GeoNetworkPublisher publisher1=GeoNetwork.get();

Explicit Configuration

Explicit Configuration implementation declaration.

//MyConfiguration must implement org.gcube.spatial.data.geonetwork.configuration.Configuration
GeoNetworkReader    reader1=GeoNetwork.get(new MyConfiguration());
...
GeoNetworkReader    reader2=GeoNetwork.get(new MyConfiguration());
...
GeoNetworkPublisher publisher1=GeoNetwork.get(new MyConfiguration());

Default Configuration

By default, the library uses implementation of the class org.gcube.spatial.data.geonetwork.configuration.DefaultConfiguration. This implementation is based on the ic-client, and relies on the gCube information system in order to get the needed parameters to interact with geonetwork REST interface. The convention used by this implementation are the one stated in GeoNetwork Runtime Resource Definition.

Changes in 3.0.0

From version 3.0.0 the interface org.gcube.spatial.data.geonetwork.configuration.Configuration has been completely changed in order to manage gcube4.0.0 SDI publishing policies as described in GeoNetwork Runtime Resource Definition.

Metadata generation facilities

Instances of org.opengis.metadata.Metadata interface can be generated in very different ways. However, we identified a common set of information which every application should include in its published metadata. Providing a common way to generate these metadata entry aims to :

Metadata Descriptor

org.gcube.spatial.data.geonetwork.iso.tpl.MetadataDescriptor is a Java class representing a simplified version of the ISO XML Model. The underlying logic will apply the model to XML templates in order to enforce the production of INSPIRE -compliant metadata throughout the infrastructure.

Usage

Following is an example snippet showing how to properly instantiate the class

MetadataDescriptor desc=new MetadataDescriptor();
 
//Setting Title
desc.setTitle("...");
 
//Setting Identifier		
desc.setUUIDIdentifier(UUID.randomUUID().toString());
 
//Setting Purpose		
desc.setPurpose("...");
 
//Setting Abstract
desc.setAbstractField("...");
 
//Setting Credits		
desc.addCredits("...");	
 
// Setting Responsible Parties
desc.addResponsibleParty(new ResponsibleParty("Author name","Author organization",
		ResponsiblePartyRole.AUTHOR,new Contact("author.mail@some.place.com","www.myorganization.com")));
 
//Setting Dataset Creation Time		
desc.setCreationTime(new GregorianCalendar().getTime());
 
 
//Setting Spatial Representation
VectorRepresentation representation=new VectorRepresentation(
		TopologyLevel.GEOMETRY_ONLY, 1000, GeometricObjectType.POINT);
desc.setSpatialRepresentation(representation);
 
//Setting INSPIRE THEME(s)
desc.addKeywordSet(new KeywordSet(
				KeywordType.THEME,
				Collections.singleton("Species distribution"),
				Thesaurus.INSPIRE_THEMES));
 
//Setting arbitrary keywords
desc.addKeywordSet(new KeywordSet(Collections.singleton("...")));
 
//Setting Extent
desc.getExtent().addGeographicExtent(BoundingBox.WORLD_EXTENT);
 
//Utility method for setting GeoServer Distribution Info
desc.setGeoServerDistributionInfo("http://geoserver.d4science.org/geoserver", 
		"ws","wmpa", "speciesProb", "EPSG:4326",BoundingBox.WORLD_EXTENT);
 
//Setting Spatial Resolution		
desc.setSpatialResolution(0.5d);
 
//Setting Usage and Access Constraints
desc.setConstraints(new ResourceConstraints("...", 
		new LegalConstraints(RestrictionCode.LICENSE,"CC-BY-SA"), 
		new LegalConstraints(RestrictionCode.LICENSE,"CC-BY-SA")));
 
//Setting Topic Category
desc.addTopicCategory(TopicCategory.ENVIRONMENT);
 
//Setting the Lineage Statement
desc.setLineageStatement("...");
 
//Obtaining the metadata file		
File metaFile=ISOMetadataByTemplate.createXML(desc);

GcubeISOMetadata class

 Please note that this class is deprecated and won't be supported in upcoming versions. See the MetadataDescriptor section in this page.

The utility class org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata lets developers to simply specify the metadata information strictly needed for the generation, relying on internal logic for generic behavior.

Instantiating

A GcubeISOMetadata instance should be generated for each publishing request, but this behavior depends on the caller application logic. At construction time, common information fetched from the gCube IS is loaded. Queries to IS are done via the ic-client, so be sure that a proper scope is setted via org.gcube.common.scope.api.ScopeProvider. Loaded configuration is represented by instances of the class org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration see #EnvironmentConfiguration class.

import org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration;
import org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata;
import org.gcube.common.scope.api.ScopeProvider;
....
ScopeProvider.instance.set(...);
GcubeISOMetadata meta=new GcubeISOMetadata();
EnvironmentConfiguration configuration = meta.getConfig();
System.out.println("Current configuration is "+configuration);

Filling parameters

The GcubeISOMetadata class exposes setter/add methods to let users specify metadata information. The following is a list of attributes that can be set along with their cardinality. Attributes which cardinality can be more then 1 are setted via the related addXXX() method, while setXXX() methods are provided for the other ones.

Attribute Name Type Cardinality
User java.lang.String 1


Title java.lang.String 1
Date java.lang.Date 1
Presentation Form org.opengis.metadata.citation.PresentationForm 1
Abstract java.lang.String 1
Purpose java.lang.String 1
Credits java.lang.String 1..N
Descriptive Keyword java.lang.String 1..N
Topic Category org.opengis.metadata.identification.TopicCategory 1..N
Extent org.geotoolkit.metadata.iso.extent.DefaultExtent 1
Geometric Object Type org.opengis.metadata.spatial.GeometricObjectType 1
Geometry Count int 1
Topology Level org.opengis.metadata.spatial.TopologyLevel 1
Resolution double 1
Graphic Overview String 0..N

The following snippets shows how this parameters are set :

import org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration;
import org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata;
import org.gcube.spatial.data.geonetwork.iso.Thesaurus;
import org.geotoolkit.metadata.iso.extent.DefaultExtent;
import org.opengis.metadata.citation.PresentationForm;
import org.opengis.metadata.identification.TopicCategory;
import org.opengis.metadata.spatial.GeometricObjectType;
import org.opengis.metadata.spatial.TopologyLevel;
 
...
 
GcubeISOMetadata meta=new GcubeISOMetadata();
//Setter methods
meta.setAbstractField(...);
meta.setCreationDate(...);
meta.setExtent(DefaultExtent.WORLD);
meta.setGeometricObjectType(GeometricObjectType.SURFACE);
meta.setPresentationForm(PresentationForm.MAP_DIGITAL);
meta.setPurpose(...);
meta.setResolution(...);
meta.setTitle(..);
meta.setTopologyLevel(TopologyLevel.GEOMETRY_ONLY);
meta.setUser(...);						
 
//Add methods
meta.addCredits(..);
meta.addGraphicOverview(...);
 
//Need to get keywords referred Thesaurus
Thesaurus generalThesaurus=meta.getConfig().getThesauri().get(...);		
meta.addKeyword(..., generalThesaurus);
meta.addKeyword(..., generalThesaurus);
 
 
meta.addTopicCategory(TopicCategory.BIOTA);

Getting the metadata

Once the metadata information have been set to the GCubeISOMetadata instance, the caller can obtain the metadata to publish just by calling its public org.opengis.metadata.Metadata getMetadata() method. In case any mandatory value is missing a MissingInformationException is thrown.

ScopeProvider.instance.set("/gcube/devsec");
GcubeISOMetadata meta=new GcubeISOMetadata();
 
// Set information
....
 
// Print out the metadata
XML.marshal(meta.getMetadata(),System.out);

Extending default behaviour

GCubeISOMetadata class can be extended in order to enhance its purpose and behaviour. In the following example we define our MyApplicationIsoMetadata class in order to :

  • Automatically set application default values when instatiating;
  • Add new mandatory fields to generate data quality information to our metadata, via :
    • Adding new member to our class
    • Override of protected method checkConstraints
    • Override of public method getMetadata()


import org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata;
import org.gcube.spatial.data.geonetwork.iso.MissingInformationException;
import org.opengis.metadata.Metadata;
 
//Extends org.gcube.spatial.data.geonetwork.iso.GcubeISOMetadata
public class MyApplicationIsoMetadata extends GcubeISOMetadata {
 
	//We want this citation to be automatically added to credits
	private static final String applicationCitation="....";
 
 
	//Our mandatory field
	private String mandatoryField=null;
 
	public MyApplicationIsoMetadata() throws Exception {
		//Let the super class initialize itself
		super();
		//Let's add our citation to credits
		this.getCredits().add(applicationCitation);
	}
 
	@Override
	protected void checkConstraints() throws MissingInformationException {
		// We let the super class to perform its checks before continuing
		super.checkConstraints();
		// Custom check against mandatoryField
		if(mandatoryField==null) throw new MissingInformationException();
	}
 
	@Override
	public Metadata getMetadata() throws URISyntaxException,MissingInformationException {
		Metadata toReturn=super.getMetadata();
		//We set our mandatory field to the metadata
                ........
		return toReturn;
	}
 
	public String getMandatoryField() {
		return mandatoryField;
	}
 
	public void setMandatoryField(String mandatoryField) {
		this.mandatoryField = mandatoryField;
	}
}

EnvironmentConfiguration class

Common metadata values (i.e. project citation, project name etc.) are loaded from a gCube generic resource that must be accessible in the current scope. The given generic resource's body must contain an XML Serialization of org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration class.

Configuration retrieval

The gcube generic resource is found submitting a query to the ic-client with the following parameters.

  • Secondary Type [default value = ISO]
  • Resource Name [default value = MetadataConstants]

The Generic resource is cached to avoid overhead in querying the IS. The cache TTL, along with the query parameters value can be configured by editing the #Properties file.

Configure environment

Geonetwork library allows administrator to easily configure their environment constants. The following snippets shows how :

import org.gcube.spatial.data.geonetwork.iso.EnvironmentConfiguration;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.resources.gcore.GenericResource;
....
//Create the configuration
EnvironmentConfiguration config=new EnvironmentConfiguration();
//Set all the values in the configuration
...
//We set the scope where to Publish the configuration
ScopeProvider.instance.set(...);
//Let's actually publish the configuration
GenericResource res=config.publish();
//Just some output log here
String id=res.id();
System.out.println("Published configuration [res ID = "+id+"] under scope "+ScopeProvider.instance.get());

The method config.publish() creates and publishes a generic resource with the configured name and secondary type (see #Properties file).

Configuration parameters

Property Type Cardinality
Protocol declarations
WMS protocol java.lang.String 0..1
WFS protocol java.lang.String 0..1
WCS protocol java.lang.String 0..1
HTTP protocol java.lang.String 0..1
Project citation
Project Name java.lang.String 0..1
Project Citation java.lang.String 0..1


Distributor Role
Distributor individual name java.lang.String 0..1
Distributor e-mail java.lang.String 0..1
Distributor organization name java.lang.String 0..1
Distributor web site java.lang.String 0..1


Provider Role
Provider individual name java.lang.String 0..1
Provider e-mail java.lang.String 0..1
Provider organization name java.lang.String 0..1
Provider web site java.lang.String 0..1
License
License java.lang.String 0..1
Thesauri Map
Theaurus org.gcube.spatial.data.geonetwork.iso.Thesaurus 0..N

Thesaurus class

Thesaurus class represents a thesaurus declaration for a given keyword set in ISO metadata (see ISO 19115:2003/19139).

The following is the list of its members.

Property Type Cardinality
Type org.opengis.metadata.identification.KeywordType 1
Title java.lang.String 1
Citation date java.util.Date 1
Citation description java.lang.String 0..1
Citation uri java.lang.String 0..1
Citation organization java.lang.String 0..1
Authored boolean 1

Example Code

Querying for metadata

import it.geosolutions.geonetwork.util.GNSearchRequest;
import it.geosolutions.geonetwork.util.GNSearchResponse;
 
import org.opengis.metadata.Metadata;
 
import org.gcube.spatial.data.geonetwork.GeoNetwork;
import org.gcube.spatial.data.geonetwork.GeoNetworkReader;
...
// Get the reader
GeoNetworkReader reader=GeoNetwork.get();
...
//Configure search request
GNSearchRequest req=new GNSearchRequest();
req.addParam(GNSearchRequest.Param.any,".....");
req.addConfig(GNSearchRequest.Config.similarity, "1");
...
//Get the result representation
GNSearchResponse resp=reader.query(req);
...
//Iterate through results and access found metadata 
for(GNSearchResponse.GNMetadata metadata:resp){
Metadata meta=reader.getById(metadata.getUUID());
...
}

Publishing metadata

import it.geosolutions.geonetwork.util.GNInsertConfiguration;
 
import org.opengis.metadata.Metadata;
 
import org.gcube.spatial.data.geonetwork.GeoNetwork;
import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher;
import org.gcube.spatial.data.geonetwork.LoginLevel;
...
//Get the publisher
GeoNetworkPublisher publisher=GeoNetwork.get();
...
//Cannot publish without logging in
publisher.login(...);
...
//Configure publish request
GNInsertConfiguration config=publisher..getCurrentUserConfiguration("dataset", "_none_");
 
 
//Publish Metadata object
Metadata toPublish=....
long publishedObjectId=publisher.insertMetadata(config, toPublish);
...
//Publish Metadata file
File myMetadataFile=...
long publishedFileId=publisher.insertMetadata(config, myMetadataFile);

Publishing from 3.0.0

From 3.0.0 the library performs various checks on GNInsertConfiguration values. In order to publish with a valid configuration (compliant with gcube4.0.0 policies) users can and are encouraged to use the following snippet code instead of creating a new instance of the class GNInsertConfiguration.

...
//Get the publisher
GeoNetworkPublisher publisher=GeoNetwork.get();
...
//Cannot publish without logging in
publisher.login(...);
...
//Get publish configuration
GNInsertConfiguration config=publisher.getCurrentUserConfiguration("datasets", "_none_");
...

Change Metadata Privileges

import it.geosolutions.geonetwork.util.GNPriv;
import it.geosolutions.geonetwork.util.GNPrivConfiguration;
 
import org.gcube.spatial.data.geonetwork.GeoNetwork;
import org.gcube.spatial.data.geonetwork.GeoNetworkPublisher;
import org.gcube.spatial.data.geonetwork.LoginLevel;
...
//Get the publisher
GeoNetworkPublisher publisher=GeoNetwork.get();
...
//Cannot modify privileges without login
publisher.login(...);
...
//Configure privileges
GNPrivConfiguration privConfig=new GNPrivConfiguration();
privConfig.addPrivileges(publisher.getConfiguration().getScopeGroup(),EnumSet.of(GNPriv.VIEW));
...
//Set the privileges
long myMetadataId=...
publisher.setPrivileges(myMetadataId, privConfig);