Use ForcedId to get current ValueSet version
This commit is contained in:
parent
f63f12e976
commit
710343a599
|
@ -25,15 +25,18 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
|||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.param.UriParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -69,15 +72,15 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
|||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(JpaPersistedResourceValidationSupport.class);
|
||||
|
||||
public static final String LOINC_GENERIC_VALUESET_URL = "http://loinc.org/vs";
|
||||
public static final String LOINC_GENERIC_VALUESET_URL_PLUS_SLASH = LOINC_GENERIC_VALUESET_URL + "/";
|
||||
|
||||
private final FhirContext myFhirContext;
|
||||
private final IBaseResource myNoMatch;
|
||||
|
||||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
@Autowired
|
||||
private ITermReadSvc myITermReadSvc;
|
||||
|
||||
private Class<? extends IBaseResource> myCodeSystemType;
|
||||
private Class<? extends IBaseResource> myStructureDefinitionType;
|
||||
private Class<? extends IBaseResource> myValueSetType;
|
||||
|
@ -104,20 +107,34 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
|||
|
||||
@Override
|
||||
public IBaseResource fetchValueSet(String theSystem) {
|
||||
// if no version is present, we need to append the current version,
|
||||
// if one exists, in case it is not the last loaded
|
||||
theSystem = appendCurrentVersion(theSystem);
|
||||
boolean isNotLoincCodeSystem = ! StringUtils.containsIgnoreCase(theSystem, "loinc");
|
||||
boolean hasVersion = theSystem.contains("|");
|
||||
boolean isForGenericValueSet = theSystem.equals(LOINC_GENERIC_VALUESET_URL);
|
||||
if (isNotLoincCodeSystem || hasVersion || isForGenericValueSet) {
|
||||
return fetchResource(myValueSetType, theSystem);
|
||||
}
|
||||
|
||||
// if no version is present, we need to fetch the resource for the current version if one exists,
|
||||
// in case it is not the last loaded
|
||||
Optional<IBaseResource> currentVSOpt = getValueSetCurrentVersion(new UriType(theSystem));
|
||||
return currentVSOpt.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Couldn't find current version ValueSet for url: " + theSystem));
|
||||
}
|
||||
|
||||
private String appendCurrentVersion(String theSystem) {
|
||||
// if version is included there is nothing to add here
|
||||
if (theSystem.contains("|")) return theSystem;
|
||||
/**
|
||||
* Obtains the current version of a ValueSet using the fact that the current
|
||||
* version is always pointed by the ForcedId for the no-versioned VS
|
||||
*/
|
||||
public Optional<IBaseResource> getValueSetCurrentVersion(UriType theUrl) {
|
||||
if (! theUrl.getValueAsString().startsWith(LOINC_GENERIC_VALUESET_URL)) return Optional.empty();
|
||||
|
||||
Optional<String> currentVersionOpt = myITermReadSvc.getValueSetCurrentVersion(new UriType(theSystem));
|
||||
if (!theUrl.getValue().startsWith(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH)) {
|
||||
throw new InternalErrorException("Don't know how to extract ForcedId from url: " + theUrl.getValueAsString());
|
||||
}
|
||||
|
||||
return currentVersionOpt.map(ver -> theSystem + "|" + ver).orElse(theSystem);
|
||||
String forcedId = theUrl.getValue().substring(LOINC_GENERIC_VALUESET_URL_PLUS_SLASH.length());
|
||||
IBaseResource valueSet = myDaoRegistry.getResourceDao(myValueSetType).read(new IdDt("ValueSet", forcedId));
|
||||
return Optional.ofNullable(valueSet);
|
||||
}
|
||||
|
||||
|
||||
|
@ -195,9 +212,6 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
|||
params.add(ValueSet.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
|
||||
params.add(ValueSet.SP_URL, new UriParam(theUri.substring(0, versionSeparator)));
|
||||
} else {
|
||||
// last loaded ValueSet not necessarily is the current version anymore, so code should be executing
|
||||
// this path only when there is no current version pointed for the ValueSet
|
||||
ourLog.warn("Fetching ValueSet current version as last loaded");
|
||||
params.add(ValueSet.SP_URL, new UriParam(theUri));
|
||||
}
|
||||
params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC));
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao.data;
|
|||
|
||||
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
||||
import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
@ -31,6 +32,8 @@ import org.springframework.data.repository.query.Param;
|
|||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static ca.uhn.fhir.jpa.dao.JpaPersistedResourceValidationSupport.LOINC_GENERIC_VALUESET_URL;
|
||||
|
||||
public interface ITermValueSetDao extends JpaRepository<TermValueSet, Long> {
|
||||
|
||||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myResourcePid = :resource_pid")
|
||||
|
@ -44,28 +47,32 @@ public interface ITermValueSetDao extends JpaRepository<TermValueSet, Long> {
|
|||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myExpansionStatus = :expansion_status")
|
||||
Slice<TermValueSet> findByExpansionStatus(Pageable pageable, @Param("expansion_status") TermValueSetPreExpansionStatusEnum theExpansionStatus);
|
||||
|
||||
@Query(value="SELECT vs FROM TermValueSet vs INNER JOIN ResourceTable r ON r.myId = vs.myResourcePid WHERE vs.myUrl = :url ORDER BY r.myUpdated DESC")
|
||||
List<TermValueSet> findTermValueSetByUrl(Pageable thePage, @Param("url") String theUrl);
|
||||
|
||||
/**
|
||||
* The current TermValueSet is not necessarily the last uploaded anymore, but we know which is the last VS resource
|
||||
* because it is pointed by a specific ForcedId, so we locate current ValueSet as the one pointing to the current resource
|
||||
*/
|
||||
@Query(value="SELECT vs FROM ForcedId f, TermValueSet vs where f.myForcedId = :forcedId and vs.myResource = f.myResource")
|
||||
Optional<TermValueSet> findTermValueSetByForcedId(@Param("forcedId") String theForcedId);
|
||||
|
||||
default Optional<TermValueSet> findTermValueSetByUrl(@Param("url") String theUrl) {
|
||||
if (theUrl.startsWith(LOINC_GENERIC_VALUESET_URL)) {
|
||||
String forcedId = theUrl.substring(LOINC_GENERIC_VALUESET_URL.length());
|
||||
if (StringUtils.isBlank(forcedId)) return Optional.empty();
|
||||
return findTermValueSetByForcedId(forcedId);
|
||||
}
|
||||
|
||||
List<TermValueSet> tvsList = findTermValueSetByUrl(Pageable.ofSize(1), theUrl);
|
||||
|
||||
return Optional.ofNullable(tvsList.size() == 1 ? tvsList.get(0) : null);
|
||||
}
|
||||
|
||||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion IS NULL")
|
||||
Optional<TermValueSet> findTermValueSetByUrlAndNullVersion(@Param("url") String theUrl);
|
||||
|
||||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion = :version")
|
||||
Optional<TermValueSet> findTermValueSetByUrlAndVersion(@Param("url") String theUrl, @Param("version") String theVersion);
|
||||
|
||||
/**
|
||||
* Obtain the only ValueSet for the url which myIsCurrentVersion is true if one exists
|
||||
* or the last loaded ValueSet for the url which version is null otherwise
|
||||
*/
|
||||
@Query("select vs FROM TermValueSet vs JOIN FETCH vs.myResource r WHERE vs.myUrl = :url AND (vs.myIsCurrentVersion is true or " +
|
||||
"(vs.myIsCurrentVersion is false AND vs.myVersion is null AND not exists(" +
|
||||
"FROM TermValueSet WHERE myUrl = :url AND myIsCurrentVersion is true )) ) order by r.myUpdated DESC")
|
||||
List<TermValueSet> listTermValueSetsByUrlAndCurrentVersion(@Param("url") String theUrl, Pageable pageable);
|
||||
|
||||
/**
|
||||
* This method uses the previous one to get a possible list of ValueSets and return the first if any
|
||||
* because the query will obtain no more than one if one with the myCurrentVersion flag exists but
|
||||
* could obtain more if one with that flag doesn't exist. For that reason the query is Pageable and ordered
|
||||
*/
|
||||
default Optional<TermValueSet> findTermValueSetByUrlAndCurrentVersion(@Param("url") String theUrl) {
|
||||
List<TermValueSet> termValueSets = listTermValueSetsByUrlAndCurrentVersion(theUrl, Pageable.ofSize(1));
|
||||
return termValueSets.isEmpty()? Optional.empty() : Optional.of(termValueSets.get(0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,24 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
|
|||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
import org.hibernate.annotations.OptimisticLock;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -86,10 +100,6 @@ public class TermValueSet implements Serializable {
|
|||
@Column(name = "EXPANSION_STATUS", nullable = false, length = MAX_EXPANSION_STATUS_LENGTH)
|
||||
private TermValueSetPreExpansionStatusEnum myExpansionStatus;
|
||||
|
||||
@OptimisticLock(excluded = true)
|
||||
@Column(name = "CURRENT_VERSION")
|
||||
private Boolean myIsCurrentVersion = false;
|
||||
|
||||
@Transient
|
||||
private transient Integer myHashCode;
|
||||
|
||||
|
@ -203,14 +213,6 @@ public class TermValueSet implements Serializable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Boolean getCurrentVersion() {
|
||||
return myIsCurrentVersion;
|
||||
}
|
||||
|
||||
public void setCurrentVersion(Boolean theCurrentVersion) {
|
||||
myIsCurrentVersion = theCurrentVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theO) {
|
||||
if (this == theO) return true;
|
||||
|
|
|
@ -26,7 +26,6 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
|||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoValueSet;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProviderValueSetDstu2;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
|
@ -43,20 +42,14 @@ import org.hl7.fhir.r4.model.Parameters;
|
|||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
public class BaseJpaResourceProviderValueSetR4 extends JpaResourceProviderR4<ValueSet> {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaResourceProviderValueSetR4.class);
|
||||
|
||||
@Autowired
|
||||
private ITermReadSvc myITermReadSvc;
|
||||
|
||||
@Operation(name = JpaConstants.OPERATION_EXPAND, idempotent = true)
|
||||
public ValueSet expand(
|
||||
HttpServletRequest theServletRequest,
|
||||
|
@ -83,16 +76,6 @@ public class BaseJpaResourceProviderValueSetR4 extends JpaResourceProviderR4<Val
|
|||
throw new InvalidRequestException("$expand must EITHER be invoked at the instance level, or have a url specified, or have a ValueSet specified. Can not combine these options.");
|
||||
}
|
||||
|
||||
// todo JM remove this code. This function is at lower level now
|
||||
// because current version is not necessarily the last uploaded anymore, we add a version parameter for the current version
|
||||
if (haveIdentifier && ! haveValueSetVersion) {
|
||||
Optional<String> currentVersionOpt = myITermReadSvc.getValueSetCurrentVersion(theUrl);
|
||||
if (currentVersionOpt.isPresent()) {
|
||||
theValueSetVersion = new StringType(currentVersionOpt.get());
|
||||
haveValueSetVersion = true;
|
||||
}
|
||||
}
|
||||
|
||||
ValueSetExpansionOptions options = createValueSetExpansionOptions(myDaoConfig, theOffset, theCount, theIncludeHierarchy, theFilter);
|
||||
|
||||
startRequest(theServletRequest);
|
||||
|
@ -115,7 +98,6 @@ public class BaseJpaResourceProviderValueSetR4 extends JpaResourceProviderR4<Val
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Operation(name = JpaConstants.OPERATION_VALIDATE_CODE, idempotent = true, returnParameters = {
|
||||
@OperationParam(name = "result", type = BooleanType.class, min = 1),
|
||||
@OperationParam(name = "message", type = StringType.class),
|
||||
|
|
|
@ -117,7 +117,6 @@ import org.hl7.fhir.r4.model.Enumerations;
|
|||
import org.hl7.fhir.r4.model.Extension;
|
||||
import org.hl7.fhir.r4.model.IntegerType;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
import org.hl7.fhir.r4.model.codesystems.ConceptSubsumptionOutcome;
|
||||
import org.quartz.JobExecutionContext;
|
||||
|
@ -197,7 +196,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
@Autowired
|
||||
protected ITermConceptDesignationDao myConceptDesignationDao;
|
||||
@Autowired
|
||||
protected ITermValueSetDao myValueSetDao;
|
||||
protected ITermValueSetDao myTermValueSetDao;
|
||||
@Autowired
|
||||
protected ITermValueSetConceptDao myValueSetConceptDao;
|
||||
@Autowired
|
||||
|
@ -232,9 +231,6 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
@Autowired
|
||||
private ITermConceptMappingSvc myTermConceptMappingSvc;
|
||||
|
||||
@Autowired
|
||||
private ITermValueSetDao myTermValueSetDao;
|
||||
|
||||
private volatile IValidationSupport myJpaValidationSupport;
|
||||
private volatile IValidationSupport myValidationSupport;
|
||||
|
||||
|
@ -343,7 +339,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
|
||||
public void deleteValueSetForResource(ResourceTable theResourceTable) {
|
||||
// Get existing entity so it can be deleted.
|
||||
Optional<TermValueSet> optionalExistingTermValueSetById = myValueSetDao.findByResourcePid(theResourceTable.getId());
|
||||
Optional<TermValueSet> optionalExistingTermValueSetById = myTermValueSetDao.findByResourcePid(theResourceTable.getId());
|
||||
|
||||
if (optionalExistingTermValueSetById.isPresent()) {
|
||||
TermValueSet existingTermValueSet = optionalExistingTermValueSetById.get();
|
||||
|
@ -351,7 +347,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
ourLog.info("Deleting existing TermValueSet[{}] and its children...", existingTermValueSet.getId());
|
||||
myValueSetConceptDesignationDao.deleteByTermValueSetId(existingTermValueSet.getId());
|
||||
myValueSetConceptDao.deleteByTermValueSetId(existingTermValueSet.getId());
|
||||
myValueSetDao.deleteById(existingTermValueSet.getId());
|
||||
myTermValueSetDao.deleteById(existingTermValueSet.getId());
|
||||
ourLog.info("Done deleting existing TermValueSet[{}] and its children.", existingTermValueSet.getId());
|
||||
}
|
||||
}
|
||||
|
@ -447,9 +443,9 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
Optional<TermValueSet> optionalTermValueSet;
|
||||
if (theValueSetToExpand.hasUrl()) {
|
||||
if (theValueSetToExpand.hasVersion()) {
|
||||
optionalTermValueSet = myValueSetDao.findTermValueSetByUrlAndVersion(theValueSetToExpand.getUrl(), theValueSetToExpand.getVersion());
|
||||
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(theValueSetToExpand.getUrl(), theValueSetToExpand.getVersion());
|
||||
} else {
|
||||
optionalTermValueSet = myValueSetDao.findTermValueSetByUrlAndCurrentVersion(theValueSetToExpand.getUrl());
|
||||
optionalTermValueSet = myTermValueSetDao.findTermValueSetByUrl(theValueSetToExpand.getUrl());
|
||||
}
|
||||
} else {
|
||||
optionalTermValueSet = Optional.empty();
|
||||
|
@ -1454,7 +1450,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
@Override
|
||||
public boolean isValueSetPreExpandedForCodeValidation(ValueSet theValueSet) {
|
||||
ResourcePersistentId valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSet.getIdElement());
|
||||
Optional<TermValueSet> optionalTermValueSet = myValueSetDao.findByResourcePid(valueSetResourcePid.getIdAsLong());
|
||||
Optional<TermValueSet> optionalTermValueSet = myTermValueSetDao.findByResourcePid(valueSetResourcePid.getIdAsLong());
|
||||
|
||||
if (!optionalTermValueSet.isPresent()) {
|
||||
ourLog.warn("ValueSet is not present in terminology tables. Will perform in-memory code validation. {}", getValueSetInfo(theValueSet));
|
||||
|
@ -1759,7 +1755,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
|
||||
TermValueSet termValueSet = optionalTermValueSet.get();
|
||||
termValueSet.setExpansionStatus(TermValueSetPreExpansionStatusEnum.EXPANSION_IN_PROGRESS);
|
||||
return myValueSetDao.saveAndFlush(termValueSet);
|
||||
return myTermValueSetDao.saveAndFlush(termValueSet);
|
||||
});
|
||||
if (valueSetToExpand == null) {
|
||||
return;
|
||||
|
@ -1768,18 +1764,18 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
// We have a ValueSet to pre-expand.
|
||||
try {
|
||||
ValueSet valueSet = txTemplate.execute(t -> {
|
||||
TermValueSet refreshedValueSetToExpand = myValueSetDao.findById(valueSetToExpand.getId()).orElseThrow(() -> new IllegalStateException("Unknown VS ID: " + valueSetToExpand.getId()));
|
||||
TermValueSet refreshedValueSetToExpand = myTermValueSetDao.findById(valueSetToExpand.getId()).orElseThrow(() -> new IllegalStateException("Unknown VS ID: " + valueSetToExpand.getId()));
|
||||
return getValueSetFromResourceTable(refreshedValueSetToExpand.getResource());
|
||||
});
|
||||
assert valueSet != null;
|
||||
|
||||
ValueSetConceptAccumulator accumulator = new ValueSetConceptAccumulator(valueSetToExpand, myValueSetDao, myValueSetConceptDao, myValueSetConceptDesignationDao);
|
||||
ValueSetConceptAccumulator accumulator = new ValueSetConceptAccumulator(valueSetToExpand, myTermValueSetDao, myValueSetConceptDao, myValueSetConceptDesignationDao);
|
||||
expandValueSet(null, valueSet, accumulator);
|
||||
|
||||
// We are done with this ValueSet.
|
||||
txTemplate.execute(t -> {
|
||||
valueSetToExpand.setExpansionStatus(TermValueSetPreExpansionStatusEnum.EXPANDED);
|
||||
myValueSetDao.saveAndFlush(valueSetToExpand);
|
||||
myTermValueSetDao.saveAndFlush(valueSetToExpand);
|
||||
return null;
|
||||
});
|
||||
|
||||
|
@ -1789,7 +1785,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
ourLog.error("Failed to pre-expand ValueSet: " + e.getMessage(), e);
|
||||
txTemplate.execute(t -> {
|
||||
valueSetToExpand.setExpansionStatus(TermValueSetPreExpansionStatusEnum.FAILED_TO_EXPAND);
|
||||
myValueSetDao.saveAndFlush(valueSetToExpand);
|
||||
myTermValueSetDao.saveAndFlush(valueSetToExpand);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
@ -1872,7 +1868,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
|
||||
private Optional<TermValueSet> getNextTermValueSetNotExpanded() {
|
||||
Optional<TermValueSet> retVal = Optional.empty();
|
||||
Slice<TermValueSet> page = myValueSetDao.findByExpansionStatus(PageRequest.of(0, 1), TermValueSetPreExpansionStatusEnum.NOT_EXPANDED);
|
||||
Slice<TermValueSet> page = myTermValueSetDao.findByExpansionStatus(PageRequest.of(0, 1), TermValueSetPreExpansionStatusEnum.NOT_EXPANDED);
|
||||
|
||||
if (!page.getContent().isEmpty()) {
|
||||
retVal = Optional.of(page.getContent().get(0));
|
||||
|
@ -1883,7 +1879,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
|
||||
@Override
|
||||
@Transactional
|
||||
public void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet , boolean theMakeItCurrent) {
|
||||
public void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet) {
|
||||
|
||||
ValidateUtil.isTrueOrThrowInvalidRequest(theResourceTable != null, "No resource supplied");
|
||||
if (isPlaceholder(theValueSet)) {
|
||||
|
@ -1902,13 +1898,6 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
termValueSet.setUrl(theValueSet.getUrl());
|
||||
termValueSet.setVersion(theValueSet.getVersion());
|
||||
termValueSet.setName(theValueSet.hasName() ? theValueSet.getName() : null);
|
||||
termValueSet.setCurrentVersion(false);
|
||||
|
||||
// value sets must be marked as current only when version is present and flag indicates that
|
||||
if (theValueSet.getVersion() != null && theMakeItCurrent) {
|
||||
resetCurrentValueSetVersion(theValueSet);
|
||||
termValueSet.setCurrentVersion(true);
|
||||
}
|
||||
|
||||
// Delete version being replaced
|
||||
deleteValueSetForResource(theResourceTable);
|
||||
|
@ -1920,13 +1909,13 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
String version = termValueSet.getVersion();
|
||||
Optional<TermValueSet> optionalExistingTermValueSetByUrl;
|
||||
if (version != null) {
|
||||
optionalExistingTermValueSetByUrl = myValueSetDao.findTermValueSetByUrlAndVersion(url, version);
|
||||
optionalExistingTermValueSetByUrl = myTermValueSetDao.findTermValueSetByUrlAndVersion(url, version);
|
||||
} else {
|
||||
optionalExistingTermValueSetByUrl = myValueSetDao.findTermValueSetByUrlAndNullVersion(url);
|
||||
optionalExistingTermValueSetByUrl = myTermValueSetDao.findTermValueSetByUrlAndNullVersion(url);
|
||||
}
|
||||
if (!optionalExistingTermValueSetByUrl.isPresent()) {
|
||||
|
||||
myValueSetDao.save(termValueSet);
|
||||
myTermValueSetDao.save(termValueSet);
|
||||
|
||||
} else {
|
||||
TermValueSet existingTermValueSet = optionalExistingTermValueSetByUrl.get();
|
||||
|
@ -1946,17 +1935,6 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void resetCurrentValueSetVersion(ValueSet theValueSet) {
|
||||
Optional<TermValueSet> termValueSetOpt = myTermValueSetDao.findTermValueSetByUrlAndCurrentVersion(theValueSet.getUrl());
|
||||
if (! termValueSetOpt.isPresent()) return;
|
||||
|
||||
TermValueSet termValueSet = termValueSetOpt.get();
|
||||
termValueSet.setCurrentVersion(false);
|
||||
myTermValueSetDao.save(termValueSet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB,
|
||||
|
@ -2509,18 +2487,4 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||
|
||||
return theReqLang.equalsIgnoreCase(theStoredLang);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Optional<String> getValueSetCurrentVersion(UriType theUrl) {
|
||||
Optional<TermValueSet> termValueSetOpt =
|
||||
myTermValueSetDao.findTermValueSetByUrlAndCurrentVersion(theUrl.getValueAsString());
|
||||
|
||||
if (! termValueSetOpt.isPresent() || StringUtils.isBlank(termValueSetOpt.get().getVersion())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return termValueSetOpt.map(TermValueSet::getVersion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -399,9 +399,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
|||
theCodeSystemResource.getVersion(), theCodeSystemVersion, resource, theRequest);
|
||||
|
||||
myDeferredStorageSvc.addConceptMapsToStorageQueue(theConceptMaps);
|
||||
|
||||
boolean isMakeVersionCurrent = ITermCodeSystemStorageSvc.isMakeVersionCurrent(theRequest);
|
||||
myDeferredStorageSvc.addValueSetsToStorageQueue(theValueSets, isMakeVersionCurrent);
|
||||
myDeferredStorageSvc.addValueSetsToStorageQueue(theValueSets);
|
||||
|
||||
return csId;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -66,7 +65,6 @@ import java.util.UUID;
|
|||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
||||
|
||||
|
@ -74,7 +72,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
|||
final private List<TermCodeSystem> myDeferredCodeSystemsDeletions = Collections.synchronizedList(new ArrayList<>());
|
||||
final private Queue<TermCodeSystemVersion> myDeferredCodeSystemVersionsDeletions = new ConcurrentLinkedQueue<>();
|
||||
final private List<TermConcept> myDeferredConcepts = Collections.synchronizedList(new ArrayList<>());
|
||||
final private List<Pair<ValueSet, Boolean>> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>());
|
||||
final private List<ValueSet> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>());
|
||||
final private List<ConceptMap> myDeferredConceptMaps = Collections.synchronizedList(new ArrayList<>());
|
||||
final private List<TermConceptParentChildLink> myConceptLinksToSaveLater = Collections.synchronizedList(new ArrayList<>());
|
||||
@Autowired
|
||||
|
@ -118,9 +116,9 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addValueSetsToStorageQueue(List<ValueSet> theValueSets, boolean theMakeThemCurrent) {
|
||||
public void addValueSetsToStorageQueue(List<ValueSet> theValueSets) {
|
||||
Validate.notNull(theValueSets);
|
||||
myDeferredValueSets.addAll(theValueSets.stream().map(vs -> Pair.of(vs, theMakeThemCurrent)).collect(Collectors.toList()));
|
||||
myDeferredValueSets.addAll(theValueSets);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -216,15 +214,12 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void processDeferredValueSets() {
|
||||
int count = Math.min(myDeferredValueSets.size(), 200);
|
||||
for (Pair<ValueSet, Boolean> nextPair : new ArrayList<>(myDeferredValueSets.subList(0, count))) {
|
||||
ValueSet valueSet = nextPair.getFirst();
|
||||
boolean makeItCurrent = nextPair.getSecond();
|
||||
ourLog.info("Creating ValueSet: {} , {}making it current version", valueSet.getId(), (makeItCurrent ? "" : "not "));
|
||||
myTerminologyVersionAdapterSvc.createOrUpdateValueSet(valueSet, makeItCurrent);
|
||||
myDeferredValueSets.remove(nextPair);
|
||||
for (ValueSet nextValueSet : new ArrayList<>(myDeferredValueSets.subList(0, count))) {
|
||||
ourLog.info("Creating ValueSet: {}", nextValueSet.getId());
|
||||
myTerminologyVersionAdapterSvc.createOrUpdateValueSet(nextValueSet);
|
||||
myDeferredValueSets.remove(nextValueSet);
|
||||
}
|
||||
ourLog.info("Saved {} deferred ValueSet resources, have {} remaining", count, myDeferredValueSets.size());
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public class TermVersionAdapterSvcDstu2 implements ITermVersionAdapterSvc {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void createOrUpdateValueSet(ValueSet theValueSet, boolean theMakeItCurrent) {
|
||||
public void createOrUpdateValueSet(ValueSet theValueSet) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ package ca.uhn.fhir.jpa.term;
|
|||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
|
||||
|
@ -38,7 +37,6 @@ import org.springframework.context.ApplicationContext;
|
|||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import static ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc.MAKE_LOADING_VERSION_CURRENT;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
|
||||
|
@ -105,7 +103,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
|
|||
}
|
||||
|
||||
@Override
|
||||
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet, boolean theMakeItCurrent) {
|
||||
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
|
||||
ValueSet valueSetDstu3;
|
||||
try {
|
||||
valueSetDstu3 = (ValueSet) VersionConvertorFactory_30_40.convertResource(theValueSet, new BaseAdvisor_30_40(false));
|
||||
|
@ -113,14 +111,11 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
|
|||
throw new InternalErrorException(e);
|
||||
}
|
||||
|
||||
TransactionDetails txDetails = new TransactionDetails();
|
||||
txDetails.putUserData(MAKE_LOADING_VERSION_CURRENT, theMakeItCurrent);
|
||||
|
||||
if (isBlank(valueSetDstu3.getIdElement().getIdPart())) {
|
||||
String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl());
|
||||
myValueSetResourceDao.update(valueSetDstu3, matchUrl, true, false, null, txDetails);
|
||||
myValueSetResourceDao.update(valueSetDstu3, matchUrl);
|
||||
} else {
|
||||
myValueSetResourceDao.update(valueSetDstu3, null, true, false, null, txDetails);
|
||||
myValueSetResourceDao.update(valueSetDstu3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ package ca.uhn.fhir.jpa.term;
|
|||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.CodeSystem;
|
||||
|
@ -34,7 +33,6 @@ import org.springframework.context.ApplicationContext;
|
|||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import static ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc.MAKE_LOADING_VERSION_CURRENT;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
|
||||
|
@ -83,15 +81,12 @@ public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl imple
|
|||
}
|
||||
|
||||
@Override
|
||||
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet, boolean theMakeItCurrent) {
|
||||
TransactionDetails txDetails = new TransactionDetails();
|
||||
txDetails.putUserData(MAKE_LOADING_VERSION_CURRENT, theMakeItCurrent);
|
||||
|
||||
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
|
||||
if (isBlank(theValueSet.getIdElement().getIdPart())) {
|
||||
String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl());
|
||||
myValueSetResourceDao.update(theValueSet, matchUrl, true, false, null, txDetails);
|
||||
myValueSetResourceDao.update(theValueSet, matchUrl);
|
||||
} else {
|
||||
myValueSetResourceDao.update(theValueSet, null, true, false, null, txDetails);
|
||||
myValueSetResourceDao.update(theValueSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ package ca.uhn.fhir.jpa.term;
|
|||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||
|
@ -36,7 +35,6 @@ import org.springframework.context.ApplicationContext;
|
|||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import static ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc.MAKE_LOADING_VERSION_CURRENT;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
|
||||
|
@ -90,18 +88,15 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
|
|||
}
|
||||
|
||||
@Override
|
||||
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet, boolean theMakeItCurrent) {
|
||||
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
|
||||
|
||||
ValueSet valueSetR4 = (ValueSet) VersionConvertorFactory_40_50.convertResource(theValueSet, new BaseAdvisor_40_50(false));
|
||||
|
||||
TransactionDetails txDetails = new TransactionDetails();
|
||||
txDetails.putUserData(MAKE_LOADING_VERSION_CURRENT, theMakeItCurrent);
|
||||
|
||||
if (isBlank(theValueSet.getIdElement().getIdPart())) {
|
||||
String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl());
|
||||
myValueSetResourceDao.update(valueSetR4, matchUrl, true, false, null, txDetails);
|
||||
myValueSetResourceDao.update(valueSetR4, matchUrl);
|
||||
} else {
|
||||
myValueSetResourceDao.update(valueSetR4, null, true, false, null, txDetails);
|
||||
myValueSetResourceDao.update(valueSetR4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public interface ITermDeferredStorageSvc {
|
|||
|
||||
void addConceptMapsToStorageQueue(List<ConceptMap> theConceptMaps);
|
||||
|
||||
void addValueSetsToStorageQueue(List<ValueSet> theValueSets, boolean theMakeThemCurrent);
|
||||
void addValueSetsToStorageQueue(List<ValueSet> theValueSets);
|
||||
|
||||
void deleteCodeSystem(TermCodeSystem theCodeSystem);
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.r4.model.CodeSystem;
|
||||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -88,13 +87,7 @@ public interface ITermReadSvc extends IValidationSupport {
|
|||
|
||||
void deleteValueSetAndChildren(ResourceTable theResourceTable);
|
||||
|
||||
|
||||
void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet, boolean theMakeItCurrent);
|
||||
|
||||
default void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet) {
|
||||
storeTermValueSet(theResourceTable, theValueSet, true);
|
||||
}
|
||||
|
||||
void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet);
|
||||
|
||||
IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB, IPrimitiveType<String> theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB);
|
||||
|
||||
|
@ -122,5 +115,4 @@ public interface ITermReadSvc extends IValidationSupport {
|
|||
*/
|
||||
CodeValidationResult codeSystemValidateCode(IIdType theCodeSystemId, String theValueSetUrl, String theVersion, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept);
|
||||
|
||||
Optional<String> getValueSetCurrentVersion(UriType theUrl);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,6 @@ public interface ITermVersionAdapterSvc {
|
|||
|
||||
void createOrUpdateConceptMap(ConceptMap theNextConceptMap);
|
||||
|
||||
void createOrUpdateValueSet(ValueSet theValueSet, boolean makeItCurrent);
|
||||
void createOrUpdateValueSet(ValueSet theValueSet);
|
||||
|
||||
}
|
||||
|
|
|
@ -571,7 +571,7 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
|
|||
|
||||
public List<String> getExpandedConceptsByValueSetUrl(String theValuesetUrl) {
|
||||
return runInTransaction(() -> {
|
||||
Optional<TermValueSet> valueSetOpt = myTermValueSetDao.findTermValueSetByUrlAndCurrentVersion(theValuesetUrl);
|
||||
Optional<TermValueSet> valueSetOpt = myTermValueSetDao.findTermValueSetByUrl(theValuesetUrl);
|
||||
assertTrue(valueSetOpt.isPresent());
|
||||
TermValueSet valueSet = valueSetOpt.get();
|
||||
List<TermValueSetConcept> concepts = valueSet.getConcepts();
|
||||
|
|
|
@ -122,15 +122,8 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
|||
cmbTokNuTable.addColumn("20210722.1", "PARTITION_ID").nullable().type(ColumnTypeEnum.INT);
|
||||
cmbTokNuTable.addColumn("20210722.2", "PARTITION_DATE").nullable().type(ColumnTypeEnum.DATE_ONLY);
|
||||
cmbTokNuTable.modifyColumn("20210722.3", "RES_ID").nullable().withType(ColumnTypeEnum.LONG);
|
||||
|
||||
version.onTable("TRM_VALUESET")
|
||||
.addColumn("20210820.1", "CURRENT_VERSION").nullable().type(ColumnTypeEnum.BOOLEAN);
|
||||
|
||||
//todo JM Add new column initialization and validate boolean in Oracle
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void init540() {
|
||||
|
||||
Builder version = forVersion(VersionEnum.V5_4_0);
|
||||
|
|
Loading…
Reference in New Issue