Skip to content

Commit

Permalink
Introduce Conformance API to configure OGCAPI Features (geoserver#8014)
Browse files Browse the repository at this point in the history
* APIConformance outline
* Outline ConformanceAdminPanel
* Update APIConformance with OGC Standard Level language
  This repalce status and provides concepts such as COMMUNITY_STANDARD and RETIRED_STANDARD
* Working AdminPagePanel for FeatureConformance, ECQLConformance and CQL2Conformance
* Add CQL2 to FeatureServiceAdminPanel
* Work on load/save
* Change to java beans configuration
* Save feature service configuration beans
* Visual feedback for conformance null / null / true / false state
* Use conformance to check parameters, provide warning when ignored
* Document new configuration options
* Fix checkstyle violation
* Revise based on feedabck and discussion
* Double check GMLSF2 is disabled to confirm CITE tests should pass
* Connect search, queryable and functions
* Adress feedback, fix headers, remove commeneded out code, remove duplication etc...
* Headers
* Use a three-state checkbox to preserve conformance default value
  The checkboxes in FeatureServiceAdminPanel would otherwise update
  the model value to false when it was originally null.

  This way the XStream persister will get the unchanged values as null
  instead of false.

* Address QA and formatting warnings

---------

Co-authored-by: Gabriel Roldan <gabriel.roldan@camptocamp.com>
  • Loading branch information
jodygarnett and groldan authored Nov 29, 2024
1 parent b987526 commit 3a8c52c
Show file tree
Hide file tree
Showing 29 changed files with 2,761 additions and 320 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 55 additions & 2 deletions doc/en/user/source/community/ogc-api/features/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ Installing the GeoServer OGC API Features module

#. On restart the services are listed at http://localhost:8080/geoserver


Docker use of OGC API Features module
-------------------------------------

#. The nightly Docker image supports the use of OGC API Feature:

.. parsed-literal::
docker pull docker.osgeo.org/geoserver:|release|
#. To run with OGC API Features:

.. parsed-literal::
docker run -it -p8080:8080 \\
--env INSTALL_EXTENSIONS=true \\
--env COMMUNITY_EXTENSIONS="ogcapi-features" \\
docker.osgeo.org/geoserver:|version|.x
#. The services are listed at http://localhost:8080/geoserver

Use of OGC API - Features service
---------------------------------

Expand Down Expand Up @@ -140,17 +161,49 @@ Defined by defined in by :ref:`config_contact`.
Configuration of OGC API - Features module
------------------------------------------
The service does not require any additional configuration to use. The service is configured using:
The service operates as an additional protocol for sharing vector data along side Web Feature Service.
The service is configured using:
* The existing :ref:`wfs` settings to define title, abstract, and output formats.
This is why the service page is titled ``GeoServer Web Feature Service`` by default.
* Feature Service conformances:
The OGC API Feature Service is modular, allowing you to enable/disable the functionality you wish to include.
By default stable Standards and Community Standards are enabled. If WFS is strict, only official Standards are enabled and community standards are disabled
The OpenAPI service description is manditory and may not be disabled.
The HTML and GeoJSON output formats are built-in and may not be disabled.
.. figure:: img/feature-service-configuration.png
Feature Service Configuration
* CQL2 Filter conformances.
Both the Text and JSON formats for CQL2 are available.
The built-in CQL2 functionality may not be disabled, and functionality that is not implemented yet may not be enabled.
.. figure:: img/cql2-configuration.png
CQL2 Filter configuration
* Control of ECQL Filter conformances
.. figure:: img/ecql-configuration.png
ECQL Filter configuration
* Built-in templates used for html generation
* Extra links can be added on a per-service or per-collection basis as indicated in :ref:`ogcapi_links`.
HTML Templates
''''''''''''''
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/* (c) 2024 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.ogcapi;

import java.io.Serializable;
import java.util.Objects;

/**
* Service capability or feature, identified by conformance class.
*
* <p>OGCAPI Web Services are defined with core functionality, strictly extended with additional,
* optional, functionality identified by "conformance class".
*
* <p>By comparison OGC Open Web Services can be extended using application profiles with
* additional, optional, functionality.
*/
@SuppressWarnings("serial")
public class APIConformance implements Serializable {

/** There are three levels of standard. */
public enum Level {
/**
* Draft developed by communities external to the OGC or other official organization.
*
* <p>GeoServer community modules are community draft standards under development.
*/
COMMUNITY_DRAFT(false, false),
/**
* Developed by communities external to the OGC or other official organization.
*
* <p>GeoServer vendor extensions are considered community standards.
*/
COMMUNITY_STANDARD(true, false),

/**
* Draft standard being developed by OGC membership or other official organization.
*
* <p>This protocol is under active development, often seeking funding and feedback.
* GeoSever community modules are used to explore draft standards.
*
* <p>This functionality is opt-in and should not be enabled by default.
*/
DRAFT_STANDARD(false, true),

/**
* Mature standard, however the implementation is still under development.
*
* <p>Does not yet pass CITE certification associated with standard.
*/
IMPLEMENTING(false, true),

/**
* Mature standard, stable and ready for use.
*
* <p>A finalized standard, no longer subject to breaking changes, is required for a
* GeoServer extension to be published. This functionality is stable and enabled by default.
*/
STANDARD(true, true),

/**
* Standards are dynamic and are retired when they are no longer in use.
*
* <p>Retired standards are not enabled by default, but may still be enabled if you made use
* of them in a previous version of GeoServer.
*/
RETIRED_STANDARD(true, false);

/** Standard is currently endorsed by the OGC or other official organization. */
private final boolean endorsed;
/** Standard is stable and no longer subject to change. */
private final boolean stable;

Level(boolean stable, boolean endorsed) {
this.endorsed = endorsed;
this.stable = stable;
}

/**
* Standard is currently endorsed by the OGC or other official organization.
*
* @return true if the standard is officially endorsed, false otherwise.
*/
public boolean isEndorsed() {
return endorsed;
}

/**
* Standard is stable and no longer subject to change.
*
* @return true if the standard is stable and no longer subject, false if the standard is
* experimental and not yet finalized.
*/
public boolean isStable() {
return stable;
}
}

public enum Type {
CORE,
EXTENSION
}

private final APIConformance parent;

/** Conformance class identifier. */
private final String id;

/** Indicates standard approval level. */
private final Level level;

private final Type type;

/** Bean property name. */
private final String property;

/**
* Conformance class declaration, defaulting to APPROVED.
*
* @param id conformance class
*/
public APIConformance(String id) {
this(id, Level.STANDARD);
}

/**
* Conformance class declaration.
*
* @param id conformance class
* @param level standard approval status
*/
public APIConformance(String id, Level level) {
this(id, level, Type.EXTENSION, null);
}
/**
* Conformance class declaration.
*
* @param id conformance class
* @param level standard approval status
* @param property storage key
*/
public APIConformance(String id, Level level, String property) {
this(id, level, Type.EXTENSION, null, property);
}

/**
* Conformance class declaration.
*
* @param id conformance class
* @param level standard approval status
* @param type conformance class type
* @param parent parent conformance class (if this is an extension)
*/
public APIConformance(String id, Level level, Type type, APIConformance parent) {
this(id, level, type, parent, id.substring(id.lastIndexOf('/') + 1));
}
/**
* Conformance class declaration.
*
* @param id conformance class
* @param level standard approval status
* @param type conformance class type
* @param parent parent conformance class (if this is an extension)
* @param property bean property name
*/
public APIConformance(
String id, Level level, Type type, APIConformance parent, String property) {
this.id = id;
this.level = level;
this.type = type;
this.parent = parent;
this.property = property;
}

public APIConformance extend(String id) {
return new APIConformance(id, Level.STANDARD, Type.EXTENSION, this);
}

public APIConformance extend(String id, Level level) {
return new APIConformance(id, level, Type.EXTENSION, this);
}

/**
* ServiceConformance conformance identifier.
*
* @return service module conformance identifier.
*/
public String getId() {
return id;
}

/**
* Recommended storage key.
*
* <p>To avoid confusion the recommended storage key is derived from the conformance class
* identifier. This may be overriden by the constructor.
*
* @return recommended storage key.
*/
public String getProperty() {
return property;
}

/**
* Conformance class standard level.
*
* @return conformance class standard level.
*/
public Level getLevel() {
return level;
}

@Override
public int hashCode() {
return id.hashCode();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
APIConformance serviceModule = (APIConformance) o;
return Objects.equals(id, serviceModule.id);
}

@Override
public String toString() {
return "APIConformance " + property + " ( " + id + " " + level + " )";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

/**
* Marks a class as a OGC API service provider. Behaves in a way similar to {@link
* org.springframework.stereotype.Controller}, the {@link APIDispatcher }assumes the methods are
* org.springframework.stereotype.Controller}, the {@link APIDispatcher } assumes the methods are
* annotated in the same way.
*/
@Retention(RetentionPolicy.RUNTIME)
Expand Down Expand Up @@ -41,7 +41,7 @@
public String landingPage();

/**
* GeoServer {@link org.geoserver.config.ServiceInfo} sublass used to locate the service
* GeoServer {@link org.geoserver.config.ServiceInfo} subclass used to locate the service
* configuration
*/
public Class<? extends ServiceInfo> serviceClass();
Expand Down
Loading

0 comments on commit 3a8c52c

Please sign in to comment.