Class CatalogueClient

java.lang.Object
com.ultikits.ultitools.utils.CatalogueClient

final class CatalogueClient extends Object
The module catalogue of protocol v2, read over /v1/catalogue/* (plans 22-18 and 22-26, D-27, D-28).

The routes, the response envelope {data: ...} and the version object follow the frozen catalogue REST contract "1.0.0" of UltiCloud (UltiKits/ulticloud main commit 682735c9, packages/contracts/generated/rest-v1/catalogue/1.0.0/), whose schemas and fixtures the tests read byte for byte. A module is addressed by its identifier; a version names its sizeBytes, its lower-case sha256, its apiLevel (an integer, or null when unknown) and a download whose kind is public (with an absolute https: URL), license_required or withdrawn. Every kind but public is not downloadable.

A version object that breaks the contract in a field the install relies on -- a sha256 that is not 64 lower-case hex characters, a sizeBytes below 1, a missing or out-of-range apiLevel, a missing isLatest or version, a public download without a URL -- is unusable: the lookup answers nothing, as for an unreadable body, and no download is requested. Keys the client does not read, including keys a later contract may add, are ignored.

Only the versions route takes the API-level filter (apiLevel, minApiLevel); the other routes reject undeclared parameters, so no request carries them. A download.url is accepted only when it is absolute and stays on the configured base URL's origin (in production https://api.ultikits.com); a relative path, which the contract never produces, is refused, so a catalogue answer can never send a download elsewhere.

Since:
6.3.1
  • Field Details

    • MODULES

      static final String MODULES
      The route prefix of every catalogue request.
      See Also:
    • FRAMEWORK

      static final String FRAMEWORK
      The route naming the newest UltiTools version.
      See Also:
    • CONTRACT_VERSION

      static final String CONTRACT_VERSION
      The catalogue REST contract version this client implements; the vendored lock must name the same.
      See Also:
    • SHA256

      private static final Pattern SHA256
      The contract's sha256: 64 lower-case hex characters.
    • HTTPS_URL

      private static final Pattern HTTPS_URL
      The contract's URL rule for icons: an absolute https: URL without spaces or control characters.
    • MAX_URL_LENGTH

      private static final int MAX_URL_LENGTH
      The longest URL the contract allows.
      See Also:
    • MAX_SIZE_BYTES

      private static final long MAX_SIZE_BYTES
      The largest sizeBytes the contract allows (2^53 - 1).
      See Also:
    • MIN_API_LEVEL

      private static final int MIN_API_LEVEL
      The contract's apiLevel range.
      See Also:
    • MAX_API_LEVEL

      private static final int MAX_API_LEVEL
      See Also:
  • Constructor Details

    • CatalogueClient

      private CatalogueClient()
  • Method Details

    • moduleRef

      static String moduleRef(String identifyString)
      The contract's :moduleRef for a module: its identifier (lower-case letter first, segments separated by a single . or -, 1 to 64 characters), as ModuleIds.of(String) derives it. The framework never addresses a module by its ULID.
      Parameters:
      identifyString - a module's identify-string
      Returns:
      the segment the catalogue addresses it by, or null when it cannot be one
    • module

      static PluginEntity module(String identifyString)
      Reads one module.
      Parameters:
      identifyString - the module's identify-string
      Returns:
      the module, or null when the catalogue does not know it or the answer is unusable
    • list

      static List<PluginEntity> list(int page, int pageSize)
      Reads one page of the catalogue.
      Parameters:
      page - the page number, from 1
      pageSize - the page size
      Returns:
      the modules of that page; empty for every failure, as the public list contract says
    • versions

      static List<CatalogueClient.Version> versions(String identifyString, int level)
      Reads the versions one framework can install, newest first as the catalogue lists them.
      Parameters:
      identifyString - the module's identify-string
      level - this framework's API level
      Returns:
      the versions, empty when the module is unknown, or null when the answer is unusable
    • lookUpVersions

      static VersionLookup lookUpVersions(String identifyString, int level, List<CatalogueClient.Version> versions)
      Reads a version list without folding an unknown module into a successful empty list.
      Parameters:
      identifyString - the module's identify-string
      level - this framework's API level
      versions - collects the versions on success, including a successful empty list
      Returns:
      FOUND with the module identifier on success, NONE only for an unknown module, or FAILED when the answer is unusable
    • version

      static CatalogueClient.Version version(String identifyString, String version)
      Reads one version.
      Parameters:
      identifyString - the module's identify-string
      version - the version string
      Returns:
      the version, or null when the catalogue does not offer it
    • moduleKnown

      static VersionLookup moduleKnown(String identifyString)
      Whether the catalogue knows a module at all.
      Parameters:
      identifyString - the module's identify-string
      Returns:
      FOUND with its identifier, NONE when the catalogue does not know it, FAILED when the lookup established nothing
    • latestVersion

      static VersionLookup latestVersion(String identifyString, int level)
      Looks up a module's newest installable version, for a module the catalogue knows.
      Parameters:
      identifyString - the module's identify-string
      level - this framework's API level
      Returns:
      FOUND with the version, NONE when nothing installable (or nothing at all) is offered, FAILED when the lookup established nothing
    • frameworkNewest

      static VersionLookup frameworkNewest()
      Looks up the newest UltiTools version.
      Returns:
      FOUND with the version, or FAILED when the lookup established nothing
    • absoluteDownloadUrl

      static String absoluteDownloadUrl(String url)
      Checks a download.url against the configured base URL. The contract makes every URL absolute (https: in production) and tells callers to use it as an opaque address, so the URL is used as written, and only when it lies under the base URL: another host, another scheme, a user@host form or a relative path is refused.
      Parameters:
      url - the value the catalogue answered
      Returns:
      the URL, or null when it is relative or would leave the catalogue's origin
    • levelQuery

      static String levelQuery(int level)
      Returns:
      the filter every versions request carries: this framework's level and the floor
    • newest

      Parameters:
      versions - the versions to choose from, in any order
      Returns:
      the one the catalogue marks as newest, the greatest otherwise, or null
    • parseVersions

      private static List<CatalogueClient.Version> parseVersions(CatalogueHttp.Json answer)
      Returns:
      the versions an answer carries, or null when it carries no usable list: one version that breaks the contract makes the whole answer unusable, so the newest version is never chosen from a list the catalogue got wrong
    • dataObject

      private static com.google.gson.JsonObject dataObject(CatalogueHttp.Json answer)
    • itemsOf

      private static com.google.gson.JsonArray itemsOf(CatalogueHttp.Json answer)
    • data

      private static com.google.gson.JsonObject data(String body)
    • toVersion

      private static CatalogueClient.Version toVersion(com.google.gson.JsonObject object)
      Reads one version object, or refuses it: null when a field the install relies on breaks the contract (see the class comment). A value of the wrong JSON type is a refusal, never an exception.
    • integer

      private static BigDecimal integer(com.google.gson.JsonElement value)
      Returns:
      the JSON number as an integer, or null when it is absent, not a number or not whole
    • toEntity

      private static PluginEntity toEntity(com.google.gson.JsonObject card)
      Maps a module card into the entity the public catalogue methods have always returned. A v2 module is identified by a ULID and an identifier, and the entity's numeric id has no v2 counterpart, so it stays 0; identifyString is the field callers use.
    • httpsUrl

      private static String httpsUrl(String url)
      Returns:
      the URL when it is an absolute https: URL the contract allows, otherwise null
    • string

      private static String string(com.google.gson.JsonObject object, String name)
    • instant

      private static Date instant(String text)
    • encodeSegment

      private static String encodeSegment(String value)