Skip to content

adds support for federated terminology provider - #905

Merged
c-schuler merged 12 commits into
masterfrom
feature-federated-terminology
Feb 26, 2026
Merged

c-schuler merged 12 commits into
masterfrom
feature-federated-terminology

Conversation

@raleigh-g-thompson

Copy link
Copy Markdown
Contributor

Still a WIP, working on tests

@github-actions

github-actions Bot commented Feb 2, 2026 •

Copy link
Copy Markdown

Formatting check succeeded!

applies spotless

@c-schuler c-schuler left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I see implemented:

  1. Infrastructure for federated routing - The FederatedTerminologyProviderRouter and related interfaces are in place
  2. Client-level VSAC detection - VsacTerminologyServerClient.isCanonicalMatch() detects VSAC URLs via regex: https*://cts.nlm.nih.gov/fhir.*
  3. Endpoint prioritization logic - prioritizeEndpoints() can sort endpoints by URL matching
  4. Single terminologyEndpoint support - Works as before, one endpoint for all terminology

These are the gaps I see:

CRMI Requirement │ Current State
Parse artifactEndpointConfiguration │ Throws NotImplementedOperationException
Route based on artifactRoute │ Not implemented
Support multiple endpoints │ Router methods exist but aren't called
Priority by match length │ prioritizeEndpoints() uses boolean match, not character count

Do you agree with my assessment of what is implemented and the gaps with CRMI?

@codecov

codecov Bot commented Feb 3, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.45631% with 150 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.55%. Comparing base (b83fd67) to head (b9aeb6e).

Files with missing lines Patch % Lines
...erminology/FederatedTerminologyProviderRouter.java 10.31% 112 Missing and 1 partial ⚠️
.../org/opencds/cqf/fhir/cr/visitor/ExpandHelper.java 50.00% 15 Missing and 1 partial ⚠️
...y/client/terminology/ITerminologyServerClient.java 78.57% 3 Missing and 3 partials ⚠️
...org/opencds/cqf/fhir/cr/visitor/VisitorHelper.java 84.00% 0 Missing and 4 partials ⚠️
...ent/terminology/ArtifactEndpointConfiguration.java 88.57% 2 Missing and 2 partials ⚠️
...nt/terminology/GenericTerminologyServerClient.java 66.66% 3 Missing ⚠️
...lient/terminology/VsacTerminologyServerClient.java 84.21% 2 Missing and 1 partial ⚠️
...rg/opencds/cqf/fhir/cr/visitor/ReleaseVisitor.java 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #905      +/-   ##
============================================
- Coverage     73.82%   73.55%   -0.28%     
  Complexity      364      364              
============================================
  Files           601      606       +5     
  Lines         29548    29758     +210     
  Branches       3923     3944      +21     
============================================
+ Hits          21815    21888      +73     
- Misses         5818     5946     +128     
- Partials       1915     1924       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@c-schuler

Copy link
Copy Markdown
Contributor

Summary of updates:

  1. Model Layer (cqf-fhir-utility)

ArtifactEndpointConfiguration.java - New class

  • Holds artifactRoute, endpointUri, endpoint
  • getMatchScore(canonicalUrl) - returns match length or -1 (no match) or 0 (fallback)
  • getEffectiveEndpoint(FhirContext) - creates endpoint from either endpoint or endpointUri
  1. Router Layer (cqf-fhir-utility)

ITerminologyProviderRouter.java - Added methods:

  • expandWithConfigurations()
  • getValueSetResourceWithConfigurations()
  • getCodeSystemResourceWithConfigurations()

FederatedTerminologyProviderRouter.java - Implemented:

  • prioritizeConfigurations() - CRMI ranking by match length, preserving input order for ties
  • All new interface methods with fallback-on-failure logic
  1. Visitor Layer (cqf-fhir-cr)

VisitorHelper.java - Added:

  • getArtifactEndpointConfigurations() - parses nested parameter structure

ExpandHelper.java - Added:

  • Overloaded expandValueSet() accepting List
  • Tries CRMI routing first, falls back to legacy single endpoint

PackageVisitor.java - Updated:

  • Parses artifactEndpointConfiguration from parameters
  • Passes configurations through to handleValueSets() and expandValueSet()
  • Removed the NotImplementedOperationException

@c-schuler
c-schuler self-requested a review February 3, 2026 17:48
@c-schuler
c-schuler marked this pull request as ready for review February 3, 2026 17:48

@raleigh-g-thompson raleigh-g-thompson left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No changes recommended.

I can't approve though since I'm also one of the authors.

@sliver007

Copy link
Copy Markdown
Collaborator

The artifactEnpointConfiguration path should be aware of and respect the authoritativeSource extension - if an authoritativeSource is specified, it should be used in the comparison logic for endpoint resolution rather than the artifact's URL/canonical.


@Override
public boolean isCanonicalMatch(String address) {
return address.matches("https*://cts.nlm.nih.gov/fhir.*");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this bit, the client shouldn't be involved in the routing configuration.

- Add buildResourceIdForExpand() to handle VSAC's non-standard URL format where version is appended with a dash (ValueSet/id-version) instead of the standard pipe separator
- Add formatParametersForLogging() and formatParameterValue() helpers for structured debug output of expansion parameters
- Enhance expansion attempt logging with terminology server base URL, full expand URL, and parameter details
- Change failure logging from info to warn level with additional context
FederatedTerminologyProviderRouterTest (16 tests):
  - List-based expand overloads exercising prioritizeEndpoints and stream filtering
  - List-based getValueSetResource, getCodeSystemResource, getLatestValueSetResource
  - Empty endpoint list edge cases
  - Exception catch-and-fallback paths in expandWithConfigurations, getValueSetResourceWithConfigurations, getCodeSystemResourceWithConfigurations

ExpandRunnerTest (2 tests):
  - Transient server error (500) retry path exercising isTransient() true branch
  - Part-parameters formatting exercising formatParameterValue hasPart() branch

GenericTerminologyServerClientClientTest (3 tests):
  - Null URL with no url parameter throws UnprocessableEntityException
  - initializeClientWithAuth with endpoint headers exercises hasHeaders() branch
  - Single-arg constructor exercises default settings fallback

ArtifactEndpointConfigurationTest (8 tests):
  - Optional getters for artifactRoute, endpointUri, endpoint (present and empty)
  - toString with non-null endpoint resource
@sonarqubecloud

Copy link
Copy Markdown

@c-schuler
c-schuler merged commit b2f1f3d into master Feb 26, 2026
9 checks passed
@c-schuler
c-schuler deleted the feature-federated-terminology branch February 26, 2026 17:41
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.

4 participants