Skip to content

GSIP 188

Josh Fix edited this page Apr 6, 2020 · 15 revisions

GSIP 188 - New extension point in ResourcePool for determining GridCoverageReader input object types

Overview

​ ImageInputStreamSpi implementations advertise an inputClass. When utilities like GeoTools' ImageIOExt.getImageInputStreamSPI() are invoked, they try to match the provided input object class to the advertised inputClass of the ImageInputStreamSpi. When creating a GridCoverageReader in the ResourcePool, GeoServer only supplies the GridCoverageReaders with URLs in the form of Strings, with one exception. There is a single method to check if the input String represents a File URL, and if so, it converts the input String to a File. ​

This input object is eventually used by ImageIO to determine which ImageInputStream to use by comparing the input class to the advertised inputClass as previously mentioned. Creating new reader implementations becomes difficult because there are already specific ImageInputStreamSpis to support String, URL, File, InputStream, etc. Ambiguity is introduced when more than one reader advertises the same inputClass. For example, S3ImageInputStreamImplSpi and StringImageInputStreamSpi both advertise the input class as String. This results in the ImageIO createImageInputStream method selecting the first SPI it comes across that supports String. ​

This proposal seeks to implement a new extension point that will allow the ResourcePool to supply configurable input objects that extend beyond String/File. This enhancement ensures the specific, desired ImageInputStreamSpi implementation is able to be identified and selected. ​

Proposed By

​ Josh Fix ​

Assigned to Release

​ This proposal is for GeoServer 2.18-beta. ​

State

  • Under Discussion
  • In Progress
  • Completed
  • Rejected
  • Deferred ​

Motivation

​ ImageI/O-Ext has recently introduced a new image reader that supports Cloud Optimized GeoTIFF images. This image reader requires a custom ImageInputStream. The SPI advertises that it supports the input class CogUri.class, yet GeoServer provides no means to instantiate this class as an input.

Proposal

​ The extension code will replace the current logic in the getObjectToRead method of ResourcePool. The code will simply loop through all implementations of the CoverageReaderInputObjectConverter interface provided by GeoServerExtensions and attempt to convert the input String to some other object. A single implementation will be provided with GeoServer that contains the existing logic found in the aforementioned getObjectToRead method of ResourcePool to check and convert the the input String to File. ​

In addition to accepting the input String, the CoverageInfo and Hints objects are to be passed to the method. This empowers implementers by providing as much information as possible to be used in the decision to convert or not. The return type is an java.util.Optional containing the converted object. Any implementation of the proposed interface that cannot convert the input object should return an empty java.util.Optional. ​

/**
 * Extension point for {@link ResourcePool} that enables custom input object types when creating
 * {@link GridCoverageReader}s.  Implementations may return any custom Object which can in turn be used by
 * {@link org.geotools.coverage.grid.io.AbstractGridFormat#getReader(Object)} implementations to instantiate the
 * appropriate GridCoverageReader and by {@link javax.imageio.spi.ImageInputStreamSpi#getInputClass()} implementations
 * to support the accurate selection of {@link javax.imageio.stream.ImageInputStream} implementations.
 *
 * @author joshfix
 * Created on 2/13/20
 */
@FunctionalInterface
public interface CoverageReaderInputObjectConverter<T> {

    /**
     * This method inspects the provided input object in an attempt to convert it to a custom class. Any of the
     * accompanying method parameters may optionally be used to better inform the decision making logic.  If an
     * implementation does not support conversion for the given input object, the method should return an empty
     * {@link Optional}.
     *
     * @param input The input object.
     * @param coverageInfo The grid coverage metadata, may be <code>null</code>.
     * @param hints Hints to use when loading the coverage, may be <code>null</code>.
     * @return an {@link Optional} containing the converted value.
     */
    Optional<T> convert(Object input, @Nullable CoverageInfo coverageInfo, @Nullable Hints hints);

}

Backwards Compatibility

​ No backwards compatibility issues are foreseen. The implementation will replace the static code in ResourcePool that attempts to check if the input String is a File and convert it if it is with an implementation of the proposed interface that accomplishes the same task. The new framework will simply allow for future readers to take advantage of new, custom input types. ​

Feedback

Voting

​ Project Steering Committee: ​

  • Alessio Fabiani: +1
  • Andrea Aime: +1
  • Ian Turton: +0
  • Jody Garnett: +1
  • Jukka Rahkonen:
  • Kevin Smith:
  • Simone Giannecchini: +0

Links

Clone this wiki locally