Skip to content

Commit

Permalink
Fixing concurrency issue in VersionSpecificWorkerContextWrapper (hapi…
Browse files Browse the repository at this point in the history
…fhir#6554)

When validating if a code is valid against a ValueSet, a potentially
cached (and therefore shared) result object was mutated. This mutation
is now done on a copy of the result object.
  • Loading branch information
Boereck committed Dec 17, 2024
1 parent 6d7f94b commit 8e03631
Showing 1 changed file with 30 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.IValidationSupport.BaseConceptProperty;
import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationIssue;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
Expand Down Expand Up @@ -825,6 +827,7 @@ private IValidationSupport.CodeValidationResult validateCodeInValueSet(
final boolean valueSetResultContainsInvalidDisplay = result.getIssues().stream()
.anyMatch(VersionSpecificWorkerContextWrapper::hasInvalidDisplayDetailCode);
if (codeSystemResult != null) {
result = copyCodeValidationResult(result);
for (IValidationSupport.CodeValidationIssue codeValidationIssue : codeSystemResult.getIssues()) {
/* Value set validation should already have checked the display name. If we get INVALID_DISPLAY
issues from code system validation, they will only repeat what was already caught.
Expand All @@ -838,6 +841,33 @@ private IValidationSupport.CodeValidationResult validateCodeInValueSet(
return result;
}

private IValidationSupport.CodeValidationResult copyCodeValidationResult(
IValidationSupport.CodeValidationResult toCopy) {
IValidationSupport.CodeValidationResult result = new IValidationSupport.CodeValidationResult();

List<CodeValidationIssue> issues = toCopy.getIssues();
List<BaseConceptProperty> properties = toCopy.getProperties();

result.setCode(toCopy.getCode())
.setCodeSystemName(toCopy.getCodeSystemName())
.setCodeSystemVersion(toCopy.getCodeSystemVersion())
.setDisplay(toCopy.getDisplay())
.setIssues(copyList(issues))
.setMessage(toCopy.getMessage())
.setSeverity(toCopy.getSeverity())
.setSourceDetails(toCopy.getSourceDetails())
.setProperties(copyList(properties));
return result;
}

private <T> List<T> copyList(List<T> issues) {
if (issues == null) {
return null;
} else {
return new ArrayList<>(issues);
}
}

private static boolean hasInvalidDisplayDetailCode(IValidationSupport.CodeValidationIssue theIssue) {
return theIssue.hasIssueDetailCode(INVALID_DISPLAY.getCode());
}
Expand Down

0 comments on commit 8e03631

Please sign in to comment.