mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-02-28 09:09:16 +00:00
Consider last stored ValueSet not necessarily current version anymore.
This commit is contained in:
parent
4920f0a15d
commit
426315f589
@ -25,6 +25,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
|||||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||||
import ca.uhn.fhir.rest.api.SortSpec;
|
import ca.uhn.fhir.rest.api.SortSpec;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
@ -41,6 +42,7 @@ import org.hl7.fhir.r4.model.IdType;
|
|||||||
import org.hl7.fhir.r4.model.ImplementationGuide;
|
import org.hl7.fhir.r4.model.ImplementationGuide;
|
||||||
import org.hl7.fhir.r4.model.Questionnaire;
|
import org.hl7.fhir.r4.model.Questionnaire;
|
||||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r4.model.UriType;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -51,6 +53,7 @@ import javax.annotation.PostConstruct;
|
|||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@ -71,6 +74,10 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DaoRegistry myDaoRegistry;
|
private DaoRegistry myDaoRegistry;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITermReadSvc myITermReadSvc;
|
||||||
|
|
||||||
private Class<? extends IBaseResource> myCodeSystemType;
|
private Class<? extends IBaseResource> myCodeSystemType;
|
||||||
private Class<? extends IBaseResource> myStructureDefinitionType;
|
private Class<? extends IBaseResource> myStructureDefinitionType;
|
||||||
private Class<? extends IBaseResource> myValueSetType;
|
private Class<? extends IBaseResource> myValueSetType;
|
||||||
@ -97,9 +104,23 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBaseResource fetchValueSet(String theSystem) {
|
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);
|
||||||
return fetchResource(myValueSetType, theSystem);
|
return fetchResource(myValueSetType, theSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String appendCurrentVersion(String theSystem) {
|
||||||
|
// if version is included there is nothing to add here
|
||||||
|
if (theSystem.contains("|")) return theSystem;
|
||||||
|
|
||||||
|
Optional<String> currentVersionOpt = myITermReadSvc.getValueSetCurrentVersion(new UriType(theSystem));
|
||||||
|
|
||||||
|
return currentVersionOpt.map(ver -> theSystem + "|" + ver).orElse(theSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBaseResource fetchStructureDefinition(String theUrl) {
|
public IBaseResource fetchStructureDefinition(String theUrl) {
|
||||||
return fetchResource(myStructureDefinitionType, theUrl);
|
return fetchResource(myStructureDefinitionType, theUrl);
|
||||||
@ -174,6 +195,9 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
|||||||
params.add(ValueSet.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
|
params.add(ValueSet.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
|
||||||
params.add(ValueSet.SP_URL, new UriParam(theUri.substring(0, versionSeparator)));
|
params.add(ValueSet.SP_URL, new UriParam(theUri.substring(0, versionSeparator)));
|
||||||
} else {
|
} 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.add(ValueSet.SP_URL, new UriParam(theUri));
|
||||||
}
|
}
|
||||||
params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC));
|
params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC));
|
||||||
|
@ -44,14 +44,28 @@ public interface ITermValueSetDao extends JpaRepository<TermValueSet, Long> {
|
|||||||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myExpansionStatus = :expansion_status")
|
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myExpansionStatus = :expansion_status")
|
||||||
Slice<TermValueSet> findByExpansionStatus(Pageable pageable, @Param("expansion_status") TermValueSetPreExpansionStatusEnum theExpansionStatus);
|
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);
|
|
||||||
|
|
||||||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion IS NULL")
|
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion IS NULL")
|
||||||
Optional<TermValueSet> findTermValueSetByUrlAndNullVersion(@Param("url") String theUrl);
|
Optional<TermValueSet> findTermValueSetByUrlAndNullVersion(@Param("url") String theUrl);
|
||||||
|
|
||||||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion = :version")
|
@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);
|
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,6 +26,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
|
|||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import org.hibernate.annotations.ColumnDefault;
|
import org.hibernate.annotations.ColumnDefault;
|
||||||
|
import org.hibernate.annotations.OptimisticLock;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
@ -85,6 +86,10 @@ public class TermValueSet implements Serializable {
|
|||||||
@Column(name = "EXPANSION_STATUS", nullable = false, length = MAX_EXPANSION_STATUS_LENGTH)
|
@Column(name = "EXPANSION_STATUS", nullable = false, length = MAX_EXPANSION_STATUS_LENGTH)
|
||||||
private TermValueSetPreExpansionStatusEnum myExpansionStatus;
|
private TermValueSetPreExpansionStatusEnum myExpansionStatus;
|
||||||
|
|
||||||
|
@OptimisticLock(excluded = true)
|
||||||
|
@Column(name = "CURRENT_VERSION")
|
||||||
|
private Boolean myIsCurrentVersion = false;
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private transient Integer myHashCode;
|
private transient Integer myHashCode;
|
||||||
|
|
||||||
@ -198,6 +203,14 @@ public class TermValueSet implements Serializable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getCurrentVersion() {
|
||||||
|
return myIsCurrentVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentVersion(Boolean theCurrentVersion) {
|
||||||
|
myIsCurrentVersion = theCurrentVersion;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object theO) {
|
public boolean equals(Object theO) {
|
||||||
if (this == theO) return true;
|
if (this == theO) return true;
|
||||||
|
@ -68,6 +68,7 @@ import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
|||||||
import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException;
|
import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException;
|
||||||
import ca.uhn.fhir.jpa.util.LogicUtil;
|
import ca.uhn.fhir.jpa.util.LogicUtil;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
@ -117,6 +118,7 @@ import org.hl7.fhir.r4.model.Enumerations;
|
|||||||
import org.hl7.fhir.r4.model.Extension;
|
import org.hl7.fhir.r4.model.Extension;
|
||||||
import org.hl7.fhir.r4.model.IntegerType;
|
import org.hl7.fhir.r4.model.IntegerType;
|
||||||
import org.hl7.fhir.r4.model.StringType;
|
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.ValueSet;
|
||||||
import org.hl7.fhir.r4.model.codesystems.ConceptSubsumptionOutcome;
|
import org.hl7.fhir.r4.model.codesystems.ConceptSubsumptionOutcome;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
@ -231,6 +233,9 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ITermConceptMappingSvc myTermConceptMappingSvc;
|
private ITermConceptMappingSvc myTermConceptMappingSvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITermValueSetDao myTermValueSetDao;
|
||||||
|
|
||||||
private volatile IValidationSupport myJpaValidationSupport;
|
private volatile IValidationSupport myJpaValidationSupport;
|
||||||
private volatile IValidationSupport myValidationSupport;
|
private volatile IValidationSupport myValidationSupport;
|
||||||
|
|
||||||
@ -445,12 +450,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||||||
if (theValueSetToExpand.hasVersion()) {
|
if (theValueSetToExpand.hasVersion()) {
|
||||||
optionalTermValueSet = myValueSetDao.findTermValueSetByUrlAndVersion(theValueSetToExpand.getUrl(), theValueSetToExpand.getVersion());
|
optionalTermValueSet = myValueSetDao.findTermValueSetByUrlAndVersion(theValueSetToExpand.getUrl(), theValueSetToExpand.getVersion());
|
||||||
} else {
|
} else {
|
||||||
List<TermValueSet> termValueSets = myValueSetDao.findTermValueSetByUrl(PageRequest.of(0, 1), theValueSetToExpand.getUrl());
|
optionalTermValueSet = myValueSetDao.findTermValueSetByUrlAndCurrentVersion(theValueSetToExpand.getUrl());
|
||||||
if (termValueSets.size() > 0) {
|
|
||||||
optionalTermValueSet = Optional.of(termValueSets.get(0));
|
|
||||||
} else {
|
|
||||||
optionalTermValueSet = Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
optionalTermValueSet = Optional.empty();
|
optionalTermValueSet = Optional.empty();
|
||||||
@ -1884,7 +1884,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet) {
|
public void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet , RequestDetails theRequestDetails) {
|
||||||
|
|
||||||
ValidateUtil.isTrueOrThrowInvalidRequest(theResourceTable != null, "No resource supplied");
|
ValidateUtil.isTrueOrThrowInvalidRequest(theResourceTable != null, "No resource supplied");
|
||||||
if (isPlaceholder(theValueSet)) {
|
if (isPlaceholder(theValueSet)) {
|
||||||
@ -1904,6 +1904,13 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||||||
termValueSet.setVersion(theValueSet.getVersion());
|
termValueSet.setVersion(theValueSet.getVersion());
|
||||||
termValueSet.setName(theValueSet.hasName() ? theValueSet.getName() : null);
|
termValueSet.setName(theValueSet.hasName() ? theValueSet.getName() : null);
|
||||||
|
|
||||||
|
// value sets must be marked as current only when version is present and flag indicates that
|
||||||
|
if (theValueSet.getVersion() != null) {
|
||||||
|
if (ITermCodeSystemStorageSvc.isMakeVersionCurrent(theRequestDetails)) {
|
||||||
|
makeVersionCurrent(theValueSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Delete version being replaced
|
// Delete version being replaced
|
||||||
deleteValueSetForResource(theResourceTable);
|
deleteValueSetForResource(theResourceTable);
|
||||||
|
|
||||||
@ -1940,6 +1947,31 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void makeVersionCurrent(ValueSet theValueSet) {
|
||||||
|
resetCurrentValueSetVersion(theValueSet);
|
||||||
|
|
||||||
|
TermValueSet termValueSet = myTermValueSetDao.findTermValueSetByUrlAndVersion(
|
||||||
|
theValueSet.getUrl(), theValueSet.getVersion())
|
||||||
|
.orElseThrow(() ->
|
||||||
|
new InternalErrorException("Couldn't retrieve TermValueSet with url: " +
|
||||||
|
theValueSet.getUrl() + " and version: " + theValueSet.getVersion() ) );
|
||||||
|
|
||||||
|
termValueSet.setCurrentVersion(true);
|
||||||
|
myTermValueSetDao.save(termValueSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB,
|
public IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB,
|
||||||
@ -2481,4 +2513,18 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
|||||||
return termConcept;
|
return termConcept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@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,7 +399,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
|||||||
theCodeSystemResource.getVersion(), theCodeSystemVersion, resource, theRequest);
|
theCodeSystemResource.getVersion(), theCodeSystemVersion, resource, theRequest);
|
||||||
|
|
||||||
myDeferredStorageSvc.addConceptMapsToStorageQueue(theConceptMaps);
|
myDeferredStorageSvc.addConceptMapsToStorageQueue(theConceptMaps);
|
||||||
myDeferredStorageSvc.addValueSetsToStorageQueue(theValueSets);
|
myDeferredStorageSvc.addValueSetsToStorageQueue(theValueSets, theRequest);
|
||||||
|
|
||||||
return csId;
|
return csId;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import ca.uhn.fhir.jpa.model.sched.ScheduledJobDefinition;
|
|||||||
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.util.StopWatch;
|
import ca.uhn.fhir.util.StopWatch;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
@ -49,6 +50,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.util.Pair;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -65,6 +67,7 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
||||||
|
|
||||||
@ -72,7 +75,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
|||||||
final private List<TermCodeSystem> myDeferredCodeSystemsDeletions = Collections.synchronizedList(new ArrayList<>());
|
final private List<TermCodeSystem> myDeferredCodeSystemsDeletions = Collections.synchronizedList(new ArrayList<>());
|
||||||
final private Queue<TermCodeSystemVersion> myDeferredCodeSystemVersionsDeletions = new ConcurrentLinkedQueue<>();
|
final private Queue<TermCodeSystemVersion> myDeferredCodeSystemVersionsDeletions = new ConcurrentLinkedQueue<>();
|
||||||
final private List<TermConcept> myDeferredConcepts = Collections.synchronizedList(new ArrayList<>());
|
final private List<TermConcept> myDeferredConcepts = Collections.synchronizedList(new ArrayList<>());
|
||||||
final private List<ValueSet> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>());
|
final private List<Pair<ValueSet, RequestDetails>> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>());
|
||||||
final private List<ConceptMap> myDeferredConceptMaps = Collections.synchronizedList(new ArrayList<>());
|
final private List<ConceptMap> myDeferredConceptMaps = Collections.synchronizedList(new ArrayList<>());
|
||||||
final private List<TermConceptParentChildLink> myConceptLinksToSaveLater = Collections.synchronizedList(new ArrayList<>());
|
final private List<TermConceptParentChildLink> myConceptLinksToSaveLater = Collections.synchronizedList(new ArrayList<>());
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -116,9 +119,9 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addValueSetsToStorageQueue(List<ValueSet> theValueSets) {
|
public void addValueSetsToStorageQueue(List<ValueSet> theValueSets, RequestDetails theRequestDetails) {
|
||||||
Validate.notNull(theValueSets);
|
Validate.notNull(theValueSets);
|
||||||
myDeferredValueSets.addAll(theValueSets);
|
myDeferredValueSets.addAll(theValueSets.stream().map(vs -> Pair.of(vs, theRequestDetails)).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -214,12 +217,15 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void processDeferredValueSets() {
|
private void processDeferredValueSets() {
|
||||||
int count = Math.min(myDeferredValueSets.size(), 200);
|
int count = Math.min(myDeferredValueSets.size(), 200);
|
||||||
for (ValueSet nextValueSet : new ArrayList<>(myDeferredValueSets.subList(0, count))) {
|
for (Pair<ValueSet, RequestDetails> nextPair : new ArrayList<>(myDeferredValueSets.subList(0, count))) {
|
||||||
ourLog.info("Creating ValueSet: {}", nextValueSet.getId());
|
ValueSet valueSet = nextPair.getFirst();
|
||||||
myTerminologyVersionAdapterSvc.createOrUpdateValueSet(nextValueSet);
|
RequestDetails requestDetails = nextPair.getSecond();
|
||||||
myDeferredValueSets.remove(nextValueSet);
|
ourLog.info("Creating ValueSet: {}", valueSet.getId());
|
||||||
|
myTerminologyVersionAdapterSvc.createOrUpdateValueSet(valueSet, requestDetails);
|
||||||
|
myDeferredValueSets.remove(nextPair);
|
||||||
}
|
}
|
||||||
ourLog.info("Saved {} deferred ValueSet resources, have {} remaining", count, myDeferredValueSets.size());
|
ourLog.info("Saved {} deferred ValueSet resources, have {} remaining", count, myDeferredValueSets.size());
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,16 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface ITermCodeSystemStorageSvc {
|
public interface ITermCodeSystemStorageSvc {
|
||||||
|
|
||||||
static final String MAKE_LOADING_VERSION_CURRENT = "make.loading.version.current";
|
String MAKE_LOADING_VERSION_CURRENT = "make.loading.version.current";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defaults to true when parameter is null or entry is not present in requestDetails.myUserData
|
||||||
|
*/
|
||||||
|
static boolean isMakeVersionCurrent(RequestDetails theRequestDetails) {
|
||||||
|
return theRequestDetails == null ||
|
||||||
|
(boolean) theRequestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
void deleteCodeSystem(TermCodeSystem theCodeSystem);
|
void deleteCodeSystem(TermCodeSystem theCodeSystem);
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
|||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
|
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ public interface ITermDeferredStorageSvc {
|
|||||||
|
|
||||||
void addConceptMapsToStorageQueue(List<ConceptMap> theConceptMaps);
|
void addConceptMapsToStorageQueue(List<ConceptMap> theConceptMaps);
|
||||||
|
|
||||||
void addValueSetsToStorageQueue(List<ValueSet> theValueSets);
|
void addValueSetsToStorageQueue(List<ValueSet> theValueSets, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
void deleteCodeSystem(TermCodeSystem theCodeSystem);
|
void deleteCodeSystem(TermCodeSystem theCodeSystem);
|
||||||
|
|
||||||
|
@ -4,12 +4,10 @@ import ca.uhn.fhir.context.support.ConceptValidationOptions;
|
|||||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
|
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.term.IValueSetConceptAccumulator;
|
import ca.uhn.fhir.jpa.term.IValueSetConceptAccumulator;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.util.FhirVersionIndependentConcept;
|
import ca.uhn.fhir.util.FhirVersionIndependentConcept;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
@ -17,7 +15,7 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
import org.hl7.fhir.r4.model.UriType;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -91,7 +89,13 @@ public interface ITermReadSvc extends IValidationSupport {
|
|||||||
|
|
||||||
void deleteValueSetAndChildren(ResourceTable theResourceTable);
|
void deleteValueSetAndChildren(ResourceTable theResourceTable);
|
||||||
|
|
||||||
void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet);
|
|
||||||
|
void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
|
default void storeTermValueSet(ResourceTable theResourceTable, ValueSet theValueSet) {
|
||||||
|
storeTermValueSet(theResourceTable, theValueSet, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB, IPrimitiveType<String> theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB);
|
IFhirResourceDaoCodeSystem.SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB, IPrimitiveType<String> theSystem, IBaseCoding theCodingA, IBaseCoding theCodingB);
|
||||||
|
|
||||||
@ -119,4 +123,5 @@ public interface ITermReadSvc extends IValidationSupport {
|
|||||||
*/
|
*/
|
||||||
CodeValidationResult codeSystemValidateCode(IIdType theCodeSystemId, String theValueSetUrl, String theVersion, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept);
|
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 createOrUpdateConceptMap(ConceptMap theNextConceptMap);
|
||||||
|
|
||||||
void createOrUpdateValueSet(ValueSet theValueSet);
|
void createOrUpdateValueSet(ValueSet theValueSet, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user