Skip to content

Server v3.0.0#2635

Draft
johngrimes wants to merge 56 commits into
mainfrom
release/server/3.0.0
Draft

Server v3.0.0#2635
johngrimes wants to merge 56 commits into
mainfrom
release/server/3.0.0

Conversation

@johngrimes

Copy link
Copy Markdown
Member

No description provided.

Add viewReference support, Reference-typed patient/group with spec
cardinality, Bundle unwrapping in the resource parameter, and 422 for
semantically invalid ViewDefinitions on the run operation. Across the
run, export, and sqlquery-run operations, reject an explicitly
unsupported _format and the unsupported source parameter rather than
silently ignoring them. Add a creation-time start timestamp to the
async job for later export-manifest timing.
Support view.viewReference resolution to a stored ViewDefinition with
per-part exclusivity and presence checks. Rewrite the completion
manifest to the SQL on FHIR shape (exportId, status, echoed
clientTrackingId and _format, export timing fields, and one output per
view with name and location parts), dropping the Bulk Data-style
fields. Return a Parameters kick-off acknowledgement for SQL on FHIR
async operations while leaving the Bulk Data kick-off body unchanged.
…ery 422

Declare the SQL on FHIR spec canonical OperationDefinition URLs for the
viewdefinition-run, viewdefinition-export, and sqlquery-run operations in
the CapabilityStatement, and stop serving the Pathling-authored
OperationDefinitions for them. Add a regression test pinning the existing
422 response for an unmappable FHIR column type under _format=fhir on
sqlquery-run, and integration coverage for the source and _format
rejections across all levels and transports.
Update the admin UI manifest parser to read the spec-shaped output
location parts (one or more per output) instead of a single url part,
emitting one download entry per file so a view that produced several
files lists every file. Add an end-to-end check that an invalid custom
ViewDefinition surfaces the 422 OperationOutcome message.
Update the run, export, and sqlquery-run operation docs for the new
viewReference support, Reference-typed patient/group, Bundle unwrapping,
the spec-shaped export manifest and kick-off acknowledgement, the source
and unsupported-format rejections, the 400/404/422 status semantics, and
the spec conformance canonicals. Credit the additional author on the
significantly changed sqlquery providers.
Align the admin UI export end-to-end mocks with the new completion
manifest: output download files are carried in location parts, and the
non-spec transactionTime and requiresAccessToken fields are removed, so
the card-listing tests exercise the location-reading parser.
Strip media-type parameters (e.g. text/csv;charset=utf-8) before
matching an explicit _format value across the run, export, and
sqlquery-run strict parsers, so a supported media type with parameters
is treated as that format rather than rejected with 400, matching the
spec's content-negotiation edge case.
The strict SQL validator's expression allow-list omitted the named and
positional parameter placeholder expressions, so any parameterised query
(using ":name") failed static validation. This blocked runtime parameter
binding for $sqlquery-run even though the binding machinery was already
present.

Add NamedParameter and PosParameter to the allow-list. They are leaf,
unevaluable value placeholders bound at execution time, so they carry no
code-execution risk.
Implement the SQL on FHIR $sqlquery-export operation, the asynchronous
counterpart to $sqlquery-run, at the system, type, and instance levels.
Clients can run one or more SQL queries against materialised ViewDefinition
tables in the background and download each result as files, following the
FHIR Asynchronous Request Pattern.

Each query produces one output. Table sources can be supplied at request
time, inline or by reference, in addition to being read from server storage.
Supported formats are NDJSON (default), CSV, and Parquet, with patient,
group, and _since filtering. A failed query fails the whole export.

To avoid duplication, extract the shared asynchronous-export machinery into a
new operations/export package (a generic completion-manifest builder, a file
writer, and a filtered data-source builder) reused by both export operations,
and refactor $sqlquery-run onto a shared SqlQueryPipeline that the export also
uses. The Admin UI gains an export affordance on the SQL query result card,
backed by a reusable export-job card shared with the ViewDefinition export.

The operation is declared in the CapabilityStatement against the spec
canonical and gated by a new sqlQueryExportEnabled configuration flag.

Resolves #2633.
Replace the boolean redirectOnComplete marker on the server's asynchronous
machinery with an AsyncPattern enum (STANDARD_ASYNC_PATTERN, BULK_DATA), so the
@AsyncSupported annotation reads as a deliberate choice between two named
patterns rather than the presence or absence of one behaviour.

Correct the Javadoc that misattributed the redirect-based completion to a "SQL
on FHIR unify-async" specification, citing the HL7 Asynchronous Interaction
Request Pattern instead.

Behaviour is unchanged; the existing async tests pass with only their
identifiers updated.
isAnyExportEnabled now also covers the SQL on FHIR asynchronous export
operations, so the all-exports-disabled case must also disable the
viewdefinition-export and sqlquery-export flags, both of which default
to enabled.
The SQL on FHIR export integration tests added to the server module push
the full build-and-test suite past the previous 30-minute job limit,
causing the run to be cancelled before completion. Raise the timeout on
the test, pre-release, and release server workflows so the suite has room
to finish.
The disabled-operation assertion called doesNotContain on its own, which
passes vacuously if the operation list is empty. Assert the still-enabled
sqlquery-run operation is present first, so the test proves the list is
populated and only sqlquery-export was dropped.
@johngrimes johngrimes self-assigned this Jun 22, 2026
@johngrimes johngrimes added release Pull request that represents a new release server Issues relating to Pathling server. labels Jun 22, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in Pathling Jun 22, 2026
@johngrimes johngrimes moved this from Backlog to In progress in Pathling Jun 22, 2026
Resolves twelve Netty advisories reported against 4.1.133.Final,
spanning HTTP/2 denial-of-service, TLS hostname verification bypass,
and DNS resolver issues. All are fixed within the 4.1.x line at
4.1.135.Final, so no move to the 4.2.x series is required. The Netty
BOM remains imported ahead of Spring Boot's so the pinned version
continues to win.
Addresses CVE-2026-55471, an XML external entity vulnerability in
XsltUtilities.saxonTransform via an unhardened Saxon TransformerFactory.
HAPI FHIR 8.10.0 still bundles 6.9.4.1, so the existing override of
org.hl7.fhir.r4 and org.hl7.fhir.utilities is raised from 6.9.7 to the
patched 6.9.10.
Resolves a batch of react-router security advisories by moving to the
latest 7.x release. None of the vulnerable code paths (RSC, SSR, data
routers, the __manifest endpoint) are reachable from the admin UI, which
uses declarative routing only, but upgrading is a low-risk minor bump
that clears the findings and lets the react-router suppressions be
removed from the Trivy ignore list.
Restore the server image's ability to run as either the FHIR server or a
Spark Kubernetes executor, selected by the container's first argument.
Spark on Kubernetes launches executor pods with the single argument
"executor" and no command override, so the role selection lives in the
image entrypoint. A Bash dry-run test covers the role-selection logic
without Docker, a network, or a cluster.
Set the dispatching entrypoint as the image's entry behaviour in both the
docker and dockerPreRelease profiles, copy it into the image via Jib
extraDirectories with executable permissions, and remove the now-dead
jvmFlags (Jib ignores them once an explicit entrypoint is set). Run the
dispatch test during the test phase of these profiles, gated by skipTests.
The citation pointed to the Spark 4.0.0 entrypoint; the runtime is Spark
4.0.2, whose executor branch is identical.
Restore the dual-role server image for Spark on Kubernetes
The Varnish frontend cache previously inherited Varnish's default 60s
first-byte timeout, which caused long-running synchronous Pathling
queries to fail with a 503 before the server could respond.

Expose the timeout as a PATHLING_FIRST_BYTE_TIMEOUT environment variable,
substituted into the backend definition, and surface it through the Helm
chart as pathlingCache.firstByteTimeout (defaulting to the previous 60s).
Introduce a recursive dependency resolver that turns a top-level query's
relatedArtifact references into a topologically ordered graph of resolved
ViewDefinition and SQLView nodes, disambiguating each reference (explicit
type prefix, else ViewDefinition-first with a SQLView fallback) and
deduplicating shared nodes. The executor materialises the graph bottom-up as
request-scoped temp views, rewriting and validating each node's SQL before
running the top-level query. A SQLQuery can now compose a stored SQLView.
Add resolver unit tests and end-to-end run coverage for the dependency-graph
guarantees: a three-level nested chain resolves in topological order, a
diamond shares its node once, the same label denotes different resources in
different nodes without collision, and cyclic, self-referential, and
over-deep graphs are rejected before any SQL executes.
A SQLView Library is now accepted as the top-level resource of $sqlquery-run
and $sqlquery-export, at the system, type, and instance levels, executing as
a parameter-less query. Supplying parameters with a parameter-less SQLView is
rejected, as is a top-level Library whose type is neither sql-query nor
sql-view.
With authorisation enabled, reading a ViewDefinition from storage now
requires READ on ViewDefinition and reading a SQLView Library requires READ
on Library, enforced at every storage-read seam - the standalone $view-run
and $view-export operations, the $sqlquery dependency graph, and the
top-level by-reference query - layered on top of the existing
per-projected-resource checks. A resource supplied inline in the request body
is exempt, as it is not read from storage.
Describe SQLView dependencies and top-level SQLViews on the run and export
operations, the reference-resolution and disambiguation rules, the
cycle/depth rejections, and the metadata-resource READ requirements. Document
the maxDependencyDepth configuration option and the ViewDefinition/Library
READ authorities, with the inline-versus-stored distinction. Mark authorship
on the new and significantly changed files.
Import java.util.List and java.util.ArrayList in the dependency resolver and
its test rather than referencing them inline, for a cleaner reading.
Add a stored SQLView Library bundle fixture (and empty variant) mirroring
the existing SQLQuery fixtures, in preparation for surfacing SQLViews in
the SQL query form.
Generalise the SQLQuery Library list into listStoredLibraries(typeCode),
add the sql-view token filter, and expose a useSqlViews hook so the SQL
query form can fetch SQLViews alongside SQLQueries. SQLQuery listing keeps
its existing query key and behaviour by delegating to the shared core.
Replace the single Library picker with a grouped picker offering stored
SQLQueries and SQLViews, omitting an empty group, and rename the read-only
dependency heading from Tables to Views. A selected SQLView runs and exports
through the unchanged stored path, resolved as Library/<id>.
On the Select query tab the Runtime parameter values section now appears
only when the selected source declares parameters, removing the empty panel
for SQLViews and param-less SQLQueries. The Provide SQL tab keeps the section
always visible to anchor inline parameter authoring.
Rename the inline Tables editor to Views and let each row reference a stored
ViewDefinition or SQLView through a grouped source selector. A collision-safe
composite option value carries the source kind so the assembled query emits
ViewDefinition/<id> or Library/<id> accordingly.
The stored query picker label changed from "SQL query library" to "SQL
query source" when SQLViews joined it; point the export e2e helper at the
new accessible name.
The inline editor's add-row, label, and source controls were renamed when
SQLView references landed; update the inline-authoring e2e paths to match.
The module-level comment described the search endpoint as listing SQLQuery
Libraries only; it now lists both SQLQueries and SQLViews.
The SQL on FHIR ViewDefinition model is a CanonicalResource, but Pathling's
stored encoder model dropped its url and version on ingestion. Retain both as
additive nullable elements so a ViewDefinition can be matched by its canonical
URL when resolving SQL on FHIR dependency references.
A relatedArtifact.resource on a SQLQuery or SQLView is a canonical URL of a
ViewDefinition or SQLView, matched against the referenced resource's url rather
than decomposed into a logical id. Extract the shared url/version parsing and
candidate selection into one helper reused by both the Library and
ViewDefinition paths, resolve ViewDefinitions by filtering on the url column,
reject non-canonical references at parse time, and reject ambiguous and
unresolvable references with named errors. Request-supplied export views are
matched and keyed by url, and a url-less supplied view is rejected.

Bumps the server's Pathling core dependency to pick up the ViewDefinition
url/version retention the resolution relies on.
…n UI

The inline SQL authoring form now binds each table source to its canonical URL
and emits that URL as relatedArtifact.resource on save, so queries authored in
the UI resolve without manual editing. Sources without a URL are listed but
disabled with an explanation, and a stored reference that matches no known
source is surfaced verbatim with a not-found note.
Update the SQL query run/export documentation and runnable examples to
reference ViewDefinitions and SQLViews by canonical URL rather than logical id,
note that a referenceable view must carry a url (and that existing
ViewDefinitions must be re-ingested), and describe the strict, ambiguous, and
not-found error responses.
Align the inline picker's disabled-source note with the wireframe's spaced
hyphen instead of an em-dash.
The spring-boot:run goal launched the server without
--add-opens=java.base/sun.util.calendar=ALL-UNNAMED, so Spark's date
conversion failed with an IllegalAccessException whenever a response
contained date values (for example a $sqlquery-run returning date
columns). The production entrypoint and the test configuration already
supplied this option; only the local run path had drifted.

Centralise the server JVM module options into the
pathling.runtime.jvmModuleOpts and pathling.test.jvmModuleOpts
properties so the run, surefire and failsafe configurations share a
single definition, and note the coupling with the production entrypoint
that a shell script cannot reference at runtime.
The result card left the "Submitted SQL" section blank when running a
stored SQLQuery or SQLView, because the page only captured the SQL text
for inline requests. The form already resolves the selected library's
SQL, so carry it on the stored request (for display only, since the
server still receives just the reference) and recover it through a
shared request-to-SQL helper. The helper also decodes the Base64
content as a fallback for inline requests lacking a sql-text extension.
The result card rendered the submitted SQL in an unbounded box, so a long
query stretched the card far down the page. Extract the existing SQL
preview into a shared, height-bounded component with a copy control and
reuse it for both the stored-query preview and the submitted SQL echoed
in result and error bodies.
Render each referenced view on a single line, clipping overflow with an
ellipsis and surfacing the full reference in a tooltip. Allow the form
column to shrink so it shares width evenly with the results column rather
than being held open by long references.
The static SQL validator walked only a plan's children, but a WITH node
exposes its CTE definition bodies as innerChildren. Relation references
inside a CTE body were therefore never checked against the declared-label
set. An undeclared table named only inside a CTE (such as an OMOP
vocabulary table) slipped past validation and surfaced as an opaque 500
from Spark's analyser instead of a clean rejection.

Descend into CTE bodies during the strict walk so these references are
rejected early with the same "undeclared table" message as top-level
relations.
The SQL validator enforces a strict allow-list of expression types. The ||
concatenation operator parses directly to a Concat expression rather than an
UnresolvedFunction, so it was rejected as a disallowed expression even though
the equivalent concat() function call was permitted as a built-in. Add Concat
to the allow-list so the two spellings behave consistently.
The string-based url and version setters and the null and empty
branches of the corresponding getters, copy, and isEmpty logic were
not exercised, dropping new-code coverage below the SonarCloud quality
gate threshold. Add unit tests covering these paths.
Support SQLView resources and view composition in SQL on FHIR operations
Bumps jackson-databind to 2.22.0 to address seven advisories
(CVE-2026-54512 through CVE-2026-54518). The existing Jackson version
pin was being silently overridden by Spring Boot's managed version
because the Jackson BOM was imported after spring-boot-dependencies;
moving it ahead lets the pin take effect, since the first BOM import
wins in Maven.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Pull request that represents a new release server Issues relating to Pathling server.

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

1 participant