resource.rst 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. .. _config_resource:
  2. Resource API
  3. ============
  4. In addition to the formal Catalog API GeoServer needs a way to manage all of the helper files such as icons and fonts, along with freemarker templates, image mosaic property files and many more.
  5. Rather than make direct use of files GeoServer has introduced a Resource API to access this content. While the primary motivation is to allow sharing resources in a cluster, eventually using a different storage, e..g. database or distributed memory. We took this opportunity to optimize the most common use-cases for file interaction in our codebase.
  6. .. note:: Make use of the Resource API for "file" interaction
  7. While the Resource API does offer the ability to unpack a File onto disk for interaction with libraries like Freemarker that only work with files, the majority of interaction can be handled with input and output streams.
  8. Reference:
  9. * `GSIP-137 - ResourceStore Rest API <https://github.com/geoserver/geoserver/wiki/GSIP-137>`__
  10. * `GSIP-136 - Resource Notification Dispatcher <https://github.com/geoserver/geoserver/wiki/GSIP-136>`__
  11. * `GSIP-132 - GSIP 132 - Resource Store changes <https://github.com/geoserver/geoserver/wiki/GSIP-132>`__
  12. Parameter Naming Convention
  13. ---------------------------
  14. The methods in the Resource API use String parameter names consistently:
  15. * ``resource path`` parameter is a path to a resource in the resource store.
  16. In the case of the default FileSystemResourceStore, this is file path that is relative with respect to the data directory. To preserve generic behaviour compatible with any resource store, developers should not assume this to be the case.
  17. Resource paths do not support the `.` and `..` relative directory names. Resource paths use forward slashes, similar to URL's and unix style file paths, and are OS-independent.
  18. * ``file path`` parameter is an absolute path to a file in the file system.
  19. While these are OS dependent (with regard to the root of the absolute path) but they must always use forward slashes, as supported by all operating systems and compatible with resource paths as well as file URL's. Note that ``Resource.path()`` for resources obtained by ``Files.asResource(file)`` will return a file path rather than a resource path.
  20. * ``file`` parameter is a java File reference.
  21. * ``url`` a location resolved with respect to the resource store.
  22. A number of special cases developed over time distilled into ``Resources.fromUrl(base,url)`` method.
  23. General Guidelines
  24. ------------------
  25. All geoserver developers should be wary of the following general principles when contributing or reviewing:
  26. * Avoid as much as possible using the file system directly.
  27. .. note:: The only acceptable exception is when third party libraries require use of a File. Even in this case use Resources API as much as possible.
  28. * Use Avoid the usage of ``Resource.file()`` and ``Resource.directory()``.
  29. These methods are only necessary for third party libraries that require usage of the file system, when the third party library accepts a file input.
  30. .. note:: The ``file()`` and ``directory()`` methods are never be used for permanent storage. Since there are alternative implementations of the ResourceStore that do not use the file system as underlying storage device, modifying a file on disk does not necessarily have a lasting effect.
  31. * For custom configuration files with a fixed location, always use ``ResourceStore``.
  32. ``GeoServerResourceLoader`` and ``GeoServerDataDirectory`` from GeoServer 1.0 have been rewritten internally to use Resource API , and should not be used in new code.
  33. * For URL's provided by user configuration (such as templates, style sheets, etc), use ``Resources.fromURL``.
  34. * For input/output, always use ``Resource.in()`` and ``Resource.out()``.
  35. This approach is compatible with java try-with-resource making for easy to follow code.
  36. ResourceStore
  37. -------------
  38. Used to manage configuration storage (file system, test harness, or database blob).
  39. InputStream used to access configuration information:
  40. .. code-block:: java
  41. Properties properties = new Properties();
  42. try (InputStream in = resourceStore.get("module/configuration.properties").in() ){
  43. properties.load(in);
  44. }
  45. An OutputStream is provided for storage (a Resource will be created as needed):
  46. .. code-block:: java
  47. Properties properties = new Properties();
  48. properties.put("hello","world");
  49. try (OutputStream out = resourceStore.get("module/configuration.properties").out() ){
  50. properties.store( out, null );
  51. }
  52. A Resource can also be extracted to a file if needed:
  53. .. code-block:: java
  54. File file = resourceStore.get("module/logo.png");
  55. BufferedImage img = ImageIO.read( file );
  56. The base directory is available using ``Paths.BASE`` (as ``""`` but relative paths (``.`` and
  57. ``..`` are not supported). Path assumes a unix-like file system, all paths are relative and use forward slash
  58. {@code /} as the separator.
  59. Resource
  60. --------
  61. Resource used for configuration storage. Described by ``getType()`` as a ``Type.DIRECTORY``, ``Type.RESOURCE``, or are considered ``Type.UNDEFINED``.
  62. Resource contents are streamed using ``out()`` and ``in()`` methods. The entire contents can be managed in one go using ``setContents(bytes)`` and ``getContents()``.
  63. .. code-block:: java
  64. try (OutputStream out = resource.out() ){
  65. properties.store(out)
  66. }
  67. Resource ``path()`` provides the complete path relative to the ``ResourceStore`` base directory. Use ``name()`` to retrieve the resource name (as the last component in the path name sequence).
  68. Resource creation is handled in a lazy fashion, use ``out()`` and the resource will be created as required, including any required parent directories are created to produce the completed path.
  69. Directory resources have the ability to ``list()`` their contents:
  70. .. code-block:: java
  71. for( Resource child : resource.list()) {
  72. ...
  73. }
  74. The method ``isInternal()`` returns whether the resource is part of the resource store or rather a wrapped file obtained by ``File.asResource``. If this method returns `false` then ``path()`` returns a file path rather than a resource path.
  75. The methods ``file()`` and ``dir()`` may be used to obtain a file system representation of the resource. Depending on the resource store implementation, this may be the underlying storage entity (in the case of the default FileSystemResourceStore), or merely a cached entity. Changes to these should not be assumed to be permanent. These methods should only be used for input when a third library requires a file and does not support passing on streams.
  76. Once created resources can be managed with ``delete()``, ``renameTo(resource)`` methods.
  77. Resource supports ``addListener(listener)`` / ``removeListener(listener)`` event notification allowing code to watch a file for change. A single listener can watch for changes within a folder, with the events providing the path of changed files.
  78. Resource ``lock()`` is also supported.
  79. Paths
  80. -----
  81. The ``Paths`` facade provides methods for working with resource paths used by ResourceStore.
  82. Helpful methods are provided for working with paths and names:
  83. * ``name(path)``
  84. * ``extension(path)``
  85. * ``parent(path)``
  86. * ``sidecar(path, extension)``
  87. * ``names(path)`` processes the path into a list of names as discussed below.
  88. Paths are broken down into a sequence of names, as listed by ``Paths.names(path)``:
  89. * ``Path.names("data/tasmania/roads.shp")`` is represented as a list of ``data``, ``tasmania``, ``roads.shp``.
  90. For file paths that are OS dependent, use ``FilePaths.names(file_path)`` instead.
  91. FilePaths
  92. ---------
  93. The ``FilePaths`` facade provides methods for working with file paths.
  94. Paths are broken down into a sequence of names, as listed by ``Paths.names(path)``:
  95. * On linux ``FilePath.names("/src/gis/cadaster/district.geopkg")`` starts with a marker to indicate an absolute path, resulting in ``/``, ``src``, ``gis``, ``cadaster``, ``district.geopkg``.
  96. * On windows ``FilePath.names("D:/gis/cadaster/district.geopkg")`` starts with a marker to indicate an absolute path, resulting in ``D:/``, ``gis``, ``cadaster``, ``district.geopkg``.
  97. Paths.convert
  98. ^^^^^^^^^^^^^
  99. The ``convert`` methods are used to process file references into resource paths:
  100. * ``Paths.convert(base,file)`` - uses URI relativize method to determine relative path (between file and base)
  101. * ``Paths.convert(base,folder, fileLocation)`` - can resolve relative location, limited to content within the base directory
  102. * ``Paths.convert(base, filename)``
  103. Resources
  104. ---------
  105. The ``Resources`` facade provides lots of common activities for working with Resource.
  106. Most of these perform common activities or check on resource status ``exists(resource)``, ``hidden(resource)``.
  107. Resources methods provide the flexibility to work with with Resource while not getting caught out in the dfference between DIRECTORY and RESOURCE type.
  108. .. code-block:: java
  109. if( Resources.exists(resource)) {
  110. // may be a file or a directory
  111. File fileLocation = Resources.find(resource);
  112. ...
  113. }
  114. There are also methods to copy contents into a resource:
  115. .. code-block:: java
  116. Resources.copy( file, targetDirectory);
  117. There are also method for working with directories recursively and filtering content:
  118. .. code-block:: java
  119. for (Resource svg : Resources.list( resource, new ExtensionFilter("svg"), true )) {
  120. ...
  121. }
  122. Resources.fromUrl
  123. ^^^^^^^^^^^^^^^^^
  124. The interpretation of the URLs is as follows:
  125. * ``resource:`` prefix - interpreted as a resource path, returns resource from the resource store.
  126. * ``file:`` prefix with absolute path - interpreted as file path, returns resource created by Files.asResource that refers to file in the file system.
  127. * ``file:`` prefix with relative path (deprecated) - interpreted as a resource path, returns resource from the resource store.
  128. Examples:
  129. * ``Resources.fromURL( baseDirectory, "resource:images/image.png")`` - resource path
  130. * ``Resources.fromURL( baseDirectory, "file:images/image.png")`` - resource path (deprecated)
  131. * ``Resources.fromURL( null, "/src/gis/cadaster/district.geopgk")`` - absolute file path (linux)
  132. * ``Resources.fromURL( baseDirectory, "D:\\gis\\cadaster\\district.geopkg")`` - absolute file path (windows)
  133. * ``Resources.fromURL( baseDirectory, "file:///D:/gis/cadaster/district.geopkg")`` - absolute file url (windows)
  134. * ``Resources.fromURL( baseDirectory, "ftp://veftp.gsfc.nasa.gov/bluemarble/")`` - null (external reference)
  135. Files
  136. -----
  137. The ``Files`` facade provides methods for working with file objects, and one method of critical importace to the Resource API.
  138. Files.asResource
  139. ^^^^^^^^^^^^^^^^
  140. The ``Files.asResource(file)`` method creates a ``ResourceAdapter`` wrapper around an absolute file location. Allows the use of Resource API when working with content outside of the data directory. This is primary useful for writing test cases.
  141. Files.url
  142. ^^^^^^^^^
  143. .. warning:: This method is deprecated along with File use, recommend use of ``Resources.fromURL (baseDirectory, url )`` to obtain Resource.
  144. The other key method is ``Files.url( baseDirectory, url)`` which is used to look up files based on a user provided URL (or path).
  145. * ``Files.url( null, "resource:styles/logo.svg")`` - internal url format restricted to data directory content
  146. * ``Files.url( null, "/src/gis/cadaster/district.geopgk")`` - absolute file path (linux)
  147. * ``Files.url( baseDirectory, "D:\\gis\\cadaster\\district.geopkg")`` - absolute file path (windows)
  148. * ``Files.url( baseDirectory, "file:///D:/gis/cadaster/district.geopkg")`` - absolute file url (windows)
  149. * ``Files.url( baseDirectory, "ftp://veftp.gsfc.nasa.gov/bluemarble/")`` - null (external reference ignored as we cannot determine a file)
  150. * ``Files.url( baseDirectory, "sde://user:pass@server:port")`` - null (custom strings are ignored as we cannot determine a file)
  151. GeoServerDataDirectory
  152. ----------------------
  153. ``GeoServerDataDirectory`` is a special ``ResourceStore`` allowing the use of catalog configuration objects to act
  154. as a reference point (rather than having to remember the structure of the data directory).
  155. .. code-block:: java
  156. Resource icon = dataDirectory.get( workspaceInfo, "airports.svg");
  157. ``GeoServerDataDirectory`` has plenty of methods that still provide direct file access, internally however they are implemented using the Resource API.
  158. .. code-block:: java
  159. public File findDataRoot() throws IOException {
  160. Resource directory = get("data");
  161. return Resources.directory(directory);
  162. }
  163. GeoServerResourceLoader
  164. -----------------------
  165. The class ``GeoServerResourceLoader`` operates as a facade mimicking some of the early file based
  166. interaction in our codebase to help during the migration to the ``ResourceStore`` API.
  167. The use of ``location`` parameters here can reference a relative location in the data directory, or an absolute file location on disk.
  168. Each method here can be expressed using the utility classes:
  169. .. code-block:: java
  170. // Using GeoServerResourceLoader to work with local file
  171. File configuration = loader.createFile(location);
  172. try (OutputStream out = new FileOutputStream(configuration)) {
  173. xstream.toXML(ogrConfiguration, out);
  174. }
  175. // Using Paths and Resources to work with local file
  176. Resource resource = resources.get(Paths.convert(location));
  177. File configuration = Resources.createNewFile(resource);
  178. try (OutputStream out = new FileOutputStream(configuration)) {
  179. xstream.toXML(ogrConfiguration, out);
  180. }
  181. // Using Resource directly to work in clustered environment
  182. Resource resource = resourceStore.get(Paths.convert(location));
  183. try (OutputStream out = resource.out()) {
  184. xstream.toXML(ogrConfiguration, out);
  185. }