Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(fhir): Validate system URL against version given in subsumption request #982

Merged
merged 1 commit into from
Feb 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix(fhir): Validate system URL against version given in subsumption req.
Also re-arranged code vs. Coding checks in the validation method.
  • Loading branch information
apeteri committed Feb 22, 2022
commit 73207465ae93f7885fadcfbfa3abd5dbd0725d01
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class FhirCodeSystemSubsumesOperationTest extends FhirRestTest {

private static final String PROCEDURE = "71388002";
private static final String ORGANISM_TOP_LEVEL = "410607006";
private static final Object MICROORGANISM = "264395009";

@Test
public void GET_CodeSystem_$subsumes_Subsumes() throws Exception {
Expand Down Expand Up @@ -87,39 +88,35 @@ public class FhirCodeSystemSubsumesOperationTest extends FhirRestTest {
.body("parameter[0].valueCode", equalTo(SubsumptionType.EQUIVALENT.name()));
}

// @Test
// public void subsumedByWithVersionTest() throws Exception {
//
// String responseString = givenAuthenticatedRequest(FHIR_ROOT_CONTEXT)
// .queryParam("codeA", BACTERIA) //Bacteria
// .queryParam("codeB", MICROORGANISM) //Microorganism (parent)
// .queryParam("system", "http:https://snomed.info/sct/900000000000207008/version/20180131")
// .when().get(CODESYSTEM_SUBSUMES)
// .then().assertThat()
// .statusCode(200)
// .extract().asString();
//
// SubsumptionResult result = convertToSubsumptionResult(responseString);
// Assert.assertEquals(SubsumptionType.SUBSUMED_BY, result.getOutcome());
// }
//
// //invalid
// @Test
// public void twoVersionsTest() throws Exception {
//
// givenAuthenticatedRequest(FHIR_ROOT_CONTEXT)
// .queryParam("codeA", BACTERIA) //Bacteria
// .queryParam("codeB", MICROORGANISM) //Microorganism (parent)
// .queryParam("system", "http:https://snomed.info/sct/900000000000207008/version/20170131")
// .queryParam("version", "2018-01-31")
// .when().get(CODESYSTEM_SUBSUMES)
// .then()
// .body("resourceType", equalTo("OperationOutcome"))
// .body("issue.severity", hasItem("error"))
// .body("issue.code", hasItem("invalid"))
// .body("issue.diagnostics", hasItem("Version specified in the URI [http:https://snomed.info/sct/900000000000207008/version/20170131] "
// + "does not match the version set in the request [2018-01-31]"))
// .statusCode(400);
// }
@Test
public void GET_CodeSystem_$subsumes_SubsumedBy_WithVersion() throws Exception {

givenAuthenticatedRequest(FHIR_ROOT_CONTEXT)
.queryParam("codeA", BACTERIA) //Bacteria
.queryParam("codeB", MICROORGANISM) //Microorganism (parent)
.queryParam("system", "http:https://snomed.info/sct/900000000000207008/version/20180131")
.when().get(CODESYSTEM_SUBSUMES)
.then().assertThat()
.statusCode(200)
.body("parameter[0].name", equalTo("outcome"))
.body("parameter[0].valueCode", equalTo(SubsumptionType.SUBSUMED_BY.name()));
}

}
@Test
public void GET_CodeSystem_$subsumes_SubsumedBy_WithAmbiguousVersions() throws Exception {

givenAuthenticatedRequest(FHIR_ROOT_CONTEXT)
.queryParam("codeA", BACTERIA) //Bacteria
.queryParam("codeB", MICROORGANISM) //Microorganism (parent)
.queryParam("system", "http:https://snomed.info/sct/900000000000207008/version/20170131")
.queryParam("version", "2018-01-31")
.when().get(CODESYSTEM_SUBSUMES)
.then()
.body("resourceType", equalTo("OperationOutcome"))
.body("issue[0].severity", equalTo("error"))
.body("issue[0].code", equalTo("invalid"))
.body("issue[0].diagnostics", equalTo("Version specified in the URI [http:https://snomed.info/sct/900000000000207008/version/20170131] "
+ "does not match the version set in the request [2018-01-31]"))
.statusCode(400);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 B2i Healthcare Pte Ltd, http:https://b2i.sg
* Copyright 2021-2022 B2i Healthcare Pte Ltd, http:https://b2i.sg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,9 +15,9 @@
*/
package com.b2international.snowowl.fhir.rest;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import com.b2international.commons.StringUtils;
import com.b2international.snowowl.core.events.util.Promise;
import com.b2international.snowowl.fhir.core.exceptions.BadRequestException;
import com.b2international.snowowl.fhir.core.model.codesystem.SubsumptionRequest;
Expand Down Expand Up @@ -190,51 +190,48 @@ private void validateSubsumptionRequest(String codeSystemId, String codeA, Strin

private void validateSubsumptionRequest(String codeSystemId, String codeA, String codeB, String system, String version, Coding codingA, Coding codingB) {

//check the systems
// check the systems
if (StringUtils.isEmpty(system) && StringUtils.isEmpty(codeSystemId)) {
throw new BadRequestException("Parameter 'system' is not specified for subsumption testing.", "SubsumptionRequest.system");
}

//TODO: this probably incorrect as codeSystemId is an internal id vs. system that is external
if (!StringUtils.isEmpty(system) && !StringUtils.isEmpty(codeSystemId)) {
if (!codeSystemId.equals(system)) {
throw new BadRequestException(String.format("Parameter 'system: %s' and path parameter 'codeSystem: %s' are not the same.", system, codeSystemId), "SubsumptionRequest.system");
}
}

//all empty
if (StringUtils.isEmpty(codeA) && StringUtils.isEmpty(codeA) && codingA == null && codingB == null) {
throw new BadRequestException("No codes or Codings are provided for subsumption testing.", "SubsumptionRequest");
// TODO: this probably incorrect as codeSystemId is an internal id vs. system that is external
if (!StringUtils.isEmpty(system) && !StringUtils.isEmpty(codeSystemId) && !codeSystemId.equals(system)) {
throw new BadRequestException(String.format("Parameter 'system: %s' and path parameter 'codeSystem: %s' are not the same.", system, codeSystemId), "SubsumptionRequest.system");
}

//No codes
if (StringUtils.isEmpty(codeA) && StringUtils.isEmpty(codeA)) {
if (StringUtils.isEmpty(codeA) && StringUtils.isEmpty(codeB)) {
// No codes and no codings
if (codingA == null && codingB == null) {
throw new BadRequestException("No codes or Codings are provided for subsumption testing.", "SubsumptionRequest");
}

// One coding is present, but the other is missing (both can not be missing as it was handled above)
if (codingA == null || codingB == null) {
throw new BadRequestException("No Codings are provided for subsumption testing.", "SubsumptionRequest.Coding");
}
}

//No codings
if (codingA == null && codingB == null) {
if (StringUtils.isEmpty(codeA) || StringUtils.isEmpty(codeB)) {
throw new BadRequestException("No codes are provided for subsumption testing.", "SubsumptionRequest.code");
}
}

//Codes are there
if (!StringUtils.isEmpty(codeA) && !StringUtils.isEmpty(codeA)) {

// Both codings are present at this point

} else {

// Some codes were provided, but a coding is also present, ambiguous
if (codingA != null || codingB != null) {
throw new BadRequestException("Provide either codes or Codings.", "SubsumptionRequest");
}
}

//Coding are there
if (codingA != null && codingB != null) {
if (!StringUtils.isEmpty(codeA) || !StringUtils.isEmpty(codeA)) {
throw new BadRequestException("Provide either codes or Codings.", "SubsumptionRequest");

// One code is present, but the other is missing (both can not be missing as it was handled in the outer "if" block above)
if (StringUtils.isEmpty(codeA) || StringUtils.isEmpty(codeB)) {
throw new BadRequestException("No codes are provided for subsumption testing.", "SubsumptionRequest.code");
}

// Both codes are present at this point
}
}


// Check system (URL) against version
if (!StringUtils.isEmpty(system) && !StringUtils.isEmpty(version) && !system.endsWith("/" + version)) {
throw new BadRequestException(String.format("Version specified in the URI [%s] does not match the version set in the request [%s]",
system, version));
}
}
}