Implement revision suggestions. Add changelog.

This commit is contained in:
juan.marchionatto 2021-09-23 11:55:50 -04:00
parent 81a4f0c78f
commit 751c5d0d05
16 changed files with 179 additions and 109 deletions

View File

@ -0,0 +1,4 @@
---
type: add
issue: 2851
title: "Allows to upload not-current version of LOINC ValueSet(s)."

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.TermReadSvcUtil;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.SortOrderEnum;
@ -62,6 +63,8 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_GENERIC_VALUESET_URL_PLUS_SLASH;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
/**
* This class is a {@link IValidationSupport Validation support} module that loads
@ -73,10 +76,6 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
private static final Logger ourLog = LoggerFactory.getLogger(JpaPersistedResourceValidationSupport.class);
public static final String LOINC_GENERIC_CODE_SYSTEM_URL = "http://loinc.org";
public static final String LOINC_GENERIC_VALUESET_URL = LOINC_GENERIC_CODE_SYSTEM_URL + "/vs";
public static final String LOINC_GENERIC_VALUESET_URL_PLUS_SLASH = LOINC_GENERIC_VALUESET_URL + "/";
private final FhirContext myFhirContext;
private final IBaseResource myNoMatch;
@ -107,7 +106,7 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
@Override
public IBaseResource fetchCodeSystem(String theSystem) {
if (myTermReadSvc.isLoincNotGenericUnversionedCodeSystem(theSystem)) {
if (TermReadSvcUtil.isLoincNotGenericUnversionedCodeSystem(theSystem)) {
Optional<IBaseResource> currentCSOpt = getCodeSystemCurrentVersion(new UriType(theSystem));
if (! currentCSOpt.isPresent()) {
ourLog.info("Couldn't find current version of CodeSystem: " + theSystem);
@ -123,18 +122,18 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
* version is always pointed by the ForcedId for the no-versioned CS
*/
private Optional<IBaseResource> getCodeSystemCurrentVersion(UriType theUrl) {
if (! theUrl.getValueAsString().contains("loinc")) return Optional.empty();
if (! theUrl.getValueAsString().contains(LOINC_LOW)) return Optional.empty();
return myTermReadSvc.readCodeSystemByForcedId("loinc");
return myTermReadSvc.readCodeSystemByForcedId(LOINC_LOW);
}
@Override
public IBaseResource fetchValueSet(String theSystem) {
if (myTermReadSvc.isLoincNotGenericUnversionedValueSet(theSystem)) {
if (TermReadSvcUtil.isLoincNotGenericUnversionedValueSet(theSystem)) {
Optional<IBaseResource> currentVSOpt = getValueSetCurrentVersion(new UriType(theSystem));
return currentVSOpt.orElseThrow(() -> new ResourceNotFoundException(
"Couldn't find current version ValueSet for url: " + theSystem));
"Unable to find current version of ValueSet for url: " + theSystem));
}
return fetchResource(myValueSetType, theSystem);
@ -145,7 +144,7 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
* version is always pointed by the ForcedId for the no-versioned VS
*/
private Optional<IBaseResource> getValueSetCurrentVersion(UriType theUrl) {
if (myTermReadSvc.mustReturnEmptyValueSet(theUrl.getValueAsString())) return Optional.empty();
if (TermReadSvcUtil.mustReturnEmptyValueSet(theUrl.getValueAsString())) return Optional.empty();
String forcedId = theUrl.getValue().substring(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH.length());
if (StringUtils.isBlank(forcedId)) return Optional.empty();

View File

@ -56,6 +56,7 @@ import java.util.Set;
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
@ -181,7 +182,7 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
public DaoMethodOutcome create(CodeSystem theResource, String theIfNoneExist, boolean thePerformIndexing,
@Nonnull TransactionDetails theTransactionDetails, RequestDetails theRequestDetails) {
// loinc CodeSystem must have an ID
if (isNotBlank(theResource.getUrl()) && theResource.getUrl().contains("loinc")
if (isNotBlank(theResource.getUrl()) && theResource.getUrl().contains(LOINC_LOW)
&& isBlank(theResource.getIdElement().getIdPart())) {
throw new InvalidParameterException("'loinc' CodeSystem must have an ID");
}

View File

@ -173,8 +173,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.dao.JpaPersistedResourceValidationSupport.LOINC_GENERIC_VALUESET_URL;
import static ca.uhn.fhir.jpa.dao.JpaPersistedResourceValidationSupport.LOINC_GENERIC_VALUESET_URL_PLUS_SLASH;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
@ -183,6 +181,8 @@ import static org.apache.commons.lang3.StringUtils.isNoneBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.lowerCase;
import static org.apache.commons.lang3.StringUtils.startsWithIgnoreCase;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_GENERIC_VALUESET_URL_PLUS_SLASH;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
public static final int DEFAULT_FETCH_SIZE = 250;
@ -2342,14 +2342,14 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
/**
* When the search is for no-version loinc system it uses the forcedId to obtain the current
* When the search is for unversioned loinc system it uses the forcedId to obtain the current
* version, as it is not necessarily the last one anymore.
* For other cases it keeps on considering the last uploaded as the current
*/
@Override
public Optional<TermValueSet> findCurrentTermValueSet(String theUrl) {
if (isLoincNotGenericUnversionedValueSet(theUrl)) {
if (mustReturnEmptyValueSet(theUrl)) return Optional.empty();
if (TermReadSvcUtil.isLoincNotGenericUnversionedValueSet(theUrl)) {
if (TermReadSvcUtil.mustReturnEmptyValueSet(theUrl)) return Optional.empty();
String forcedId = theUrl.substring(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH.length());
if (StringUtils.isBlank(forcedId)) return Optional.empty();
@ -2363,38 +2363,6 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
}
@Override
public boolean mustReturnEmptyValueSet(String theUrl) {
if (! theUrl.startsWith(LOINC_GENERIC_VALUESET_URL)) return true;
if (! theUrl.startsWith(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH)) {
throw new InternalErrorException("Don't know how to extract ForcedId from url: " + theUrl);
}
String forcedId = theUrl.substring(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH.length());
return StringUtils.isBlank(forcedId);
}
@Override
public boolean isLoincNotGenericUnversionedValueSet(String theUrl) {
boolean isLoincCodeSystem = StringUtils.containsIgnoreCase(theUrl, "loinc");
boolean isNoVersion = ! theUrl.contains("|");
boolean isNotLoincGenericValueSet = ! theUrl.equals(LOINC_GENERIC_VALUESET_URL);
return isLoincCodeSystem && isNoVersion && isNotLoincGenericValueSet;
}
@Override
public boolean isLoincNotGenericUnversionedCodeSystem(String theUrl) {
boolean isLoincCodeSystem = StringUtils.containsIgnoreCase(theUrl, "loinc");
boolean isNoVersion = ! theUrl.contains("|");
return isLoincCodeSystem && isNoVersion;
}
@SuppressWarnings("unchecked")
private CodeValidationResult codeSystemValidateCode(String theCodeSystemUrl, String theCodeSystemVersion, String theCode, String theDisplay) {
@ -2426,7 +2394,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
if (isNoneBlank(theCodeSystemVersion)) {
predicates.add(criteriaBuilder.equal(systemVersionJoin.get("myCodeSystemVersionId"), theCodeSystemVersion));
} else {
if (theCodeSystemUrl.toLowerCase(Locale.ROOT).contains("loinc")) {
if (theCodeSystemUrl.toLowerCase(Locale.ROOT).contains(LOINC_LOW)) {
predicates.add(criteriaBuilder.isNull(systemVersionJoin.get("myCodeSystemVersionId")));
} else {
query.orderBy(criteriaBuilder.desc(root.get("myUpdated")));

View File

@ -88,6 +88,7 @@ import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
private static final Logger ourLog = LoggerFactory.getLogger(TermCodeSystemStorageSvcImpl.class);
@ -140,8 +141,8 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
CodeSystem codeSystemResource = new CodeSystem();
codeSystemResource.setUrl(theSystem);
codeSystemResource.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT);
if (isBlank(codeSystemResource.getIdElement().getIdPart()) && theSystem.contains("loinc")) {
codeSystemResource.setId("loinc");
if (isBlank(codeSystemResource.getIdElement().getIdPart()) && theSystem.contains(LOINC_LOW)) {
codeSystemResource.setId(LOINC_LOW);
}
myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(codeSystemResource);

View File

@ -0,0 +1,62 @@
package ca.uhn.fhir.jpa.term;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.commons.lang3.StringUtils;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_GENERIC_VALUESET_URL;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_GENERIC_VALUESET_URL_PLUS_SLASH;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
public class TermReadSvcUtil {
public static boolean mustReturnEmptyValueSet(String theUrl) {
if (! theUrl.startsWith(LOINC_GENERIC_VALUESET_URL)) return true;
if (! theUrl.startsWith(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH)) {
throw new InternalErrorException("Don't know how to extract ValueSet's ForcedId from url: " + theUrl);
}
String forcedId = theUrl.substring(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH.length());
return StringUtils.isBlank(forcedId);
}
public static boolean isLoincNotGenericUnversionedValueSet(String theUrl) {
boolean isLoincCodeSystem = StringUtils.containsIgnoreCase(theUrl, LOINC_LOW);
boolean isNoVersion = ! theUrl.contains("|");
boolean isNotLoincGenericValueSet = ! theUrl.equals(LOINC_GENERIC_VALUESET_URL);
return isLoincCodeSystem && isNoVersion && isNotLoincGenericValueSet;
}
public static boolean isLoincNotGenericUnversionedCodeSystem(String theUrl) {
boolean isLoincCodeSystem = StringUtils.containsIgnoreCase(theUrl, LOINC_LOW);
boolean isNoVersion = ! theUrl.contains("|");
return isLoincCodeSystem && isNoVersion;
}
}

View File

@ -36,6 +36,7 @@ import org.springframework.context.event.EventListener;
import java.security.InvalidParameterException;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
private IFhirResourceDao<ConceptMap> myConceptMapResourceDao;
@ -65,8 +66,8 @@ public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl imple
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
validateCodeSystemForStorage(theCodeSystemResource);
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
if (theCodeSystemResource.getUrl().contains("loinc")) {
throw new InvalidParameterException("LOINC CodeSystem must have an 'ID' element");
if (theCodeSystemResource.getUrl().contains(LOINC_LOW)) {
throw new InvalidParameterException("'loinc' CodeSystem must have an 'ID' element");
}
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
return myCodeSystemResourceDao.update(theCodeSystemResource, matchUrl, theRequestDetails).getId();

View File

@ -124,18 +124,6 @@ public interface ITermReadSvc extends IValidationSupport {
/**
* Version independent
*/
boolean mustReturnEmptyValueSet(String theUrl);
/**
* Version independent
*/
boolean isLoincNotGenericUnversionedCodeSystem(String theSystem);
/**
* Version independent
*/
boolean isLoincNotGenericUnversionedValueSet(String theUrl);
Optional<IBaseResource> readCodeSystemByForcedId(String theForcedId);
}

View File

@ -34,12 +34,14 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.function.Function;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
@ -47,7 +49,6 @@ import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class JpaPersistedResourceValidationSupportTest {
@ -59,7 +60,7 @@ class JpaPersistedResourceValidationSupportTest {
@Mock private Cache<String, IBaseResource> myLoadCache;
@Mock private IFhirResourceDao<ValueSet> myValueSetResourceDao;
@InjectMocks
private IValidationSupport testedClass =
new JpaPersistedResourceValidationSupport(theFhirContext);
@ -69,10 +70,6 @@ class JpaPersistedResourceValidationSupportTest {
@BeforeEach
public void setup() {
ReflectionTestUtils.setField(testedClass, "myTermReadSvc", myTermReadSvc);
ReflectionTestUtils.setField(testedClass, "myDaoRegistry", myDaoRegistry);
ReflectionTestUtils.setField(testedClass, "myLoadCache", myLoadCache);
ReflectionTestUtils.setField(testedClass, "myCodeSystemType", myCodeSystemType);
ReflectionTestUtils.setField(testedClass, "myValueSetType", myValueSetType);
}
@ -82,22 +79,18 @@ class JpaPersistedResourceValidationSupportTest {
@Test
void fetchCodeSystemMustUseForcedId() {
when(myTermReadSvc.isLoincNotGenericUnversionedCodeSystem(anyString())).thenReturn(true);
testedClass.fetchCodeSystem("string-containing-loinc");
verify(myTermReadSvc, times(1)).readCodeSystemByForcedId("loinc");
verify(myTermReadSvc, times(1)).readCodeSystemByForcedId(LOINC_LOW);
verify(myLoadCache, never()).get(anyString(), isA(Function.class));
}
@Test
void fetchCodeSystemMustNotUseForcedId() {
when(myTermReadSvc.isLoincNotGenericUnversionedCodeSystem(anyString())).thenReturn(false);
testedClass.fetchCodeSystem("string-not-containing-l-o-i-n-c");
verify(myTermReadSvc, never()).readCodeSystemByForcedId("loinc");
verify(myTermReadSvc, never()).readCodeSystemByForcedId(LOINC_LOW);
verify(myLoadCache, times(1)).get(anyString(), isA(Function.class));
}
@ -109,21 +102,17 @@ class JpaPersistedResourceValidationSupportTest {
@Test
void fetchValueSetMustUseForcedId() {
when(myTermReadSvc.isLoincNotGenericUnversionedValueSet(anyString())).thenReturn(true);
when(myDaoRegistry.getResourceDao(ValueSet.class)).thenReturn(myValueSetResourceDao);
final String valueSetId = "string-containing-loinc";
ResourceNotFoundException thrown = assertThrows(
ResourceNotFoundException.class,
() -> testedClass.fetchValueSet("string-containing-loinc"));
() -> testedClass.fetchValueSet(valueSetId));
assertTrue(thrown.getMessage().contains("Couldn't find current version ValueSet for url"));
assertTrue(thrown.getMessage().contains("Unable to find current version of ValueSet for url: " + valueSetId));
}
@Test
void fetchValueSetMustNotUseForcedId() {
when(myTermReadSvc.isLoincNotGenericUnversionedValueSet(anyString())).thenReturn(false);
testedClass.fetchValueSet("string-not-containing-l-o-i-n-c");
verify(myLoadCache, times(1)).get(anyString(), isA(Function.class));

View File

@ -81,6 +81,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.fail;
@ -501,7 +502,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.setUrl("http://loinc.org");
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
cs.setId("loinc");
cs.setId(LOINC_LOW);
myCodeSystemDao.update(cs);
Group group = new Group();
@ -569,7 +570,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.setUrl("http://loinc.org");
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
cs.setId("loinc");
cs.setId(LOINC_LOW);
myCodeSystemDao.update(cs);
Group group = new Group();
@ -637,7 +638,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.setUrl("http://loinc.org");
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
cs.setId("loinc");
cs.setId(LOINC_LOW);
myCodeSystemDao.update(cs);
Group group = new Group();
@ -1713,7 +1714,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
cs.setUrl(ITermLoaderSvc.LOINC_URI);
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
cs.addConcept().setCode("10013-1");
cs.setId("loinc");
cs.setId(LOINC_LOW);
myCodeSystemDao.update(cs);
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(new UriType("http://fooVs"), null, new StringType("10013-1"), new StringType(ITermLoaderSvc.LOINC_URI), null, null, null, mySrd);

View File

@ -33,6 +33,7 @@ import org.springframework.test.util.ReflectionTestUtils;
import java.security.InvalidParameterException;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.verify;
@ -50,14 +51,14 @@ class TermVersionAdapterSvcR4Test {
@Test
void createOrUpdateCodeSystemMustHaveId() {
org.hl7.fhir.r4.model.CodeSystem codeSystem = new CodeSystem();
CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl("a-loinc-system");
InvalidParameterException thrown = assertThrows(
InvalidParameterException.class,
() -> testedClass.createOrUpdateCodeSystem(codeSystem, new ServletRequestDetails()));
assertTrue(thrown.getMessage().contains("LOINC CodeSystem must have an 'ID' element"));
assertTrue(thrown.getMessage().contains("'loinc' CodeSystem must have an 'ID' element"));
}
@ -65,8 +66,8 @@ class TermVersionAdapterSvcR4Test {
void createOrUpdateCodeSystemWithIdNoException() {
ReflectionTestUtils.setField(testedClass, "myCodeSystemResourceDao", myCodeSystemResourceDao);
org.hl7.fhir.r4.model.CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl("a-loinc-system").setId("loinc");
CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl("a-loinc-system").setId(LOINC_LOW);
when(myCodeSystemResourceDao.update(codeSystem, theRequestDetails)).thenReturn(theDaoMethodOutcome);

View File

@ -25,7 +25,6 @@ import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.ValueSet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@ -75,6 +74,7 @@ import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
@ -930,7 +930,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
testProps.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), "false");
doReturn(mockFileDescriptors).when(testedSvc).getLoadedFileDescriptors(mockFileDescriptorList);
InvalidRequestException thrown = Assertions.assertThrows(InvalidRequestException.class,
InvalidRequestException thrown = assertThrows(InvalidRequestException.class,
() -> testedSvc.loadLoinc(mockFileDescriptorList, mySrd) );
assertEquals("'" + LOINC_CODESYSTEM_VERSION.getCode() + "' property is required when '" +

View File

@ -77,6 +77,7 @@ import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_UPLOAD_
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_XML_FILE;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -440,7 +441,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
// for CodeSystem:
// _ current CS is present and has no version
CodeSystem codeSystem = myCodeSystemDao.read(new IdType("loinc"));
CodeSystem codeSystem = myCodeSystemDao.read(new IdType(LOINC_LOW));
String csString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem);
ourLog.info("CodeSystem:\n" + csString);

View File

@ -42,6 +42,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
@ -406,7 +407,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
.addFilter()
.setProperty("copyright")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("loinc");
.setValue(LOINC_LOW);
outcome = myTermSvc.expandValueSet(null, vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("47239-9"));
@ -478,7 +479,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
.addFilter()
.setProperty("copyright")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("loinc");
.setValue(LOINC_LOW);
outcome = myTermSvc.expandValueSet(null, vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4"));

View File

@ -1,10 +1,31 @@
package ca.uhn.fhir.jpa.term.api;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.data.ITermValueSetDao;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.TermReadSvcR4;
import ca.uhn.fhir.jpa.term.TermReadSvcUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import com.google.common.collect.Lists;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -79,7 +100,7 @@ class ITermReadSvcTest {
@Test
void doesntStartWithGenericVSReturnsTrue() {
boolean ret = testedClass.mustReturnEmptyValueSet("http://boing.org");
boolean ret = TermReadSvcUtil.mustReturnEmptyValueSet("http://boing.org");
assertTrue(ret);
}
@ -87,20 +108,20 @@ class ITermReadSvcTest {
void doesntStartWithGenericVSPlusSlashThrows() {
InternalErrorException thrown = assertThrows(
InternalErrorException.class,
() -> testedClass.mustReturnEmptyValueSet("http://loinc.org/vs-no-slash-after-vs"));
() -> TermReadSvcUtil.mustReturnEmptyValueSet("http://loinc.org/vs-no-slash-after-vs"));
assertTrue(thrown.getMessage().contains("Don't know how to extract ForcedId from url:"));
assertTrue(thrown.getMessage().contains("Don't know how to extract ValueSet's ForcedId from url:"));
}
@Test
void blankVsIdReturnsTrue() {
boolean ret = testedClass.mustReturnEmptyValueSet("http://loinc.org/vs/");
boolean ret = TermReadSvcUtil.mustReturnEmptyValueSet("http://loinc.org/vs/");
assertTrue(ret);
}
@Test
void startsWithGenericPlusSlashPlusIdReturnsFalse() {
boolean ret = testedClass.mustReturnEmptyValueSet("http://loinc.org/vs/some-vs-id");
boolean ret = TermReadSvcUtil.mustReturnEmptyValueSet("http://loinc.org/vs/some-vs-id");
assertFalse(ret);
}
@ -112,19 +133,19 @@ class ITermReadSvcTest {
@Test
void doesntContainLoincReturnsFalse() {
boolean ret = testedClass.isLoincNotGenericUnversionedCodeSystem("http://boing.org");
boolean ret = TermReadSvcUtil.isLoincNotGenericUnversionedCodeSystem("http://boing.org");
assertFalse(ret);
}
@Test
void hasVersionReturnsFalse() {
boolean ret = testedClass.isLoincNotGenericUnversionedCodeSystem("http://boing.org|v2.68");
boolean ret = TermReadSvcUtil.isLoincNotGenericUnversionedCodeSystem("http://boing.org|v2.68");
assertFalse(ret);
}
@Test
void containsLoincAndNoVersionReturnsTrue() {
boolean ret = testedClass.isLoincNotGenericUnversionedCodeSystem("http://anything-plus-loinc.org");
boolean ret = TermReadSvcUtil.isLoincNotGenericUnversionedCodeSystem("http://anything-plus-loinc.org");
assertTrue(ret);
}
}
@ -134,25 +155,25 @@ class ITermReadSvcTest {
@Test
void notLoincReturnsFalse() {
boolean ret = testedClass.isLoincNotGenericUnversionedValueSet("http://anything-but-loin-c.org");
boolean ret = TermReadSvcUtil.isLoincNotGenericUnversionedValueSet("http://anything-but-loin-c.org");
assertFalse(ret);
}
@Test
void isLoincAndHasVersionReturnsFalse() {
boolean ret = testedClass.isLoincNotGenericUnversionedValueSet("http://loinc.org|v2.67");
boolean ret = TermReadSvcUtil.isLoincNotGenericUnversionedValueSet("http://loinc.org|v2.67");
assertFalse(ret);
}
@Test
void isLoincNoVersionButEqualsGenericValueSetUrlReturnsFalse() {
boolean ret = testedClass.isLoincNotGenericUnversionedValueSet("http://loinc.org/vs");
boolean ret = TermReadSvcUtil.isLoincNotGenericUnversionedValueSet("http://loinc.org/vs");
assertFalse(ret);
}
@Test
void isLoincNoVersionStartsWithGenericValueSetPlusSlashPlusIdReturnsTrue() {
boolean ret = testedClass.isLoincNotGenericUnversionedValueSet("http://loinc.org/vs/vs-id");
boolean ret = TermReadSvcUtil.isLoincNotGenericUnversionedValueSet("http://loinc.org/vs/vs-id");
assertTrue(ret);
}

View File

@ -0,0 +1,32 @@
package org.hl7.fhir.common.hapi.validation.support;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public class ValidationConstants {
public static final String LOINC_LOW = "loinc";
public static final String LOINC_GENERIC_CODE_SYSTEM_URL = "http://loinc.org";
public static final String LOINC_GENERIC_VALUESET_URL = LOINC_GENERIC_CODE_SYSTEM_URL + "/vs";
public static final String LOINC_GENERIC_VALUESET_URL_PLUS_SLASH = LOINC_GENERIC_VALUESET_URL + "/";
// not to be instantiated
private ValidationConstants() { }
}