Skip to content

feat(llmo-akamai): CUSTOM-default OAE onboarding (PUT deploy + caching/scope gates) - #2851

Closed
ABHA61 wants to merge 8 commits into
feat/akamai-oae-automationfrom
feat/akamai-oae-custom-only
Closed

feat(llmo-akamai): CUSTOM-default OAE onboarding (PUT deploy + caching/scope gates)#2851
ABHA61 wants to merge 8 commits into
feat/akamai-oae-automationfrom
feat/akamai-oae-custom-only

Conversation

@ABHA61

@ABHA61 ABHA61 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Squash-collapses the OAE onboarding work onto a fresh feat/akamai-oae-automation branch (cut from main) so the review PR (feat/akamai-oae-automationmain) shows a single commit for senior review.

Squash-merge this PR — that puts one commit on feat/akamai-oae-automation. Full context lives in the automation → main review PR.

Akash Bhardwaj and others added 8 commits July 18, 2026 14:20
…g/scope gates)

Rework the Akamai "Optimize at Edge" (BYOCDN) onboarding for CUSTOM-default properties.

Rule builder (llmo-akamai-utils.js):
- Wildcard the UA match values (*GPTBot* etc.) so they match real agent strings, not
  only an exact "GPTBot".
- Add a Caching behavior (Honor origin Cache-Control + Expires) to the OAE rule ONLY
  when the property's default rule has none (cfg.addCaching); cacheId is always present.

Controller (llmo-akamai.js):
- deploy/plan: revert JSON-Patch -> full-tree PUT (updateRuleTree, pinned ruleFormat;
  plan uses the client's dryRun).
- Scope gate: reject a non-CUSTOM default origin (400) BEFORE creating a version, so a
  rejected onboarding leaves no orphan version.
- Caching decision: addCaching = !defaultRuleHasCaching(tree).
- Optional baseVersion (copy-from); caller email in the activation note.

Tests + OpenAPI updated (119 passing, lint clean).

NOTE: package.json temporarily points @adobe/spacecat-shared-akamai-client at a gist
tarball for testing. Swap it back to the published version (after adobe/spacecat-shared#1825
merges + releases) before merging this PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mergeIntoTree/buildRuleTreePatch defaulted insertIndex to 0 when the caller
(the wizard) sends none, inserting "Optimize at Edge" as the FIRST child. On
Akamai, sibling rules evaluate top-down and origin/caching are last-match-wins,
so a later stock rule (Offload origin, Increase availability, …) clobbered the
OAE origin override + cacheId and bots were never routed. Default now appends
after all existing children; an explicit numeric insertIndex is still honored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…error

Akamai's activation POST regularly exceeds the shared client's 10s request
timeout on large rule trees (it re-validates the whole tree), so client.activate
throws even though Akamai already queued the activation; any retry then returns
422 already-activated. Both were surfaced as a 502 "Akamai activation failed"
(and a misleading "check credentials" in the UI), though the activation was in
flight. The activate handler now, on error, looks up the latest activation for
the exact version+network and — if it's in flight or active — reports success so
the UI polls it. Genuine failures still surface.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rity)

- OAE origin host now comes from env.EDGE_OPTIMIZE_EDGE_DOMAIN (falls back to
  live.edgeoptimize.net), so a dev/stage deployment routes AI-bot traffic to
  dev/stage.edgeoptimize.net instead of always prod. matchSan (*.edgeoptimize.net)
  covers all three, so CUSTOM cert validation still holds.
- Restore the setVariable PMUSER_EDGE_OPTIMIZE_FAILOVER=TRUE on the Site Failover
  rule (declared FALSE, flipped on failover) for v38 parity — observability marker
  for Akamai logs; does not affect routing/caching.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a test where both the activation POST and the latestActivation recovery
lookup fail, so the handler falls through to the sanitized 502 — restoring diff
coverage for the recover inner-catch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A just-queued Akamai activation appears in the activations list before its id is
assigned, serializing as "atv_null" (which passes the general id regex but is not
pollable). The activate recovery now returns activationId:null for any non-real
(non-numeric) id, so the UI polls by network until a real atv_<digits> appears
instead of polling an unpollable placeholder and 404-ing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- deploy: reject baseVersion 0 (passes DECIMAL_INT_RE but PAPI versions start at
  1) with a clean 400, mirroring activate.
- activate recovery: only adopt a listed activation submitted within the last 5
  minutes (isRecentlySubmitted) so a failed POST can't falsely match an unrelated
  older activation for the same version+network; log the double-failure at error.
- behaviorCaching: document that defaultTtl 1d is the origin-omits-Cache-Control
  fallback, not the common path.
- OpenAPI: insertIndex now documents the append-last default (was "0/first").

Addresses MysticatBot/Codex review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Removes the 5-minute recency guard from activation recovery. Re-activating a
version that is already ACTIVE returns Akamai 422 already-activated; with the
recency guard, an activation submitted >5min ago was rejected and surfaced as a
false "Akamai activation failed", even though the version is live on the network.
The version+network + in-flight/active status match is the correct guard: it
means the desired end state exists, so report success regardless of age.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ABHA61

ABHA61 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

Closing — keeping the original PR #2850 for review instead.

@ABHA61 ABHA61 closed this Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant