Class EquinixRateCard

java.lang.Object
com.eqixiac.equinix.design.value.ratecard.EquinixRateCard
All Implemented Interfaces:
RateCard

public final class EquinixRateCard extends Object implements RateCard
A RateCard backed by the live Equinix Fabric Pricing API (fabric.prices()); the authoritative source of Equinix-side connection and Cloud Router prices for the cost, savings, and TCO models.

Every lookup is one targeted POST /fabric/v4/prices/search. The live service rejects a catalogue scan by /type alone (HTTP 400: /connection/type, /connection/bandwidth and both access-point types are mandatory for connections, and /router/package/code and /router/location/metroCode for Cloud Routers; observed 2026-11-11). A connection is queried as COLO (or CLOUD_ROUTER for IP_VC) on the A-side to a service provider (SP) on the Z-side, both in the requested metro, which is the Fabric-to-cloud connection the design models price. A lookup with no metro, or for a connection type this card does not map, cannot be priced live and returns empty so a layered card falls back. Rows are matched on their structured descriptor (type, bandwidth, access-point metro, router package).

Both lookups honour the request's remaining axes strictly. When a metro is requested, a row of another metro is never returned - the lookup yields empty instead, so a layered card can consult a lower layer that may hold a genuine figure for that metro. The live catalogue is also term-scoped, so rows whose termLength matches the requested Term are preferred; when only a different-term row exists, it is returned with a note naming the substitution (never silently), and a row without a termLength is term-neutral.

The card is fault-tolerant: if the catalogue cannot be fetched (network error, unauthenticated client, endpoint unavailable), it yields Optional.empty() for every lookup so callers fall back to another rate card or a heuristic rather than failing, and it reports the failure through isLiveSourceUnavailable(). Every quote it does produce is tagged PriceSource.EQUINIX_LIVE.

Each query's result is cached for the card's lifetime once it succeeds. A failed query is not cached and is retried on the next lookup, so a transient 429/5xx/auth error never permanently poisons the card. A lookup that finds no matching or no priced row simply defers to the fallback - never a wrong or phantom-zero number.

  • Method Details

    • of

      public static EquinixRateCard of(FabricGateway fabric)
      Creates a live rate card over the given authenticated Fabric client. The price catalogue is fetched lazily on the first lookup and cached for the lifetime of the card.
      Parameters:
      fabric - the authenticated Fabric client (or any FabricGateway)
      Returns:
      a live Equinix rate card
    • connection

      public Optional<PriceQuote> connection(ConnectionType type, int bandwidthMbps, MetroCode metro, Term term)
      Description copied from interface: RateCard
      Resolves the price of a single Fabric connection / virtual connection.

      Implementation contract. The matching strategy is implementation-specific, and a card whose data lacks an axis (metro, term, type) still returns its best figure - or empty - rather than failing; callers must not assume every card is sensitive to every parameter. Of the bundled cards: CustomRateCard resolves the most specific declared entry (exact metro+term down to metro/term-agnostic, then a declared default); EquinixRateCard matches bandwidth and type against the live catalogue, honours a requested metro strictly (a wrong-metro row is never returned), and prefers a term-matched row - a different-term row is only ever returned with a note naming the substitution; ReferenceRateCard matches on bandwidth alone (smallest tabulated tier at or above the request, linearly extrapolated with an EXTRAPOLATED note above the top tier) and ignores type, metro, and term entirely.

      Specified by:
      connection in interface RateCard
      Parameters:
      type - the connection type (e.g. EVPL_VC); may be null for any type
      bandwidthMbps - the provisioned bandwidth in Mbps
      metro - the metro the connection originates in (may be null if metro-agnostic)
      term - the commitment term (may be null if term-agnostic)
      Returns:
      the resolved quote, or Optional.empty() if this card cannot price the connection
    • connectionLookup

      public PriceLookup<PriceQuote> connectionLookup(ConnectionType type, int bandwidthMbps, MetroCode metro, Term term)
      RateCard.connection(ConnectionType, int, MetroCode, Term) with the reason when it cannot be priced. Cards override this to say exactly why (no metro, no live row, no declared rate); the default states that this card holds no figure.

      The reason names the cause: no metro, a bandwidth of 0, an unmapped connection type, the live source unreachable, or no priced row for the request.

      Specified by:
      connectionLookup in interface RateCard
      Parameters:
      type - the connection type; may be null
      bandwidthMbps - the bandwidth in Mbps
      metro - the metro; may be null
      term - the term; may be null
      Returns:
      the figure, or the reason there is none
    • cloudRouter

      public Optional<PriceQuote> cloudRouter(String packageCode, MetroCode metro, Term term)
      Description copied from interface: RateCard
      Resolves the price of a single Fabric Cloud Router instance.

      Implementation contract. As with RateCard.connection(ConnectionType, int, MetroCode, Term), matching is implementation-specific and cards without a metro/term axis return their best figure regardless. Of the bundled cards: CustomRateCard resolves the most specific declared (packageCode, metro, term) entry; EquinixRateCard matches the package code and metro structurally against the row's own descriptor (exact package equality, the row's own metro code) and prefers a term-matched row, labelling any term substitution; ReferenceRateCard ignores metro and term, and substitutes its STANDARD figure for an unlisted package with a note naming the substitution.

      Specified by:
      cloudRouter in interface RateCard
      Parameters:
      packageCode - the router package / tier code (e.g. "STANDARD"); may be null for any
      metro - the metro the router is deployed in (may be null if metro-agnostic)
      term - the commitment term (may be null if term-agnostic)
      Returns:
      the resolved quote, or Optional.empty() if this card cannot price the router
    • cloudRouterLookup

      public PriceLookup<PriceQuote> cloudRouterLookup(String packageCode, MetroCode metro, Term term)
      RateCard.cloudRouter(String, MetroCode, Term) with the reason when it cannot be priced. The reason names the cause as for connectionLookup(ConnectionType, int, MetroCode, Term).
      Specified by:
      cloudRouterLookup in interface RateCard
      Parameters:
      packageCode - the router package; may be null
      metro - the metro; may be null
      term - the term; may be null
      Returns:
      the figure, or the reason there is none
    • source

      public PriceSource source()
      Description copied from interface: RateCard
      The dominant provenance of prices this card produces. Aggregating cards report PriceSource.COMPOSITE.
      Specified by:
      source in interface RateCard
      Returns:
      the price source
    • isLiveSourceUnavailable

      public boolean isLiveSourceUnavailable()
      Whether the most recent attempt to fetch the live price catalogue failed (network error, unauthenticated client, 429/5xx). When true, an empty lookup result means "the live source could not be reached", not "no such price"; the next lookup retries the fetch. A successful fetch - even one that legitimately returns no rows - clears this. Lets callers distinguish an empty catalogue from a failed fetch.
      Returns:
      true if the last catalogue fetch failed and rows may be missing