Resolve canonicals whose URL last segment differs from the resource id (cross-namespace canonicals)#1331
Open
KyleOps wants to merge 2 commits into
Open
Resolve canonicals whose URL last segment differs from the resource id (cross-namespace canonicals)#1331KyleOps wants to merge 2 commits into
KyleOps wants to merge 2 commits into
Conversation
…o-publish ServerType.CLOUD is intended for static hosts (S3, GitHub Pages, etc.) that cannot execute server-side redirect scripts, but two defects made it produce non-functional output: 1. HTML_TEMPLATE was a verbatim copy of PHP_TEMPLATE, so createHtmlRedirect() wrote PHP into index.html. Replaced it with a static HTML redirect (meta refresh + window.location.replace + canonical link), with JSON/XML links for machine clients. Content negotiation is not possible without a server runtime, so browsers go to the human-readable page. 2. PublicationProcess.updatePublishBox (the -go-publish path) had no CLOUD branch, so cloud sites fell through to buildApacheRedirections() and got PHP. Added the missing CLOUD -> buildCloudRedirections() case, matching IGReleaseUpdater.
…-namespace) A resource can legitimately have a canonical whose last path segment differs from its id/filename — e.g. AU external-terminology extensions, where the id is 'au-<x>-extended' (file ValueSet-au-<x>-extended.html) but the canonical is http://terminology.hl7.org.au/ValueSet/<x>-extended (no 'au-'). FHIR does not require id and url to match. Today the cloud redirect builder skips these (the spec.internals 'paths' entry has a full-URL key, dropped by the !contains(":") guard), so dereferencing the published canonical 404s: resolution targets <Type>-<tail>.html, which doesn't exist (the file is <Type>-<id>.html). Emit a flat static-HTML alias <Type>-<tail>.html -> the rendered <Type>-<id>.html for such canonicals (the mapping is already in spec.internals). No-op when tail==id (the common case) and never overwrites a real rendered page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A FHIR resource can legitimately have a canonical URL whose last path segment differs from its
id(and therefore from its rendered filename). When it does, the published canonical does not resolve — it 404s and falls through to the IG landing/history page.Real-world case: AU Base external-terminology extensions. By convention these are authored as:
id=au-v3-ActEncounterCode-extended→ rendered fileValueSet-au-v3-ActEncounterCode-extended.htmlurl(canonical) =http://terminology.hl7.org.au/ValueSet/v3-ActEncounterCode-extended(noau-)FHIR does not require
idandurlto match, and this difference is intentional (the AU terminology authors confirmed the convention:idgets theau-prefix; the canonical uses<hl7-au-namespace>/<external-id>-extended). 13 resources in AU Base 6.x follow it.Dereferencing the canonical resolves to
…/ValueSet-v3-ActEncounterCode-extended.html, but the publisher only ever wrote…/ValueSet-**au-**v3-ActEncounterCode-extended.html, so → 404.Root cause
spec.internalsalready records the canonical → rendered-file mapping, e.g.:But
IGReleaseRedirectionBuilder.buildCloudRedirections()only emits a stub when the path key is IG-canonical-relative; cross-namespace canonicals come throughparseSpecDetailsas full-URL keys and are dropped by theif (!s.contains(":"))guard. So no redirect is generated for them, and resolution targets a<Type>-<tail>.htmlfile that doesn't exist.Fix
For a cross-namespace canonical (full-URL key) whose last segment differs from the rendered file, emit a flat alias
<Type>-<tail>.htmlthat redirects to the actual rendered<Type>-<id>.html(the mapping is already inspec.internals). Guards:<Type>-<tail>already equals the rendered id (the common case — no alias, no overhead);Generated in each published version folder, so versioned canonicals (
…|6.0.0) resolve too.Scope: the cloud/static redirect path (
buildCloudRedirections). Builds on #1327 (static-HTML redirect template + wiringCLOUDinto-go-publish); the net-new change here is one method,createCanonicalUrlAlias.Testing
Built the jar and ran
-go-publish(server typecloud) on AU Base 6.x, deployed the output to a GitHub Pages preview:https://hl7.org.au/fhir/ValueSet-v3-ActEncounterCode-extended.html→ Content Not Found.ValueSet-v3-ActEncounterCode-extended.htmlis generated, returns 200, and redirects toValueSet-au-v3-ActEncounterCode-extended.html(the real resource page).CodeSystem-v2-0203,CodeSystem-v3-ActCode,ValueSet-jurisdiction-extended,ValueSet-v3-ServiceDeliveryLocationRoleType-extended, …).id == tail(e.g.ValueSet-accession-number-type) is unchanged — it renders directly, no alias emitted.The full cross-host chain (
terminology.hl7.org.au/...→hl7.org.au/fhir/...→ alias) is completed by the existing edge/host rewrite; this change supplies the file that rewrite lands on.Live before/after
Design note
Aliases use absolute redirect targets, consistent with the existing canonical/version redirect stubs (and with FHIR canonicals being absolute global identifiers). Making preview builds host-agnostic (so absolute links don't point at production) is a separate, broader concern (a preview/
-baseoverride) and is intentionally out of scope here.Affected resources (AU Base 6.x)
CodeSystems:
au-v2-0203,au-v2-0360,au-v2-0443,au-v3-ActCode,au-location-physical-type,au-location-type.ValueSets:
au-v2-0203-extended,au-v2-0360-extended,au-v2-0443-extended,au-v3-ActEncounterCode-extended,au-v3-ServiceDeliveryLocationRoleType-extended,au-jurisdiction-extended,au-location-physical-type-extended.(Genuinely-external code systems like
mims-external→http://www.mims.com.au/codesare correctly left alone — their canonical points to an outside authority and shouldn't resolve to the IG.)Note: this branch is based on #1327, so the diff includes that PR's commit until it merges; the net-new commit here is the
createCanonicalUrlAliaschange.