From 710343a59964d128032c288b69b62d884f8835ed Mon Sep 17 00:00:00 2001 From: "juan.marchionatto" Date: Tue, 31 Aug 2021 13:33:39 -0400 Subject: [PATCH] Use ForcedId to get current ValueSet version --- ...JpaPersistedResourceValidationSupport.java | 48 ++++++++----- .../fhir/jpa/dao/data/ITermValueSetDao.java | 43 +++++++----- .../ca/uhn/fhir/jpa/entity/TermValueSet.java | 30 ++++---- .../r4/BaseJpaResourceProviderValueSetR4.java | 18 ----- .../fhir/jpa/term/BaseTermReadSvcImpl.java | 68 +++++-------------- .../term/TermCodeSystemStorageSvcImpl.java | 4 +- .../jpa/term/TermDeferredStorageSvcImpl.java | 19 ++---- .../jpa/term/TermVersionAdapterSvcDstu2.java | 2 +- .../jpa/term/TermVersionAdapterSvcDstu3.java | 11 +-- .../jpa/term/TermVersionAdapterSvcR4.java | 11 +-- .../jpa/term/TermVersionAdapterSvcR5.java | 11 +-- .../jpa/term/api/ITermDeferredStorageSvc.java | 2 +- .../uhn/fhir/jpa/term/api/ITermReadSvc.java | 10 +-- .../jpa/term/api/ITermVersionAdapterSvc.java | 2 +- .../ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java | 2 +- .../tasks/HapiFhirJpaMigrationTasks.java | 7 -- 16 files changed, 110 insertions(+), 178 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java index be05a547e9d..e46fe36abf9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java @@ -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 myCodeSystemType; private Class myStructureDefinitionType; private Class 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); - return fetchResource(myValueSetType, 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 currentVSOpt = getValueSetCurrentVersion(new UriType(theSystem)); + return currentVSOpt.orElseThrow(() -> new ResourceNotFoundException( + "Couldn't find current version ValueSet for url: " + 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 getValueSetCurrentVersion(UriType theUrl) { + if (! theUrl.getValueAsString().startsWith(LOINC_GENERIC_VALUESET_URL)) return Optional.empty(); - private String appendCurrentVersion(String theSystem) { - // if version is included there is nothing to add here - if (theSystem.contains("|")) return 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()); + } - Optional currentVersionOpt = myITermReadSvc.getValueSetCurrentVersion(new UriType(theSystem)); - - 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)); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java index fbdd1d86921..ac37eac7525 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermValueSetDao.java @@ -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 { @Query("SELECT vs FROM TermValueSet vs WHERE vs.myResourcePid = :resource_pid") @@ -44,28 +47,32 @@ public interface ITermValueSetDao extends JpaRepository { @Query("SELECT vs FROM TermValueSet vs WHERE vs.myExpansionStatus = :expansion_status") Slice 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 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 findTermValueSetByForcedId(@Param("forcedId") String theForcedId); + + default Optional 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 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 findTermValueSetByUrlAndNullVersion(@Param("url") String theUrl); @Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion = :version") Optional 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 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 findTermValueSetByUrlAndCurrentVersion(@Param("url") String theUrl) { - List termValueSets = listTermValueSetsByUrlAndCurrentVersion(theUrl, Pageable.ofSize(1)); - return termValueSets.isEmpty()? Optional.empty() : Optional.of(termValueSets.get(0)); - } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java index 549388877dd..c42e6ca96e0 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSet.java @@ -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; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java index 6021db337e1..94cb8a684e2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderValueSetR4.java @@ -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 { 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 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 optionalExistingTermValueSetById = myValueSetDao.findByResourcePid(theResourceTable.getId()); + Optional 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 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 optionalTermValueSet = myValueSetDao.findByResourcePid(valueSetResourcePid.getIdAsLong()); + Optional 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 getNextTermValueSetNotExpanded() { Optional retVal = Optional.empty(); - Slice page = myValueSetDao.findByExpansionStatus(PageRequest.of(0, 1), TermValueSetPreExpansionStatusEnum.NOT_EXPANDED); + Slice 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 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 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 theCodeA, IPrimitiveType theCodeB, @@ -2509,18 +2487,4 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc { return theReqLang.equalsIgnoreCase(theStoredLang); } - - @Override - @Transactional - public Optional getValueSetCurrentVersion(UriType theUrl) { - Optional termValueSetOpt = - myTermValueSetDao.findTermValueSetByUrlAndCurrentVersion(theUrl.getValueAsString()); - - if (! termValueSetOpt.isPresent() || StringUtils.isBlank(termValueSetOpt.get().getVersion())) { - return Optional.empty(); - } - - return termValueSetOpt.map(TermValueSet::getVersion); - } - } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java index a204f2d6080..6a4d72c0337 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermCodeSystemStorageSvcImpl.java @@ -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; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java index 808138cd649..6e36e2fb331 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermDeferredStorageSvcImpl.java @@ -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 myDeferredCodeSystemsDeletions = Collections.synchronizedList(new ArrayList<>()); final private Queue myDeferredCodeSystemVersionsDeletions = new ConcurrentLinkedQueue<>(); final private List myDeferredConcepts = Collections.synchronizedList(new ArrayList<>()); - final private List> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>()); + final private List myDeferredValueSets = Collections.synchronizedList(new ArrayList<>()); final private List myDeferredConceptMaps = Collections.synchronizedList(new ArrayList<>()); final private List myConceptLinksToSaveLater = Collections.synchronizedList(new ArrayList<>()); @Autowired @@ -118,9 +116,9 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc { } @Override - public void addValueSetsToStorageQueue(List theValueSets, boolean theMakeThemCurrent) { + public void addValueSetsToStorageQueue(List 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 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()); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu2.java index 61947b8460b..6fad466ce7e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu2.java @@ -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(); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java index 047f40bee34..446a5188cfa 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java @@ -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); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR4.java index 70ef2efbfbc..be3cf92be7e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR4.java @@ -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); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java index 18ac5987e70..93e96974d27 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java @@ -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); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java index 6d13a10249e..91cdb11b7f6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermDeferredStorageSvc.java @@ -52,7 +52,7 @@ public interface ITermDeferredStorageSvc { void addConceptMapsToStorageQueue(List theConceptMaps); - void addValueSetsToStorageQueue(List theValueSets, boolean theMakeThemCurrent); + void addValueSetsToStorageQueue(List theValueSets); void deleteCodeSystem(TermCodeSystem theCodeSystem); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java index 6dbe1d0e603..b8e93b2e97f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermReadSvc.java @@ -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 theCodeA, IPrimitiveType theCodeB, IPrimitiveType 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 getValueSetCurrentVersion(UriType theUrl); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermVersionAdapterSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermVersionAdapterSvc.java index 1b528a5b9c3..1f763f5a6b9 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermVersionAdapterSvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermVersionAdapterSvc.java @@ -41,6 +41,6 @@ public interface ITermVersionAdapterSvc { void createOrUpdateConceptMap(ConceptMap theNextConceptMap); - void createOrUpdateValueSet(ValueSet theValueSet, boolean makeItCurrent); + void createOrUpdateValueSet(ValueSet theValueSet); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java index c97c0f682e6..8f00ee5a1d7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r5/BaseJpaR5Test.java @@ -571,7 +571,7 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil public List getExpandedConceptsByValueSetUrl(String theValuesetUrl) { return runInTransaction(() -> { - Optional valueSetOpt = myTermValueSetDao.findTermValueSetByUrlAndCurrentVersion(theValuesetUrl); + Optional valueSetOpt = myTermValueSetDao.findTermValueSetByUrl(theValuesetUrl); assertTrue(valueSetOpt.isPresent()); TermValueSet valueSet = valueSetOpt.get(); List concepts = valueSet.getConcepts(); diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java index 1cedc83eabc..dcd04dcad57 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java +++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java @@ -122,15 +122,8 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks { 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);