Class PlanValidator
- Layer 1 - structural / catalog (no provisioning, no live connection dry-run): names (length/charset, asserted locally - never learned from a 400), duplicate names, IP /30 overlaps, ASN sanity, package/metro validity; and, against the public catalog the optimizer already fetched, that every Z-side service-profile uuid resolves, is offered in the connection's metro with a valid seller region, and that the bandwidth fits the profile's allowed tiers and the router package ceiling. A required cloud that is NOT offered at a targeted metro is flagged as a new-market gap rather than silently dropped.
- Layer 2 - live router dry-run (self-contained, real): each planned Cloud Router is
posted to
POST /fabric/v4/routers?dryRun=true. FCRs have no dependency, so this fully validates package/metro/notifications at plan time with nothing provisioned. - Layer 3 - connection endpoint dry-run: a connection whose A-side Cloud Router does not exist yet is not sent a doomed endpoint-less dry-run; it is recorded as DEFERRED (validated structurally now; the live endpoint dry-run runs at provisioning, and needs the customer's authorization key). A connection whose A-side endpoint already exists (a caller-supplied port/FCR, lens 3b) IS dry-run for real, with a complete body.
Every catalog / dry-run step is best-effort: a gateway that cannot serve a surface at all (a bare stub, an offline run) skips that step rather than failing the plan, exactly as the optimizer's catalog scan degrades. Hard errors are only raised from working catalog data or a genuine API rejection.
Three outcome buckets
A live-layer step reaches one of three distinct verdicts, never conflated:
- ERROR - the plan is wrong: a hard structural/catalog failure, or a genuine API rejection of a well-formed request (a 4xx validation rejection, e.g. HTTP 400/409). Errors invalidate the plan.
- DEFERRED - will legitimately validate at provisioning: the connection endpoint dry-run postponed because the A-side Cloud Router does not exist yet (lens 3a). Not an error.
- SKIPPED - could not validate now, and here is why: an infeasibility - the live surface was unavailable (offline / bare stub / not connected), or the API answered with a non-rejection failure (401/403 not entitled, 429 throttled, 5xx server-side, or a transport/timeout error). A skip never invalidates the plan; it is surfaced with a human/LLM-readable reason so the gap is called out rather than hidden.
The rejection-vs-infeasibility split is centralized in classifyLiveFailure(Throwable) so
every live-layer catch classifies identically, and so the execution-time pre-flight can reuse it.
Native multicloud links (Beta)
A PlannedMulticloudInterconnect has no Fabric request body and this SDK calls no
cloud-provider API, so no layer can validate it live and none will at provisioning. Each link is
therefore recorded as SKIPPED with a reason naming the link, never as DEFERRED (nothing
validates it later) and never as an ERROR, with two exceptions that are Layer-1 errors: a
structurally malformed entry (blank or duplicate name, the same cloud on both sides, a
non-positive bandwidth), and an entry produced under CloudToCloudStrategy.NATIVE_ONLY
for which the catalog holds no usable environment (none for the region pair, a status other than
GA, or no size covering the requested bandwidth).
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classThe classification of a single live-layer failure.static enumWhether a live-layer failure is a genuine rejection (a plan defect) or an infeasibility (a skip).static final classThe outcome of validating a plan, in three distinct buckets - hard/rejection errors (which invalidate the plan), deferred validations (which do NOT - they run at provisioning), and skipped validations (which do NOT - they could not be attempted now, each with a reason) - plus the per-connection customer inputs a first-time customer must gather. -
Method Summary
Modifier and TypeMethodDescriptionstatic PlanValidator.LiveFailureClassifies a failure thrown from a live validation step (a router or connection dry-run) as either a genuine rejection of a well-formed request - a real plan defect that must become an ERROR - or an infeasibility that must become a SKIPPED(reason) and never invalidate an otherwise-sound plan.static PlanValidator.Resultvalidate(List<MetroRecommendation> metros, OptimizationRequest request, DeploymentTopology topology, List<PlannedCloudRouter> routers, List<PlannedConnection> providerConnections, List<PlannedBackboneLink> backboneLinks, List<PlannedRoutingProtocol> protocols, Long customerAsn, FabricGateway fabric) Validates a plan that has no native multicloud links.static PlanValidator.Resultvalidate(List<MetroRecommendation> metros, OptimizationRequest request, DeploymentTopology topology, List<PlannedCloudRouter> routers, List<PlannedConnection> providerConnections, List<PlannedBackboneLink> backboneLinks, List<PlannedRoutingProtocol> protocols, List<PlannedMulticloudInterconnect> multicloudLinks, Long customerAsn, FabricGateway fabric) Validates a plan across all layers.
-
Method Details
-
validate
public static PlanValidator.Result validate(List<MetroRecommendation> metros, OptimizationRequest request, DeploymentTopology topology, List<PlannedCloudRouter> routers, List<PlannedConnection> providerConnections, List<PlannedBackboneLink> backboneLinks, List<PlannedRoutingProtocol> protocols, Long customerAsn, FabricGateway fabric) Validates a plan that has no native multicloud links. Equivalent to the ten-argument overload withmulticloudLinks == null.- Parameters:
metros- the source metro recommendations (for the new-market check); may benullrequest- the optimization request (for workload provider dependencies); may benulltopology- the placement topology (which workloads sit where); may benullrouters- the planned Cloud RoutersproviderConnections- the planned provider connectionsbackboneLinks- the planned backbone linksprotocols- the planned routing protocols (for IP overlap checks)customerAsn- the customer BGP ASN, ornullto skip the ASN sanity checkfabric- the gateway for catalog + dry-run access;nullskips every live step- Returns:
- the validation result
-
validate
public static PlanValidator.Result validate(List<MetroRecommendation> metros, OptimizationRequest request, DeploymentTopology topology, List<PlannedCloudRouter> routers, List<PlannedConnection> providerConnections, List<PlannedBackboneLink> backboneLinks, List<PlannedRoutingProtocol> protocols, List<PlannedMulticloudInterconnect> multicloudLinks, Long customerAsn, FabricGateway fabric) Validates a plan across all layers.- Parameters:
metros- the source metro recommendations (for the new-market check); may benullrequest- the optimization request (for workload provider dependencies); may benulltopology- the placement topology (which workloads sit where); may benullrouters- the planned Cloud RoutersproviderConnections- the planned provider connectionsbackboneLinks- the planned backbone linksprotocols- the planned routing protocols (for IP overlap checks)multicloudLinks- the planned native multicloud links (Beta); may benull. Each is recorded as skipped, or as an error in the cases listed in the class documentationcustomerAsn- the customer BGP ASN, ornullto skip the ASN sanity checkfabric- the gateway for catalog + dry-run access;nullskips every live step- Returns:
- the validation result
-
classifyLiveFailure
Classifies a failure thrown from a live validation step (a router or connection dry-run) as either a genuine rejection of a well-formed request - a real plan defect that must become an ERROR - or an infeasibility that must become a SKIPPED(reason) and never invalidate an otherwise-sound plan.- Infeasibility (SKIPPED):
EquinixAuthenticationException(401, not authed),EquinixAuthorizationException(403, not entitled - the brand-new-customer case),EquinixRateLimitException(429, throttled),EquinixServerException(5xx, server-side), and any transport/timeout/connect error (a non-serviceRuntimeExceptionor SDK client error). A baseEquinixServiceExceptionwith no status is also treated as infeasible rather than risk invalidating a sound plan on an ambiguous error. - Rejection (ERROR): an
EquinixServiceExceptioncarrying a 4xx status that is a validation rejection (e.g. HTTP 400/409) - the API rejected a well-formed request because the request itself is wrong.
- Parameters:
e- the failure thrown from the live step;nulltolerated (treated as infeasible)- Returns:
- the classification, with an infeasibility reason when applicable
- Infeasibility (SKIPPED):
-