Skip to content

Commit aa721d0

Browse files
committed
ValueSet expansion workaround for version wildcard includes
1 parent 04fe813 commit aa721d0

8 files changed

+161
-4
lines changed

src/main/java/dev/dsf/fhir/validator/client/TerminologyServerClient.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package dev.dsf.fhir.validator.client;
22

3+
import java.util.List;
34
import java.util.Objects;
45

56
import org.hl7.fhir.r4.model.CapabilityStatement;
7+
import org.hl7.fhir.r4.model.CodeSystem;
68
import org.hl7.fhir.r4.model.Coding;
79
import org.hl7.fhir.r4.model.OperationOutcome;
810
import org.hl7.fhir.r4.model.ValueSet;
@@ -15,6 +17,14 @@ record ValidationResult(boolean result, String message, OperationOutcome outome)
1517
{
1618
}
1719

20+
record UrlAndVersion(String url, String version)
21+
{
22+
public static UrlAndVersion fromCodeSystem(CodeSystem cs)
23+
{
24+
return new UrlAndVersion(cs.getUrl(), cs.getVersion());
25+
}
26+
}
27+
1828
/**
1929
* @param valueSet
2030
* not <code>null</code>
@@ -55,4 +65,12 @@ default ValidationResult validate(String system, String code, String display, St
5565

5666
return validate(new Coding(system, code, display).setVersion(version));
5767
}
68+
69+
/**
70+
* @param url
71+
* not <code>null</code>
72+
* @return
73+
* @throws WebApplicationException
74+
*/
75+
List<UrlAndVersion> getSupportedCodeSystemVersion(String url) throws WebApplicationException;
5876
}

src/main/java/dev/dsf/fhir/validator/client/TerminologyServerClientJersey.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.dsf.fhir.validator.client;
22

33
import java.security.KeyStore;
4+
import java.util.List;
45
import java.util.Objects;
56
import java.util.concurrent.TimeUnit;
67
import java.util.logging.Level;
@@ -15,7 +16,10 @@
1516
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJsonProvider;
1617
import org.glassfish.jersey.logging.LoggingFeature;
1718
import org.glassfish.jersey.logging.LoggingFeature.Verbosity;
19+
import org.hl7.fhir.r4.model.Bundle;
20+
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
1821
import org.hl7.fhir.r4.model.CapabilityStatement;
22+
import org.hl7.fhir.r4.model.CodeSystem;
1923
import org.hl7.fhir.r4.model.Coding;
2024
import org.hl7.fhir.r4.model.OperationOutcome;
2125
import org.hl7.fhir.r4.model.Parameters;
@@ -143,4 +147,16 @@ public CapabilityStatement getMetadata() throws WebApplicationException
143147
{
144148
return getResource().path("metadata").request(Constants.CT_FHIR_JSON_NEW).get(CapabilityStatement.class);
145149
}
150+
151+
@Override
152+
public List<UrlAndVersion> getSupportedCodeSystemVersion(String url) throws WebApplicationException
153+
{
154+
Bundle resultBundle = getResource().path("CodeSystem").queryParam("url", url).queryParam("_summary", "true")
155+
.request(Constants.CT_FHIR_JSON_NEW).get(Bundle.class);
156+
157+
return resultBundle.getEntry().stream().filter(BundleEntryComponent::hasResource)
158+
.map(BundleEntryComponent::getResource).filter(r -> r instanceof CodeSystem).map(r -> (CodeSystem) r)
159+
.filter(cs -> cs.hasVersionElement() && cs.getVersionElement().hasValue())
160+
.map(UrlAndVersion::fromCodeSystem).distinct().toList();
161+
}
146162
}

src/main/java/dev/dsf/fhir/validator/main/ValidationConfig.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import dev.dsf.fhir.validator.value_set.ValueSetExpanderImpl;
5757
import dev.dsf.fhir.validator.value_set.ValueSetExpanderWithFileSystemCache;
5858
import dev.dsf.fhir.validator.value_set.ValueSetExpanderWithModifiers;
59+
import dev.dsf.fhir.validator.value_set.ValueSetExpansionClientStarVersion;
5960
import dev.dsf.fhir.validator.value_set.ValueSetExpansionClientWithFileSystemCache;
6061
import dev.dsf.fhir.validator.value_set.ValueSetExpansionClientWithModifiers;
6162
import dev.dsf.fhir.validator.value_set.ValueSetModifier;
@@ -400,7 +401,8 @@ private ValidationPackageClientJersey validationPackageClientJersey()
400401
public TerminologyServerClient terminologyServerClient()
401402
{
402403
return new ValueSetExpansionClientWithFileSystemCache(valueSetCacheFolder(), fhirContext(),
403-
new ValueSetExpansionClientWithModifiers(terminologyServerClientJersey(), valueSetModifiers()),
404+
new ValueSetExpansionClientWithModifiers(
405+
new ValueSetExpansionClientStarVersion(terminologyServerClientJersey()), valueSetModifiers()),
404406
valueSetCacheDraftResources);
405407
}
406408

src/main/java/dev/dsf/fhir/validator/service/ResourceValidatorImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public boolean resolveURL(IResourceValidator validator, Object appContext, Strin
6161
else if (url != null && url.startsWith("urn:uuid:") && url.length() == 45
6262
&& ("uri".equals(type) || "url".equals(type)) && !canonical)
6363
return true;
64+
else if (url != null && url.startsWith("urn:oid:") && "uri".equals(type) && !canonical)
65+
return true;
6466
else if (url != null && (url.startsWith("http://") || url.startsWith("https://"))
6567
&& ("uri".equals(type) || "canonical".equals(type)))
6668
return true;

src/main/java/dev/dsf/fhir/validator/service/ValidatorFactoryImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ private ValidationSupportChain createSupportChain(FhirContext context,
343343
new NonValidatingValidationSupport(context, "http://fhir.de/CodeSystem/bfarm/icd-10-gm",
344344
"http://fhir.de/CodeSystem/dimdi/icd-10-gm", "http://fhir.de/CodeSystem/bfarm/ops",
345345
"http://fhir.de/CodeSystem/dimdi/ops", "http://fhir.de/CodeSystem/ifa/pzn",
346-
"http://snomed.info/sct", "http://loinc.org"));
346+
"http://snomed.info/sct", "http://loinc.org", "http://varnomen.hgvs.org"));
347347
}
348348

349349
private <V> List<V> getAll(Function<ValidationPackageWithDepedencies, List<V>> mapper,
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package dev.dsf.fhir.validator.value_set;
2+
3+
import java.util.Comparator;
4+
import java.util.List;
5+
import java.util.Objects;
6+
import java.util.Optional;
7+
import java.util.function.Function;
8+
9+
import org.hl7.fhir.r4.model.CapabilityStatement;
10+
import org.hl7.fhir.r4.model.Coding;
11+
import org.hl7.fhir.r4.model.ValueSet;
12+
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
import org.springframework.beans.factory.InitializingBean;
16+
17+
import dev.dsf.fhir.validator.client.TerminologyServerClient;
18+
import jakarta.ws.rs.WebApplicationException;
19+
20+
public class ValueSetExpansionClientStarVersion implements TerminologyServerClient, InitializingBean
21+
{
22+
private static final Logger logger = LoggerFactory.getLogger(ValueSetExpansionClientStarVersion.class);
23+
24+
private final TerminologyServerClient delegate;
25+
26+
public ValueSetExpansionClientStarVersion(TerminologyServerClient delegate)
27+
{
28+
this.delegate = delegate;
29+
}
30+
31+
@Override
32+
public void afterPropertiesSet() throws Exception
33+
{
34+
Objects.requireNonNull(delegate, "delegate");
35+
}
36+
37+
@Override
38+
public ValueSet expand(ValueSet valueSet) throws WebApplicationException
39+
{
40+
Objects.requireNonNull(valueSet, "valueSet");
41+
42+
Optional<String> starSystem = valueSet.getCompose().getInclude().size() != 1 ? Optional.empty()
43+
: valueSet.getCompose().getInclude().stream()
44+
.filter(i -> i.hasVersionElement() && i.getVersionElement().hasValue()
45+
&& "*".equals(i.getVersion()) && i.hasSystemElement()
46+
&& i.getSystemElement().hasValue())
47+
.map(ConceptSetComponent::getSystem).findFirst();
48+
49+
return starSystem.map(s ->
50+
{
51+
getSupportedCodeSystemVersion(s).stream().sorted(Comparator.comparing(UrlAndVersion::version))
52+
.map(expandForVersion(valueSet.copy()))
53+
.forEach(v -> valueSet.getExpansion().getContains().addAll(v.getExpansion().getContains()));
54+
55+
return valueSet;
56+
57+
}).orElseGet(() -> delegate.expand(valueSet));
58+
}
59+
60+
private Function<UrlAndVersion, ValueSet> expandForVersion(ValueSet valueSet)
61+
{
62+
return urlAndVersion ->
63+
{
64+
logger.debug("Expanding ValueSet {}|{} with version wildcard include for CodeSystem {}|{}",
65+
valueSet.getUrl(), valueSet.getVersion(), urlAndVersion.url(), urlAndVersion.version());
66+
67+
valueSet.getCompose().setInclude(null);
68+
valueSet.getCompose().addInclude().setSystem(urlAndVersion.url()).setVersion(urlAndVersion.version());
69+
70+
ValueSet expanded = delegate.expand(valueSet);
71+
expanded.getExpansion().getContains().stream().forEach(c -> c.setVersion(urlAndVersion.version()));
72+
return expanded;
73+
};
74+
}
75+
76+
@Override
77+
public CapabilityStatement getMetadata() throws WebApplicationException
78+
{
79+
return delegate.getMetadata();
80+
}
81+
82+
@Override
83+
public ValidationResult validate(Coding coding) throws WebApplicationException
84+
{
85+
Objects.requireNonNull(coding, "coding");
86+
87+
return delegate.validate(coding);
88+
}
89+
90+
@Override
91+
public List<UrlAndVersion> getSupportedCodeSystemVersion(String url) throws WebApplicationException
92+
{
93+
Objects.requireNonNull(url, "url");
94+
95+
return delegate.getSupportedCodeSystemVersion(url);
96+
}
97+
}

src/main/java/dev/dsf/fhir/validator/value_set/ValueSetExpansionClientWithFileSystemCache.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.InputStream;
44
import java.io.OutputStream;
55
import java.nio.file.Path;
6+
import java.util.List;
67
import java.util.Objects;
78
import java.util.function.Function;
89

@@ -95,6 +96,8 @@ public ValueSet expand(ValueSet valueSet) throws WebApplicationException
9596

9697
private ValueSet expandAndWriteToCache(ValueSet valueSet)
9798
{
99+
Objects.requireNonNull(valueSet, "valueSet");
100+
98101
ValueSet expanded = delegate.expand(valueSet);
99102

100103
if (PublicationStatus.DRAFT.equals(expanded.getStatus()) && !cacheDraftResources)
@@ -116,6 +119,16 @@ public CapabilityStatement getMetadata() throws WebApplicationException
116119
@Override
117120
public ValidationResult validate(Coding coding) throws WebApplicationException
118121
{
122+
Objects.requireNonNull(coding, "coding");
123+
119124
return delegate.validate(coding);
120125
}
126+
127+
@Override
128+
public List<UrlAndVersion> getSupportedCodeSystemVersion(String url) throws WebApplicationException
129+
{
130+
Objects.requireNonNull(url, "url");
131+
132+
return delegate.getSupportedCodeSystemVersion(url);
133+
}
121134
}

src/main/java/dev/dsf/fhir/validator/value_set/ValueSetExpansionClientWithModifiers.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ public void afterPropertiesSet() throws Exception
3636
@Override
3737
public ValueSet expand(ValueSet valueSet) throws WebApplicationException
3838
{
39-
if (valueSet == null)
40-
return null;
39+
Objects.requireNonNull(valueSet, "valueSet");
4140

4241
for (ValueSetModifier modifier : valueSetModifiers)
4342
valueSet = modifier.modifyPreExpansion(valueSet);
@@ -59,6 +58,16 @@ public CapabilityStatement getMetadata() throws WebApplicationException
5958
@Override
6059
public ValidationResult validate(Coding coding) throws WebApplicationException
6160
{
61+
Objects.requireNonNull(coding, "coding");
62+
6263
return delegate.validate(coding);
6364
}
65+
66+
@Override
67+
public List<UrlAndVersion> getSupportedCodeSystemVersion(String url) throws WebApplicationException
68+
{
69+
Objects.requireNonNull(url, "url");
70+
71+
return delegate.getSupportedCodeSystemVersion(url);
72+
}
6473
}

0 commit comments

Comments
 (0)