Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions doc/en/user/source/community/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,4 @@ officially part of the GeoServer releases. They are however built along with the
onelogin/index
wmts-multidimensional/index
notification/index
opensearch-eo/index
s3-geotiff/index
nsg-profile/index
212 changes: 212 additions & 0 deletions doc/en/user/source/community/nsg-profile/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
.. _community_nsg_profile:

NSG Profile
===========
NSG Profile introduces a new operation for WFS 2.0.2 named PageResults. This operation will allow clients to access paginated results using random positions.

The current WFS 2.0.2 OGC specification defines a basic pagination support that can been used to navigate through features responses results.

Pagination is activated when parameters count and startIndex are used in the query, for example:

::

http://<host>/geoserver/ows?service=WFS&version=2.0.0&request=GetFeature&typeNames=topp%3Atasmania_roads&count=5&startIndex=0



In this case each page will contain five features.
The returned feature collection will have the next and previous attributes which will contain an URL that will allow clients to navigate through the results pages, i.e. previous page and next page:

::

<wfs:FeatureCollection
previous="http://localhost:8080/geoserver/wfs?
REQUEST=GetFeature&
VERSION=2.0.0&
TYPENAMES=topp:tasmania_roads&
SERVICE=WFS&
COUNT=2&
STARTINDEX=0"
next="http://localhost:8080/geoserver/wfs?
REQUEST=GetFeature&
VERSION=2.0.0&
TYPENAMES=topp:tasmania_roads&
SERVICE=WFS&
COUNT=2&
STARTINDEX=4"
numberMatched="14"
numberReturned="2">


This means that this type of navigation will always be sequential, if the client is showing page two and the user wants to see page five the client will have to:

#. request page three and use the provided next URL to retrieve page four
#. request page four and use the provided next URI to retrieve page five

This is not an ideal solution to access random pages, which is common action.
PageResults operation will improve this by allowing clients to request random pages directly.

Installing the extension
------------------------

#. Download the NSG Profile extension from the nightly GeoServer community module builds.

#. Place the JARs into the ``WEB-INF/lib`` directory of the GeoServer installation.

Configure the extension
-----------------------

The root directory inside the GeoServer data directory for the nsg-profile community module is named nsg-profile and all the configurations properties are stored in a file named **configuration.properties**.

All configuration properties are changeable at runtime, which means that if a property is updated the module take it into account.

When the application starts if no configuration file exists one with the default values is created.

The GetFeature requests representations associated with an index result type is serialized and stored in the file system in a location that is configurable.

The default location, relative to the GeoServer data directory, is nsg-profie/resultSets.

The GetFeature request to resultSetID mapping is stored by default in an H2 DB in nsg-profie/resultSets folder; for details on database configuration see `GeoTools JDBCDataStore syntax <http://docs.geotools.org/stable/userguide/library/jdbc/datastore.html>`_

The configuration properties are the follows:


.. list-table::
:widths: 20 30 50
:header-rows: 1

* - Name
- Default Value
- Description
* - resultSets.storage.path
- ${GEOSERVER_DATA_DIR}/nsg-profile/resultSets
- Path where to store GetFeature requests representations
* - resultSets.timeToLive
- 600
- How long a GetFeature request should be maintained by the server (in seconds)
* - resultSets.db.dbtype
- h2
- DB type used to store GetFeature request to resultSetID mapping
* - resultSets.db.database
- ${GEOSERVER_DATA_DIR}/nsg-profile/db/resultSets
- path where to store GetFeature request to resultSetID mapping
* - resultSets.db.user
- sa
- database user username
* - resultSets.db.password
- sa
- database user password
* - resultSets.db.port
-
- database port to connect to
* - resultSets.db.schema
-
- database schema
* - resultSets.db.host
-
- server to connect to


Index Result Type
-----------------
The **index result type** extends the WFS **hits result type** by adding an extra attribute named **resultSetID** to the response.
The **resultSetID** attribute can then be used by the **PageResults operation** to navigate randomly through the results.

A GetFeature request that uses the index result type should look like this:

::

http://<host>/geoserver/ows?service=WFS&version=2.0.0&request=GetFeature&typeNames=topp%3Atasmania_roads&resultType=index


The response of a GetFeature operation when the index result type is used should look like this:

::

<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection
numberMatched="14"
numberReturned="0"
resultSetID="ef35292477a011e7b5a5be2e44b06b34"
xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:ows="http://www.opengis.net/ows/1.1"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs/2.0
http://schemas.opengis.net/wfs/2.0/wfs.xsd"/>

The **resultSetID** is an unique identifier that identifies the original request.

Clients will use the **resultSetID** with the PageResults operation to reference the original request.

If pagination is used, the previous and next attributes should appear as in hits result type request.

PageResults Operation
---------------------

The **PageResults operation** allows clients to query random positions of an existing result set (stored GetFeature request) that was previously created using the **index result type** request.

The available parameters are this ones:

.. list-table::
:widths: 40 20 40
:header-rows: 1

* - Name
- Mandotry
- Default Value
* - service
- YES
- WFS
* - version
- YES
- 2.0.2
* - request
- YES
- PageResults
* - resultSetID
- YES
-
* - startIndex
- NO
- 0
* - count
- NO
- 10
* - outputFormat
- NO
- application/gml+xml; version=3.2
* - resultType
- NO
- results
* - timeout
- NO
- 300


The two parameters that are not already supported by the GetFeature operation are the **resultSetID** parameter and the **timeout** parameter.

#. The **resultSetID** parameter should reference an existing result set (stored GetFeature request).

A typical PageResults request will look like this:

::

http://<host>/geoserver/ows?service=WFS&version=2.0.2&request=PageResults&resultSetID=ef35292477a011e7b5a5be2e44b06b34&startIndex=5&count=10&outputFormat=application/gml+xml; version=3.2&resultType=results


This looks like a GetFeature request where the **query expression was substituted by the resultSetID parameter**.

#. The **timeout** parameter is not implemented yet.

The following parameters of index request are override using the ones provided with the PageResults operation or the default values:

#. startIndex
#. count
#. outputFormat
#. resultType

and finally the GetFeature response is returned.
92 changes: 92 additions & 0 deletions src/community/nsg-profile/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.geoserver</groupId>
<artifactId>community</artifactId>
<version>2.12-SNAPSHOT</version>
</parent>
<groupId>org.geoserver.community</groupId>
<artifactId>gs-nsg-profile</artifactId>
<packaging>jar</packaging>
<name>NSG Profile</name>
<dependencies>
<!-- geoserver dependencies -->
<dependency>
<groupId>org.geoserver</groupId>
<artifactId>gs-wfs</artifactId>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-core</artifactId>
</dependency>
<!-- geotools dependencies -->
<dependency>
<groupId>org.geotools.jdbc</groupId>
<artifactId>gt-jdbc-h2</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- geoserver tests dependencies -->
<dependency>
<groupId>org.geoserver</groupId>
<artifactId>gs-main</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geoserver</groupId>
<artifactId>gs-wfs</artifactId>
<classifier>tests</classifier>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.geoserver.web</groupId>
<artifactId>gs-web-core</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<!-- other tests dependencies -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.html</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
</project>

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/

package org.geoserver.nsg.pagination.random;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.geoserver.platform.resource.Resource;
import org.geotools.data.DataStore;

/**
*
* Class used to store the index result type configuration managed by {@link IndexInitializer}
*
* @author sandr
*
*/
public class IndexConfiguration {

private DataStore currentDataStore;

private Resource storageResource;

private Long timeToLiveInSec = 600l;

private Map<String, Object> currentDataStoreParams;

/**
* Store the DB parameters and the relative {@link DataStore}
*
* @param currentDataStoreParams
* @param currentDataStore
*/
public void setCurrentDataStore(Map<String, Object> currentDataStoreParams,
DataStore currentDataStore) {
this.currentDataStoreParams = currentDataStoreParams;
this.currentDataStore = currentDataStore;
}

/**
* Store the reference to resource used to archive the serialized GetFeatureRequest
*
* @param storageResource
*/
public void setStorageResource(Resource storageResource) {
this.storageResource = storageResource;
}

/**
* Store the value of time to live of stored GetFeatureRequest
*
* @param timeToLive
* @param timeUnit
*/
public void setTimeToLive(Long timeToLive, TimeUnit timeUnit) {
this.timeToLiveInSec = timeUnit.toSeconds(timeToLive);
}

public DataStore getCurrentDataStore() {
return currentDataStore;
}

public Map<String, Object> getCurrentDataStoreParams() {
return currentDataStoreParams;
}

public Resource getStorageResource() {
return storageResource;
}

public Long getTimeToLiveInSec() {
return timeToLiveInSec;
}

}
Loading