Class RateCardCostModel

java.lang.Object
com.eqixiac.equinix.design.cost.RateCardCostModel
All Implemented Interfaces:
CostModel

public final class RateCardCostModel extends Object implements CostModel
The CostModel of the Metro Optimizer: prices what a portfolio needs, metro by metro, from a RateCard. The same PortfolioCost feeds the cost objective, the budget constraint and the result's cost estimate, so they cannot disagree.

What is priced, from the portfolio's placement:

  • one Fabric connection (default IP_VC) per (metro, cloud) leg, sized as the sum of the sized workloads it carries (primary and standby) rounded up to the next Fabric bandwidth tier (TIERS_MBPS);
  • one Fabric Cloud Router (default STANDARD) in every metro that carries a cloud leg: router-originated connections need no customer port, which is how the Deployment Wizard builds the design;
  • the cloud provider's own fee per leg, from the reference table as a ConnectionModel.HOSTED (partner) connection, because a Fabric cloud connection is the provider's partner product (ReferenceRateCard.providerConnection): the exact tier, or the next tier up with a "rounded up from X to Y Mbps" note, or unpriced with the reason;
  • data leaving each cloud (CloudIntent.monthlyEgressGb) at the provider's private-path rate when the portfolio connects to the cloud, otherwise at its internet rate.

A metro that carries no leg is charged nothing: there is no per-metro base fee. Data sent into a cloud (monthlyIngressGb) is not charged by the providers the reference table covers, so no line is added for it. Colocation space and power, and site access circuits, are not priced.

Every line is priced in the target currency (commercial.currency, default USD). A line quoted in another currency is converted through CurrencyConverters (pinned spec rates, then a supplied converter, then live ECB reference rates, then the bundled table): it keeps its original amount and currency in CostLine.conversion(), its note states the rate, source and date, and its range is widened by the rate's band. Amounts in different currencies are never added raw. Only a currency no source covers leaves the line unpriced, with that reason.

Every line carries its source and a range from PriceBands. Anything that cannot be priced (an unsized workload, a metro the card has no figure for, a provider with no port row) is listed in PortfolioCost.unpriced(), never counted as zero. Each distinct item (metro, item, bandwidth tier, term) is priced once per model and cached; prepare(Collection, DesignContext) prices a solver's batch ahead on a small bounded pool.

  • Field Details

  • Method Details

    • builder

      public static RateCardCostModel.Builder builder(RateCard rateCard)
      Parameters:
      rateCard - the card Equinix items and egress are priced from
      Returns:
      a builder
    • forSpec

      public static RateCardCostModel.Builder forSpec(DesignSpec spec, RateCard rateCard)
      A builder preset from a spec: the term (commercial.term, default Term.MONTH_1), the target currency (commercial.currency, default USD) and commercial.exchangeRates.
      Parameters:
      spec - the design spec
      rateCard - the card Equinix items and egress are priced from
      Returns:
      a builder
    • converter

      public CurrencyConverters.Chain converter()
      Returns:
      the converter in use (pinned rates, supplied converter, live ECB rates, bundled table)
    • term

      public Term term()
      Returns:
      the commitment term prices are looked up at
    • currency

      public String currency()
      Returns:
      the currency lines are restated in, USD unless set
    • exchangeRates

      public CommercialTerms.ExchangeRates exchangeRates()
      Returns:
      the caller's exchange rates, or null when none were supplied
    • missingRates

      public SortedSet<String> missingRates(PortfolioCost cost)
      The currencies whose exchange rate to currency() is missing for this cost: every line currency other than the target. Empty when the cost is comparable in the target currency.
      Parameters:
      cost - a cost this model produced
      Returns:
      the missing rates' currency codes, sorted
    • price

      public PortfolioCost price(MetroPortfolio portfolio, DesignContext context)
      Specified by:
      price in interface CostModel
      Parameters:
      portfolio - the candidate design
      context - the facts of this run
      Returns:
      every priced line with its source and range, and what could not be priced
    • prepare

      public void prepare(Collection<MetroPortfolio> portfolios, DesignContext context)
      Prices, in one batch, every distinct item these portfolios need that has not been priced yet: each (item, metro, bandwidth, term) once, on a small bounded pool (RateCardCostModel.Builder.prefetch(int, Duration, int)). The answers are the ones price(MetroPortfolio, DesignContext) would get on its own, because each item is priced by the same lookup and stored under the same key; only the order the lookups run in differs. A lookup that has not answered within the lookup timeout is priced from the fallback card (RateCardCostModel.Builder.fallbackRateCard(RateCard), default the reference table) with a note saying so, and after maxTimeouts timeouts the remaining lookups are priced from the fallback card without waiting; notes() lists every such substitution.
      Specified by:
      prepare in interface CostModel
      Parameters:
      portfolios - the portfolios about to be priced
      context - the facts of this run
    • notes

      public List<String> notes()
      Substitutions made while pricing: lookups that timed out or failed and were priced from the fallback card.
      Returns:
      the notes, empty when every lookup answered
    • tierFor

      public static int tierFor(int mbps)
      Parameters:
      mbps - a bandwidth
      Returns:
      the smallest tier at or above it, or -1 above the largest