Skip to content

Instantly share code, notes, and snippets.

@joshfix
Last active February 14, 2020 18:15
Show Gist options
  • Save joshfix/d5458221192fe6f678f37e5a225954cd to your computer and use it in GitHub Desktop.
Save joshfix/d5458221192fe6f678f37e5a225954cd to your computer and use it in GitHub Desktop.

GSIP xxxx - 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. The power of being able to advertise an input class is severely crippled by GeoServer’s inability to create readers with alternative input classes. 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 a generic type object defined by the implementation. Any implementation of the proposed interface that cannot convert the input String should return the input String unaltered.

/**
/**
 * 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<U> convert(T 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:
  • Andrea Aime:
  • Brad Hards:
  • Ian Turton:
  • Jody Garnett:
  • Jukka Rahkonen:
  • Kevin Smith:
  • Simone Giannecchini:

Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment