Merge remote-tracking branch 'remotes/origin/master' into ks-flyway

This commit is contained in:
Ken Stevens 2019-11-20 14:32:19 -05:00
commit 6a55e1a8cb
127 changed files with 3300 additions and 2859 deletions

View File

@ -0,0 +1,43 @@
package example;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import java.io.FileReader;
public class ValidateSimple {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidateSimple.class);
public static void main(String[] args) throws Exception {
FhirContext ctx = FhirContext.forR4();
// Create a validator module
FhirInstanceValidator instanceValidator = new FhirInstanceValidator();
// We'll create a validation chain with only the DefaultProfileValidationupport registered
ValidationSupportChain validationSupportChain = new ValidationSupportChain();
validationSupportChain.addValidationSupport(new DefaultProfileValidationSupport());
instanceValidator.setValidationSupport(validationSupportChain);
// Create a validator and register the InstanceValidator module
FhirValidator val = ctx.newValidator();
val.registerValidatorModule(instanceValidator);
// Read in the file and validate it
String nextFile = args[0];
try (FileReader fileReader = new FileReader(nextFile)) {
String input = IOUtils.toString(fileReader);
ValidationResult result = val.validateWithResult(input);
IBaseOperationOutcome oo = result.toOperationOutcome();
ourLog.info("Result:\n{}", ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(oo));
}
}
}

View File

@ -1,19 +1,27 @@
package ca.uhn.fhir.context;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
import java.util.*;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
/*
* #%L
@ -44,61 +52,22 @@ public class RuntimeSearchParam {
private final RestSearchParameterTypeEnum myParamType;
private final String myPath;
private final Set<String> myTargets;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("base", myBase)
.append("name", myName)
.append("path", myPath)
.append("id", myId)
.append("uri", myUri)
.toString();
}
private final Set<String> myProvidesMembershipInCompartments;
private final RuntimeSearchParamStatusEnum myStatus;
private final String myUri;
private final Map<String, List<IBaseExtension<?, ?>>> myExtensions = new HashMap<>();
public IIdType getId() {
return myId;
}
public String getUri() {
return myUri;
}
/**
* Constructor
*/
public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List<RuntimeSearchParam> theCompositeOf,
Set<String> theProvidesMembershipInCompartments, Set<String> theTargets, RuntimeSearchParamStatusEnum theStatus) {
this(theId, theUri, theName, theDescription, thePath, theParamType, theCompositeOf, theProvidesMembershipInCompartments, theTargets, theStatus, null);
}
@Override
public boolean equals(Object theO) {
if (this == theO) return true;
if (theO == null || getClass() != theO.getClass()) return false;
RuntimeSearchParam that = (RuntimeSearchParam) theO;
return new EqualsBuilder()
.append(getId(), that.getId())
.append(getName(), that.getName())
.append(getPath(), that.getPath())
.append(getUri(), that.getUri())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(getId())
.append(getName())
.append(getPath())
.append(getUri())
.toHashCode();
}
/**
* Constructor
*/
public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List<RuntimeSearchParam> theCompositeOf,
Set<String> theProvidesMembershipInCompartments, Set<String> theTargets, RuntimeSearchParamStatusEnum theStatus, Collection<String> theBase) {
super();
@ -136,6 +105,77 @@ public class RuntimeSearchParam {
}
}
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set<String> theProvidesMembershipInCompartments, Set<String> theTargets, RuntimeSearchParamStatusEnum theStatus) {
this(null, null, theName, theDescription, thePath, theParamType, null, theProvidesMembershipInCompartments, theTargets, theStatus);
}
/**
* Retrieve user data - This can be used to store any application-specific data
*
* @return
*/
public List<IBaseExtension<?, ?>> getExtensions(String theKey) {
List<IBaseExtension<?, ?>> retVal = myExtensions.get(theKey);
if (retVal != null) {
retVal = Collections.unmodifiableList(retVal);
}
return retVal;
}
/**
* Sets user data - This can be used to store any application-specific data
*/
public RuntimeSearchParam addExtension(String theKey, IBaseExtension theValue) {
List<IBaseExtension<?, ?>> valuesList = myExtensions.computeIfAbsent(theKey, k -> new ArrayList<>());
valuesList.add(theValue);
return this;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("base", myBase)
.append("name", myName)
.append("path", myPath)
.append("id", myId)
.append("uri", myUri)
.toString();
}
public IIdType getId() {
return myId;
}
public String getUri() {
return myUri;
}
@Override
public boolean equals(Object theO) {
if (this == theO) return true;
if (theO == null || getClass() != theO.getClass()) return false;
RuntimeSearchParam that = (RuntimeSearchParam) theO;
return new EqualsBuilder()
.append(getId(), that.getId())
.append(getName(), that.getName())
.append(getPath(), that.getPath())
.append(getUri(), that.getUri())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(getId())
.append(getName())
.append(getPath())
.append(getUri())
.toHashCode();
}
public Set<String> getBase() {
return myBase;
}
@ -153,10 +193,6 @@ public class RuntimeSearchParam {
return myStatus;
}
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set<String> theProvidesMembershipInCompartments, Set<String> theTargets, RuntimeSearchParamStatusEnum theStatus) {
this(null, null, theName, theDescription, thePath, theParamType, null, theProvidesMembershipInCompartments, theTargets, theStatus);
}
public List<RuntimeSearchParam> getCompositeOf() {
return myCompositeOf;
}
@ -206,5 +242,5 @@ public class RuntimeSearchParam {
RETIRED,
UNKNOWN
}
}

View File

@ -118,11 +118,10 @@ public class ReflectionUtil {
/**
* Instantiate a class by no-arg constructor, throw {@link ConfigurationException} if we fail to do so
*/
@CoverageIgnore
public static <T> T newInstance(Class<T> theType) {
Validate.notNull(theType, "theType must not be null");
try {
return theType.newInstance();
return theType.getConstructor().newInstance();
} catch (Exception e) {
throw new ConfigurationException("Failed to instantiate " + theType.getName(), e);
}

View File

@ -25,6 +25,7 @@ import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IResultIterator;
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.IBulkExportCollectionDao;
import ca.uhn.fhir.jpa.dao.data.IBulkExportCollectionFileDao;
import ca.uhn.fhir.jpa.dao.data.IBulkExportJobDao;
@ -251,7 +252,7 @@ public class BulkDataExportSvcImpl implements IBulkDataExportSvc {
OutputStreamWriter writer = new OutputStreamWriter(outputStream, Constants.CHARSET_UTF8);
IParser parser = myContext.newJsonParser().setPrettyPrint(false);
List<Long> pidsSpool = new ArrayList<>();
List<ResourcePersistentId> pidsSpool = new ArrayList<>();
List<IBaseResource> resourcesSpool = new ArrayList<>();
while (query.hasNext()) {
pidsSpool.add(query.next());

View File

@ -10,6 +10,7 @@ import ca.uhn.fhir.jpa.bulk.BulkDataExportProvider;
import ca.uhn.fhir.jpa.bulk.BulkDataExportSvcImpl;
import ca.uhn.fhir.jpa.bulk.IBulkDataExportSvc;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
import ca.uhn.fhir.jpa.graphql.JpaStorageServices;
import ca.uhn.fhir.jpa.interceptor.JpaConsentContextServices;
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
@ -26,6 +27,8 @@ import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
import ca.uhn.fhir.jpa.search.reindex.ResourceReindexingSvcImpl;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.subscription.SubscriptionActivatingInterceptor;
import ca.uhn.fhir.jpa.subscription.dbmatcher.CompositeInMemoryDaoSubscriptionMatcher;
import ca.uhn.fhir.jpa.subscription.dbmatcher.DaoSubscriptionMatcher;
@ -129,6 +132,12 @@ public abstract class BaseConfig {
return b;
}
@Bean
public ISearchParamRegistry searchParamRegistry() {
return new SearchParamRegistryImpl();
}
@Bean(name = "mySubscriptionTriggeringProvider")
@Lazy
public SubscriptionTriggeringProvider subscriptionTriggeringProvider() {

View File

@ -5,16 +5,11 @@ import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorDstu2;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryDstu2;
import ca.uhn.fhir.jpa.term.TermReadSvcDstu2;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu2;
import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.validation.IInstanceValidatorModule;
import ca.uhn.fhir.validation.IValidatorModule;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.instance.hapi.validation.CachingValidationSupport;
import org.hl7.fhir.instance.hapi.validation.DefaultProfileValidationSupport;
@ -117,11 +112,6 @@ public class BaseDstu2Config extends BaseConfig {
return new SearchParamExtractorDstu2();
}
@Bean
public ISearchParamRegistry searchParamRegistry() {
return new SearchParamRegistryDstu2();
}
@Bean(name = "mySystemDaoDstu2", autowire = Autowire.BY_NAME)
public IFhirSystemDao<ca.uhn.fhir.model.dstu2.resource.Bundle, MetaDt> systemDaoDstu2() {
ca.uhn.fhir.jpa.dao.FhirSystemDaoDstu2 retVal = new ca.uhn.fhir.jpa.dao.FhirSystemDaoDstu2();

View File

@ -2,7 +2,6 @@ package ca.uhn.fhir.jpa.config.dstu3;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.ParserOptions;
import ca.uhn.fhir.jpa.config.BaseConfig;
import ca.uhn.fhir.jpa.config.BaseConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
@ -11,24 +10,20 @@ import ca.uhn.fhir.jpa.dao.TransactionProcessor;
import ca.uhn.fhir.jpa.dao.dstu3.TransactionProcessorVersionAdapterDstu3;
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorDstu3;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryDstu3;
import ca.uhn.fhir.jpa.term.TermReadSvcDstu3;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcDstu3;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu3;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainDstu3;
import ca.uhn.fhir.validation.IInstanceValidatorModule;
import ca.uhn.fhir.validation.IValidatorModule;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.CachingValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -95,8 +90,8 @@ public class BaseDstu3Config extends BaseConfigDstu3Plus {
}
@Bean
public TransactionProcessor<Bundle, Bundle.BundleEntryComponent> transactionProcessor() {
return new TransactionProcessor<>();
public TransactionProcessor transactionProcessor() {
return new TransactionProcessor();
}
@Bean(name = "myInstanceValidatorDstu3")
@ -140,11 +135,6 @@ public class BaseDstu3Config extends BaseConfigDstu3Plus {
return new SearchParamExtractorDstu3();
}
@Bean
public ISearchParamRegistry searchParamRegistry() {
return new SearchParamRegistryDstu3();
}
@Bean(name = "mySystemDaoDstu3")
public IFhirSystemDao<org.hl7.fhir.dstu3.model.Bundle, org.hl7.fhir.dstu3.model.Meta> systemDaoDstu3() {
return new ca.uhn.fhir.jpa.dao.dstu3.FhirSystemDaoDstu3();

View File

@ -2,7 +2,6 @@ package ca.uhn.fhir.jpa.config.r4;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.ParserOptions;
import ca.uhn.fhir.jpa.config.BaseConfig;
import ca.uhn.fhir.jpa.config.BaseConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
@ -11,22 +10,20 @@ import ca.uhn.fhir.jpa.dao.TransactionProcessor;
import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4;
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryR4;
import ca.uhn.fhir.jpa.term.*;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcR4;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR4;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainR4;
import ca.uhn.fhir.validation.IInstanceValidatorModule;
import ca.uhn.fhir.validation.IValidatorModule;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport;
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r4.hapi.validation.CachingValidationSupport;
import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
@ -88,8 +85,8 @@ public class BaseR4Config extends BaseConfigDstu3Plus {
}
@Bean
public TransactionProcessor<Bundle, Bundle.BundleEntryComponent> transactionProcessor() {
return new TransactionProcessor<>();
public TransactionProcessor transactionProcessor() {
return new TransactionProcessor();
}
@Bean(name = GRAPHQL_PROVIDER_NAME)
@ -142,11 +139,6 @@ public class BaseR4Config extends BaseConfigDstu3Plus {
return new SearchParamExtractorR4();
}
@Bean
public ISearchParamRegistry searchParamRegistry() {
return new SearchParamRegistryR4();
}
@Bean(name = "mySystemDaoR4", autowire = Autowire.BY_NAME)
public IFhirSystemDao<org.hl7.fhir.r4.model.Bundle, org.hl7.fhir.r4.model.Meta> systemDaoR4() {
ca.uhn.fhir.jpa.dao.r4.FhirSystemDaoR4 retVal = new ca.uhn.fhir.jpa.dao.r4.FhirSystemDaoR4();

View File

@ -10,8 +10,6 @@ import ca.uhn.fhir.jpa.dao.TransactionProcessor;
import ca.uhn.fhir.jpa.dao.r5.TransactionProcessorVersionAdapterR5;
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR5;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryR5;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcR5;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR5;
@ -88,8 +86,8 @@ public class BaseR5Config extends BaseConfigDstu3Plus {
}
@Bean
public TransactionProcessor<Bundle, Bundle.BundleEntryComponent> transactionProcessor() {
return new TransactionProcessor<>();
public TransactionProcessor transactionProcessor() {
return new TransactionProcessor();
}
@Bean(name = GRAPHQL_PROVIDER_NAME)
@ -142,11 +140,6 @@ public class BaseR5Config extends BaseConfigDstu3Plus {
return new SearchParamExtractorR5();
}
@Bean
public ISearchParamRegistry searchParamRegistry() {
return new SearchParamRegistryR5();
}
@Bean(name = "mySystemDaoR5", autowire = Autowire.BY_NAME)
public IFhirSystemDao<Bundle, org.hl7.fhir.r5.model.Meta> systemDaoR5() {
ca.uhn.fhir.jpa.dao.r5.FhirSystemDaoR5 retVal = new ca.uhn.fhir.jpa.dao.r5.FhirSystemDaoR5();

View File

@ -1,10 +1,21 @@
package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceProvenanceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
import ca.uhn.fhir.jpa.dao.expunge.ExpungeService;
import ca.uhn.fhir.jpa.dao.index.DaoSearchParamSynchronizer;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
@ -13,6 +24,7 @@ import ca.uhn.fhir.jpa.delete.DeleteConflictService;
import ca.uhn.fhir.jpa.entity.ResourceSearchView;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
@ -74,7 +86,11 @@ import org.springframework.transaction.support.TransactionSynchronizationAdapter
import org.springframework.transaction.support.TransactionSynchronizationManager;
import javax.annotation.PostConstruct;
import javax.persistence.*;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
@ -83,7 +99,12 @@ import javax.xml.stream.events.XMLEvent;
import java.util.*;
import java.util.Map.Entry;
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.left;
import static org.apache.commons.lang3.StringUtils.trim;
/*
* #%L
@ -107,7 +128,7 @@ import static org.apache.commons.lang3.StringUtils.*;
@SuppressWarnings("WeakerAccess")
@Repository
public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao, IJpaDao<T>, ApplicationContextAware {
public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStorageDao implements IDao, IJpaDao<T>, ApplicationContextAware {
public static final long INDEX_STATUS_INDEXED = 1L;
public static final long INDEX_STATUS_INDEXING_FAILED = 2L;
@ -168,6 +189,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
private FhirContext myContext;
private ApplicationContext myApplicationContext;
@Override
protected IInterceptorBroadcaster getInterceptorBroadcaster() {
return myInterceptorBroadcaster;
}
protected ApplicationContext getApplicationContext() {
return myApplicationContext;
}
@ -290,6 +316,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
return retVal;
}
@Override
protected DaoConfig getConfig() {
return myConfig;
}
@ -925,34 +952,36 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
@SuppressWarnings("unchecked")
@Override
public ResourceTable updateEntity(RequestDetails theRequest, final IBaseResource theResource, ResourceTable
public ResourceTable updateEntity(RequestDetails theRequest, final IBaseResource theResource, IBasePersistedResource
theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
Validate.notNull(theEntity);
Validate.isTrue(theDeletedTimestampOrNull != null || theResource != null, "Must have either a resource[%s] or a deleted timestamp[%s] for resource PID[%s]", theDeletedTimestampOrNull != null, theResource != null, theEntity.getId());
Validate.isTrue(theDeletedTimestampOrNull != null || theResource != null, "Must have either a resource[%s] or a deleted timestamp[%s] for resource PID[%s]", theDeletedTimestampOrNull != null, theResource != null, theEntity.getPersistentId());
ourLog.debug("Starting entity update");
ResourceTable entity = (ResourceTable) theEntity;
/*
* This should be the very first thing..
*/
if (theResource != null) {
if (thePerformIndexing) {
if (!ourValidationDisabledForUnitTest) {
validateResourceForStorage((T) theResource, theEntity);
validateResourceForStorage((T) theResource, entity);
}
}
String resourceType = myContext.getResourceDefinition(theResource).getName();
if (isNotBlank(theEntity.getResourceType()) && !theEntity.getResourceType().equals(resourceType)) {
if (isNotBlank(entity.getResourceType()) && !entity.getResourceType().equals(resourceType)) {
throw new UnprocessableEntityException(
"Existing resource ID[" + theEntity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + theEntity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
"Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
}
}
if (theEntity.getPublished() == null) {
if (entity.getPublished() == null) {
ourLog.debug("Entity has published time: {}", new InstantDt(theUpdateTime));
theEntity.setPublished(theUpdateTime);
entity.setPublished(theUpdateTime);
}
ResourceIndexedSearchParams existingParams = null;
@ -963,89 +992,89 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
if (theDeletedTimestampOrNull != null) {
// DELETE
theEntity.setDeleted(theDeletedTimestampOrNull);
theEntity.setUpdated(theDeletedTimestampOrNull);
theEntity.setNarrativeTextParsedIntoWords(null);
theEntity.setContentTextParsedIntoWords(null);
theEntity.setHashSha256(null);
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, true);
entity.setDeleted(theDeletedTimestampOrNull);
entity.setUpdated(theDeletedTimestampOrNull);
entity.setNarrativeTextParsedIntoWords(null);
entity.setContentTextParsedIntoWords(null);
entity.setHashSha256(null);
entity.setIndexStatus(INDEX_STATUS_INDEXED);
changed = populateResourceIntoEntity(theRequest, theResource, entity, true);
} else {
// CREATE or UPDATE
existingParams = new ResourceIndexedSearchParams(theEntity);
theEntity.setDeleted(null);
existingParams = new ResourceIndexedSearchParams(entity);
entity.setDeleted(null);
if (thePerformIndexing) {
newParams = new ResourceIndexedSearchParams();
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, theUpdateTime, theEntity, theResource, existingParams, theRequest);
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, theUpdateTime, entity, theResource, existingParams, theRequest);
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, true);
changed = populateResourceIntoEntity(theRequest, theResource, entity, true);
if (changed.isChanged()) {
theEntity.setUpdated(theUpdateTime);
entity.setUpdated(theUpdateTime);
if (theResource instanceof IResource) {
theEntity.setLanguage(((IResource) theResource).getLanguage().getValue());
entity.setLanguage(((IResource) theResource).getLanguage().getValue());
} else {
theEntity.setLanguage(((IAnyResource) theResource).getLanguageElement().getValue());
entity.setLanguage(((IAnyResource) theResource).getLanguageElement().getValue());
}
newParams.setParamsOn(theEntity);
theEntity.setIndexStatus(INDEX_STATUS_INDEXED);
populateFullTextFields(myContext, theResource, theEntity);
newParams.setParamsOn(entity);
entity.setIndexStatus(INDEX_STATUS_INDEXED);
populateFullTextFields(myContext, theResource, entity);
}
} else {
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, false);
changed = populateResourceIntoEntity(theRequest, theResource, entity, false);
theEntity.setUpdated(theUpdateTime);
theEntity.setIndexStatus(null);
entity.setUpdated(theUpdateTime);
entity.setIndexStatus(null);
}
}
if (!changed.isChanged() && !theForceUpdate && myConfig.isSuppressUpdatesWithNoChange()) {
ourLog.debug("Resource {} has not changed", theEntity.getIdDt().toUnqualified().getValue());
ourLog.debug("Resource {} has not changed", entity.getIdDt().toUnqualified().getValue());
if (theResource != null) {
updateResourceMetadata(theEntity, theResource);
updateResourceMetadata(entity, theResource);
}
theEntity.setUnchangedInCurrentOperation(true);
return theEntity;
entity.setUnchangedInCurrentOperation(true);
return entity;
}
if (theUpdateVersion) {
theEntity.setVersion(theEntity.getVersion() + 1);
entity.setVersion(entity.getVersion() + 1);
}
/*
* Save the resource itself
*/
if (theEntity.getId() == null) {
myEntityManager.persist(theEntity);
if (entity.getId() == null) {
myEntityManager.persist(entity);
if (theEntity.getForcedId() != null) {
myEntityManager.persist(theEntity.getForcedId());
if (entity.getForcedId() != null) {
myEntityManager.persist(entity.getForcedId());
}
postPersist(theEntity, (T) theResource);
postPersist(entity, (T) theResource);
} else if (theEntity.getDeleted() != null) {
theEntity = myEntityManager.merge(theEntity);
} else if (entity.getDeleted() != null) {
entity = myEntityManager.merge(entity);
postDelete(theEntity);
postDelete(entity);
} else {
theEntity = myEntityManager.merge(theEntity);
entity = myEntityManager.merge(entity);
postUpdate(theEntity, (T) theResource);
postUpdate(entity, (T) theResource);
}
/*
* Create history entry
*/
if (theCreateNewHistoryEntry) {
final ResourceHistoryTable historyEntry = theEntity.toHistory();
final ResourceHistoryTable historyEntry = entity.toHistory();
historyEntry.setEncoding(changed.getEncoding());
historyEntry.setResource(changed.getResource());
@ -1076,7 +1105,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
if (haveSource || haveRequestId) {
ResourceHistoryProvenanceEntity provenance = new ResourceHistoryProvenanceEntity();
provenance.setResourceHistoryTable(historyEntry);
provenance.setResourceTable(theEntity);
provenance.setResourceTable(entity);
if (haveRequestId) {
provenance.setRequestId(left(requestId, Constants.REQUEST_ID_LENGTH));
}
@ -1102,7 +1131,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
for (String nextKey : newParams.getPopulatedResourceLinkParameters()) {
presentSearchParams.put(nextKey, Boolean.TRUE);
}
Set<Entry<String, RuntimeSearchParam>> activeSearchParams = mySearchParamRegistry.getActiveSearchParams(theEntity.getResourceType()).entrySet();
Set<Entry<String, RuntimeSearchParam>> activeSearchParams = mySearchParamRegistry.getActiveSearchParams(entity.getResourceType()).entrySet();
for (Entry<String, RuntimeSearchParam> nextSpEntry : activeSearchParams) {
if (nextSpEntry.getValue().getParamType() == RestSearchParameterTypeEnum.REFERENCE) {
if (!presentSearchParams.containsKey(nextSpEntry.getKey())) {
@ -1110,13 +1139,13 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
}
}
AddRemoveCount presenceCount = mySearchParamPresenceSvc.updatePresence(theEntity, presentSearchParams);
AddRemoveCount presenceCount = mySearchParamPresenceSvc.updatePresence(entity, presentSearchParams);
// Interceptor broadcast: JPA_PERFTRACE_INFO
if (!presenceCount.isEmpty()) {
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
StorageProcessingMessage message = new StorageProcessingMessage();
message.setMessage("For " + theEntity.getIdDt().toUnqualifiedVersionless().getValue() + " added " + presenceCount.getAddCount() + " and removed " + presenceCount.getRemoveCount() + " resource search parameter presence entries");
message.setMessage("For " + entity.getIdDt().toUnqualifiedVersionless().getValue() + " added " + presenceCount.getAddCount() + " and removed " + presenceCount.getRemoveCount() + " resource search parameter presence entries");
HookParams params = new HookParams()
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest)
@ -1132,17 +1161,17 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
*/
if (thePerformIndexing) {
if (newParams == null) {
myExpungeService.deleteAllSearchParams(theEntity.getId());
myExpungeService.deleteAllSearchParams(entity.getId());
} else {
// Synchronize search param indexes
AddRemoveCount searchParamAddRemoveCount = myDaoSearchParamSynchronizer.synchronizeSearchParamsToDatabase(newParams, theEntity, existingParams);
AddRemoveCount searchParamAddRemoveCount = myDaoSearchParamSynchronizer.synchronizeSearchParamsToDatabase(newParams, entity, existingParams);
// Interceptor broadcast: JPA_PERFTRACE_INFO
if (!searchParamAddRemoveCount.isEmpty()) {
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
StorageProcessingMessage message = new StorageProcessingMessage();
message.setMessage("For " + theEntity.getIdDt().toUnqualifiedVersionless().getValue() + " added " + searchParamAddRemoveCount.getAddCount() + " and removed " + searchParamAddRemoveCount.getRemoveCount() + " resource search parameter index entries");
message.setMessage("For " + entity.getIdDt().toUnqualifiedVersionless().getValue() + " added " + searchParamAddRemoveCount.getAddCount() + " and removed " + searchParamAddRemoveCount.getRemoveCount() + " resource search parameter index entries");
HookParams params = new HookParams()
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest)
@ -1152,25 +1181,27 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
// Syncrhonize composite params
mySearchParamWithInlineReferencesExtractor.storeCompositeStringUniques(newParams, theEntity, existingParams);
mySearchParamWithInlineReferencesExtractor.storeCompositeStringUniques(newParams, entity, existingParams);
}
}
if (theResource != null) {
updateResourceMetadata(theEntity, theResource);
updateResourceMetadata(entity, theResource);
}
return theEntity;
return entity;
}
@Override
public ResourceTable updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion,
ResourceTable theEntity, IIdType theResourceId, IBaseResource theOldResource) {
IBasePersistedResource theEntity2, IIdType theResourceId, IBaseResource theOldResource) {
ResourceTable entity = (ResourceTable) theEntity2;
// We'll update the resource ID with the correct version later but for
// now at least set it to something useful for the interceptors
theResource.setId(theEntity.getIdDt());
theResource.setId(entity.getIdDt());
// Notify interceptors
ActionRequestDetails requestDetails;
@ -1188,7 +1219,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
doCallHooks(theRequestDetails, Pointcut.STORAGE_PRESTORAGE_RESOURCE_UPDATED, hookParams);
// Perform update
ResourceTable savedEntity = updateEntity(theRequestDetails, theResource, theEntity, null, thePerformIndexing, thePerformIndexing, new Date(), theForceUpdateVersion, thePerformIndexing);
ResourceTable savedEntity = updateEntity(theRequestDetails, theResource, entity, null, thePerformIndexing, thePerformIndexing, new Date(), theForceUpdateVersion, thePerformIndexing);
/*
* If we aren't indexing (meaning we're probably executing a sub-operation within a transaction),
@ -1226,18 +1257,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
return savedEntity;
}
protected void addPidToResource(ResourceTable theEntity, IBaseResource theResource) {
protected void addPidToResource(IBasePersistedResource theEntity, IBaseResource theResource) {
if (theResource instanceof IAnyResource) {
IDao.RESOURCE_PID.put((IAnyResource) theResource, theEntity.getId());
IDao.RESOURCE_PID.put((IAnyResource) theResource, theEntity.getPersistentId().getIdAsLong());
} else if (theResource instanceof IResource) {
IDao.RESOURCE_PID.put((IResource) theResource, theEntity.getId());
IDao.RESOURCE_PID.put((IResource) theResource, theEntity.getPersistentId().getIdAsLong());
}
}
protected void doCallHooks(RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, thePointcut, theParams);
}
protected void updateResourceMetadata(IBaseResourceEntity theEntity, IBaseResource theResource) {
IIdType id = theEntity.getIdDt();
if (getContext().getVersion().getVersion().isRi()) {

View File

@ -26,7 +26,15 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.delete.DeleteConflictList;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.BaseTag;
import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.entity.TagDefinition;
import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
@ -40,22 +48,50 @@ import ca.uhn.fhir.jpa.util.xmlpatch.XmlPatchUtils;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.*;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.PatchTypeEnum;
import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.param.QualifierDetails;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.rest.server.method.SearchMethodBinding;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.*;
import ca.uhn.fhir.validation.*;
import ca.uhn.fhir.util.ObjectUtil;
import ca.uhn.fhir.util.OperationOutcomeUtil;
import ca.uhn.fhir.util.ReflectionUtil;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.IInstanceValidatorModule;
import ca.uhn.fhir.validation.IValidationContext;
import ca.uhn.fhir.validation.IValidatorModule;
import ca.uhn.fhir.validation.ValidationOptions;
import ca.uhn.fhir.validation.ValidationResult;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.r4.model.InstantType;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseMetaType;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Propagation;
@ -64,12 +100,10 @@ import org.springframework.transaction.support.TransactionSynchronizationAdapter
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.*;
@ -168,24 +202,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return create(theResource, theIfNoneExist, true, new Date(), theRequestDetails);
}
public IBaseOperationOutcome createErrorOperationOutcome(String theMessage, String theCode) {
return createOperationOutcome(OO_SEVERITY_ERROR, theMessage, theCode);
}
public IBaseOperationOutcome createInfoOperationOutcome(String theMessage) {
return createOperationOutcome(OO_SEVERITY_INFO, theMessage, "informational");
}
private IInstanceValidatorModule getInstanceValidator() {
return myInstanceValidator;
}
private IBaseOperationOutcome createOperationOutcome(String theSeverity, String theMessage, String theCode) {
IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getContext());
OperationOutcomeUtil.addIssue(getContext(), oo, theSeverity, theMessage, null, theCode);
return oo;
}
@Override
public DaoMethodOutcome delete(IIdType theId) {
return delete(theId, null);
@ -281,7 +301,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
DaoMethodOutcome retVal = delete(theId, deleteConflicts, theRequestDetails);
myDeleteConflictService.validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
DeleteConflictService.validateDeleteConflictsEmptyOrThrowException(getContext(), deleteConflicts);
ourLog.debug("Processed delete on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
return retVal;
@ -295,7 +315,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
public DeleteMethodOutcome deleteByUrl(String theUrl, DeleteConflictList deleteConflicts, RequestDetails theRequest) {
StopWatch w = new StopWatch();
Set<Long> resourceIds = myMatchResourceUrlService.processMatchUrl(theUrl, myResourceType, theRequest);
Set<ResourcePersistentId> resourceIds = myMatchResourceUrlService.processMatchUrl(theUrl, myResourceType, theRequest);
if (resourceIds.size() > 1) {
if (myDaoConfig.isAllowMultipleDelete() == false) {
throw new PreconditionFailedException(getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "DELETE", theUrl, resourceIds.size()));
@ -303,8 +323,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
List<ResourceTable> deletedResources = new ArrayList<>();
for (Long pid : resourceIds) {
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid);
for (ResourcePersistentId pid : resourceIds) {
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid.getId());
deletedResources.add(entity);
T resourceToDelete = toResource(myResourceType, entity, null, false);
@ -372,7 +392,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
DeleteMethodOutcome outcome = deleteByUrl(theUrl, deleteConflicts, theRequestDetails);
myDeleteConflictService.validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
DeleteConflictService.validateDeleteConflictsEmptyOrThrowException(getContext(), deleteConflicts);
return outcome;
}
@ -399,13 +419,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
entity.setResourceType(toResourceName(theResource));
if (isNotBlank(theIfNoneExist)) {
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theIfNoneExist, myResourceType, theRequest);
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theIfNoneExist, myResourceType, theRequest);
if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "CREATE", theIfNoneExist, match.size());
throw new PreconditionFailedException(msg);
} else if (match.size() == 1) {
Long pid = match.iterator().next();
entity = myEntityManager.find(ResourceTable.class, pid);
ResourcePersistentId pid = match.iterator().next();
entity = myEntityManager.find(ResourceTable.class, pid.getId());
IBaseResource resource = toResource(entity, false);
theResource.setId(resource.getIdElement().getValue());
return toMethodOutcome(theRequest, entity, resource).setCreated(false);
@ -605,6 +625,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return myExpungeService.expunge(getResourceName(), null, null, theExpungeOptions, theRequestDetails);
}
@Override
public String getResourceName() {
return myResourceName;
}
@ -790,13 +811,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ResourceTable entityToUpdate;
if (isNotBlank(theConditionalUrl)) {
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theConditionalUrl, myResourceType, theRequest);
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theConditionalUrl, myResourceType, theRequest);
if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "PATCH", theConditionalUrl, match.size());
throw new PreconditionFailedException(msg);
} else if (match.size() == 1) {
Long pid = match.iterator().next();
entityToUpdate = myEntityManager.find(ResourceTable.class, pid);
ResourcePersistentId pid = match.iterator().next();
entityToUpdate = myEntityManager.find(ResourceTable.class, pid.getId());
} else {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "invalidMatchUrlNoMatches", theConditionalUrl);
throw new ResourceNotFoundException(msg);
@ -848,57 +869,16 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
// nothing by default
}
/**
* May be overridden by subclasses to validate resources prior to storage
*
* @param theResource The resource that is about to be stored
*/
protected void preProcessResourceForStorage(T theResource) {
String type = getContext().getResourceDefinition(theResource).getName();
if (!getResourceName().equals(type)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessageSanitized(BaseHapiFhirResourceDao.class, "incorrectResourceType", type, getResourceName()));
}
if (theResource.getIdElement().hasIdPart()) {
if (!theResource.getIdElement().isIdPartValid()) {
throw new InvalidRequestException(getContext().getLocalizer().getMessageSanitized(BaseHapiFhirResourceDao.class, "failedToCreateWithInvalidId", theResource.getIdElement().getIdPart()));
}
}
/*
* Replace absolute references with relative ones if configured to do so
*/
if (getConfig().getTreatBaseUrlsAsLocal().isEmpty() == false) {
FhirTerser t = getContext().newTerser();
List<ResourceReferenceInfo> refs = t.getAllResourceReferences(theResource);
for (ResourceReferenceInfo nextRef : refs) {
IIdType refId = nextRef.getResourceReference().getReferenceElement();
if (refId != null && refId.hasBaseUrl()) {
if (getConfig().getTreatBaseUrlsAsLocal().contains(refId.getBaseUrl())) {
IIdType newRefId = refId.toUnqualified();
nextRef.getResourceReference().setReference(newRefId.getValue());
}
}
}
}
}
@Override
public Set<Long> processMatchUrl(String theMatchUrl, RequestDetails theRequest) {
return myMatchResourceUrlService.processMatchUrl(theMatchUrl, getResourceType(), theRequest);
}
@Override
public IBaseResource readByPid(Long thePid) {
public IBaseResource readByPid(ResourcePersistentId thePid) {
StopWatch w = new StopWatch();
Optional<ResourceTable> entity = myResourceTableDao.findById(thePid);
Optional<ResourceTable> entity = myResourceTableDao.findById(thePid.getIdAsLong());
if (!entity.isPresent()) {
throw new ResourceNotFoundException("No resource found with PID " + thePid);
}
if (entity.get().getDeleted() != null) {
throw newResourceGoneException(entity.get());
throw createResourceGoneException(entity.get());
}
T retVal = toResource(myResourceType, entity.get(), null, false);
@ -907,17 +887,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return retVal;
}
@NotNull
private ResourceGoneException newResourceGoneException(BaseHasResource theResourceEntity) {
StringBuilder b = new StringBuilder();
b.append("Resource was deleted at ");
b.append(new InstantType(theResourceEntity.getDeleted()).getValueAsString());
ResourceGoneException retVal = new ResourceGoneException(b.toString());
retVal.setResourceId(theResourceEntity.getIdDt());
return retVal;
}
@Override
public T read(IIdType theId) {
return read(theId, null);
@ -947,7 +916,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (theDeletedOk == false) {
if (entity.getDeleted() != null) {
throw newResourceGoneException(entity);
throw createResourceGoneException(entity);
}
}
@ -990,8 +959,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
public BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId, RequestDetails theRequest) {
validateResourceTypeAndThrowInvalidRequestException(theId);
Long pid = myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart(), theRequest);
BaseHasResource entity = myEntityManager.find(ResourceTable.class, pid);
ResourcePersistentId pid = myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart(), theRequest);
BaseHasResource entity = myEntityManager.find(ResourceTable.class, pid.getIdAsLong());
if (entity == null) {
throw new ResourceNotFoundException(theId);
@ -1009,7 +978,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (entity == null) {
if (theId.hasVersionIdPart()) {
TypedQuery<ResourceHistoryTable> q = myEntityManager.createQuery("SELECT t from ResourceHistoryTable t WHERE t.myResourceId = :RID AND t.myResourceType = :RTYP AND t.myResourceVersion = :RVER", ResourceHistoryTable.class);
q.setParameter("RID", pid);
q.setParameter("RID", pid.getId());
q.setParameter("RTYP", myResourceName);
q.setParameter("RVER", theId.getVersionIdPartAsLong());
try {
@ -1029,7 +998,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
protected ResourceTable readEntityLatestVersion(IIdType theId, RequestDetails theRequest) {
ResourceTable entity = myEntityManager.find(ResourceTable.class, myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart(), theRequest));
ResourcePersistentId persistentId = myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart(), theRequest);
ResourceTable entity = myEntityManager.find(ResourceTable.class, persistentId.getId());
if (entity == null) {
throw new ResourceNotFoundException(theId);
}
@ -1154,14 +1124,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public Set<Long> searchForIds(SearchParameterMap theParams, RequestDetails theRequest) {
public Set<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest) {
SearchBuilder builder = newSearchBuilder();
builder.setType(getResourceType(), getResourceName());
// FIXME: fail if too many results
HashSet<Long> retVal = new HashSet<>();
HashSet<ResourcePersistentId> retVal = new HashSet<>();
String uuid = UUID.randomUUID().toString();
SearchRuntimeDetails searchRuntimeDetails = new SearchRuntimeDetails(theRequest, uuid);
@ -1178,12 +1148,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
protected <MT extends IBaseMetaType> MT toMetaDt(Class<MT> theType, Collection<TagDefinition> tagDefinitions) {
MT retVal;
try {
retVal = theType.newInstance();
} catch (Exception e) {
throw new InternalErrorException("Failed to instantiate " + theType.getName(), e);
}
MT retVal = ReflectionUtil.newInstance(theType);
for (TagDefinition next : tagDefinitions) {
switch (next.getTagType()) {
case PROFILE:
@ -1200,58 +1165,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return retVal;
}
private DaoMethodOutcome toMethodOutcome(RequestDetails theRequest, @Nonnull final ResourceTable theEntity, @Nonnull IBaseResource theResource) {
DaoMethodOutcome outcome = new DaoMethodOutcome();
IIdType id = null;
if (theResource.getIdElement().getValue() != null) {
id = theResource.getIdElement();
}
if (id == null) {
id = theEntity.getIdDt();
if (getContext().getVersion().getVersion().isRi()) {
id = getContext().getVersion().newIdType().setValue(id.getValue());
}
}
outcome.setId(id);
if (theEntity.getDeleted() == null) {
outcome.setResource(theResource);
}
outcome.setEntity(theEntity);
// Interceptor broadcast: STORAGE_PREACCESS_RESOURCES
if (outcome.getResource() != null) {
SimplePreResourceAccessDetails accessDetails = new SimplePreResourceAccessDetails(outcome.getResource());
HookParams params = new HookParams()
.add(IPreResourceAccessDetails.class, accessDetails)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
if (accessDetails.isDontReturnResourceAtIndex(0)) {
outcome.setResource(null);
}
}
// Interceptor broadcast: STORAGE_PRESHOW_RESOURCES
// Note that this will only fire if someone actually goes to use the
// resource in a response (it's their responsibility to call
// outcome.fireResourceViewCallback())
outcome.registerResourceViewCallback(() -> {
if (outcome.getResource() != null) {
SimplePreResourceShowDetails showDetails = new SimplePreResourceShowDetails(outcome.getResource());
HookParams params = new HookParams()
.add(IPreResourceShowDetails.class, showDetails)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
outcome.setResource(showDetails.getResource(0));
}
});
return outcome;
}
private ArrayList<TagDefinition> toTagList(IBaseMetaType theMeta) {
ArrayList<TagDefinition> retVal = new ArrayList<>();
@ -1340,13 +1253,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
IIdType resourceId;
if (isNotBlank(theMatchUrl)) {
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theRequest);
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theRequest);
if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size());
throw new PreconditionFailedException(msg);
} else if (match.size() == 1) {
Long pid = match.iterator().next();
entity = myEntityManager.find(ResourceTable.class, pid);
ResourcePersistentId pid = match.iterator().next();
entity = myEntityManager.find(ResourceTable.class, pid.getId());
resourceId = entity.getIdDt();
} else {
return create(theResource, null, thePerformIndexing, new Date(), theRequest);
@ -1440,7 +1353,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, true, theRequest);
}
myDeleteConflictService.validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
DeleteConflictService.validateDeleteConflictsEmptyOrThrowException(getContext(), deleteConflicts);
IBaseOperationOutcome oo = createInfoOperationOutcome("Ok to delete");
return new MethodOutcome(new IdDt(theId.getValue()), oo);

View File

@ -88,4 +88,9 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
}
@Nullable
@Override
protected String getResourceName() {
return null;
}
}

View File

@ -0,0 +1,204 @@
package ca.uhn.fhir.jpa.dao;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2019 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.FhirTerser;
import ca.uhn.fhir.util.OperationOutcomeUtil;
import ca.uhn.fhir.util.ResourceReferenceInfo;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.InstantType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;
import static ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.OO_SEVERITY_ERROR;
import static ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.OO_SEVERITY_INFO;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public abstract class BaseStorageDao {
/**
* May be overridden by subclasses to validate resources prior to storage
*
* @param theResource The resource that is about to be stored
*/
protected void preProcessResourceForStorage(IBaseResource theResource) {
String type = getContext().getResourceDefinition(theResource).getName();
if (getResourceName() != null && !getResourceName().equals(type)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessageSanitized(BaseHapiFhirResourceDao.class, "incorrectResourceType", type, getResourceName()));
}
if (theResource.getIdElement().hasIdPart()) {
if (!theResource.getIdElement().isIdPartValid()) {
throw new InvalidRequestException(getContext().getLocalizer().getMessageSanitized(BaseHapiFhirResourceDao.class, "failedToCreateWithInvalidId", theResource.getIdElement().getIdPart()));
}
}
/*
* Replace absolute references with relative ones if configured to do so
*/
if (getConfig().getTreatBaseUrlsAsLocal().isEmpty() == false) {
FhirTerser t = getContext().newTerser();
List<ResourceReferenceInfo> refs = t.getAllResourceReferences(theResource);
for (ResourceReferenceInfo nextRef : refs) {
IIdType refId = nextRef.getResourceReference().getReferenceElement();
if (refId != null && refId.hasBaseUrl()) {
if (getConfig().getTreatBaseUrlsAsLocal().contains(refId.getBaseUrl())) {
IIdType newRefId = refId.toUnqualified();
nextRef.getResourceReference().setReference(newRefId.getValue());
}
}
}
}
if ("Bundle".equals(type)) {
Set<String> allowedBundleTypes = getConfig().getBundleTypesAllowedForStorage();
String bundleType = BundleUtil.getBundleType(getContext(), (IBaseBundle) theResource);
if (isBlank(bundleType) || !allowedBundleTypes.contains(bundleType)) {
String message = "Unable to store a Bundle resource on this server with a Bundle.type value of: " + (isNotBlank(bundleType) ? bundleType : "(missing)");
throw new UnprocessableEntityException(message);
}
}
}
protected DaoMethodOutcome toMethodOutcome(RequestDetails theRequest, @Nonnull final IBasePersistedResource theEntity, @Nonnull IBaseResource theResource) {
DaoMethodOutcome outcome = new DaoMethodOutcome();
IIdType id = null;
if (theResource.getIdElement().getValue() != null) {
id = theResource.getIdElement();
}
if (id == null) {
id = theEntity.getIdDt();
if (getContext().getVersion().getVersion().isRi()) {
id = getContext().getVersion().newIdType().setValue(id.getValue());
}
}
outcome.setId(id);
if (theEntity.isDeleted() == false) {
outcome.setResource(theResource);
}
outcome.setEntity(theEntity);
// Interceptor broadcast: STORAGE_PREACCESS_RESOURCES
if (outcome.getResource() != null) {
SimplePreResourceAccessDetails accessDetails = new SimplePreResourceAccessDetails(outcome.getResource());
HookParams params = new HookParams()
.add(IPreResourceAccessDetails.class, accessDetails)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
if (accessDetails.isDontReturnResourceAtIndex(0)) {
outcome.setResource(null);
}
}
// Interceptor broadcast: STORAGE_PRESHOW_RESOURCES
// Note that this will only fire if someone actually goes to use the
// resource in a response (it's their responsibility to call
// outcome.fireResourceViewCallback())
outcome.registerResourceViewCallback(() -> {
if (outcome.getResource() != null) {
SimplePreResourceShowDetails showDetails = new SimplePreResourceShowDetails(outcome.getResource());
HookParams params = new HookParams()
.add(IPreResourceShowDetails.class, showDetails)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
outcome.setResource(showDetails.getResource(0));
}
});
return outcome;
}
protected void doCallHooks(RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequestDetails, thePointcut, theParams);
}
protected abstract IInterceptorBroadcaster getInterceptorBroadcaster();
public IBaseOperationOutcome createErrorOperationOutcome(String theMessage, String theCode) {
return createOperationOutcome(OO_SEVERITY_ERROR, theMessage, theCode);
}
public IBaseOperationOutcome createInfoOperationOutcome(String theMessage) {
return createOperationOutcome(OO_SEVERITY_INFO, theMessage, "informational");
}
private IBaseOperationOutcome createOperationOutcome(String theSeverity, String theMessage, String theCode) {
IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getContext());
OperationOutcomeUtil.addIssue(getContext(), oo, theSeverity, theMessage, null, theCode);
return oo;
}
@NotNull
protected ResourceGoneException createResourceGoneException(IBasePersistedResource theResourceEntity) {
StringBuilder b = new StringBuilder();
b.append("Resource was deleted at ");
b.append(new InstantType(theResourceEntity.getDeleted()).getValueAsString());
ResourceGoneException retVal = new ResourceGoneException(b.toString());
retVal.setResourceId(theResourceEntity.getIdDt());
return retVal;
}
/**
* Provide the DaoConfig
*/
protected abstract DaoConfig getConfig();
/**
* Returns the resource type for this DAO, or null if this is a system-level DAO
*/
@Nullable
protected abstract String getResourceName();
/**
* Provides the FHIR context
*/
protected abstract FhirContext getContext();
}

View File

@ -20,13 +20,14 @@ package ca.uhn.fhir.jpa.dao;
* #L%
*/
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.MethodOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
public class DaoMethodOutcome extends MethodOutcome {
private ResourceTable myEntity;
private IBasePersistedResource myEntity;
private IBaseResource myPreviousResource;
/**
@ -36,11 +37,11 @@ public class DaoMethodOutcome extends MethodOutcome {
super();
}
public ResourceTable getEntity() {
public IBasePersistedResource getEntity() {
return myEntity;
}
public DaoMethodOutcome setEntity(ResourceTable theEntity) {
public DaoMethodOutcome setEntity(IBasePersistedResource theEntity) {
myEntity = theEntity;
return this;
}

View File

@ -80,8 +80,7 @@ public class DaoRegistry implements ApplicationContextAware, IDaoRegistry {
* @throws InvalidRequestException If the given resource type is not supported
*/
public IFhirResourceDao getResourceDao(String theResourceName) {
init();
IFhirResourceDao retVal = myResourceNameToResourceDao.get(theResourceName);
IFhirResourceDao<IBaseResource> retVal = getResourceDaoOrNull(theResourceName);
if (retVal == null) {
List<String> supportedResourceTypes = myResourceNameToResourceDao
.keySet()
@ -126,12 +125,9 @@ public class DaoRegistry implements ApplicationContextAware, IDaoRegistry {
}
@Nullable
public <T extends IBaseResource> IFhirResourceDao<T> getResourceDaoOrNull(String theResourceType) {
try {
return (IFhirResourceDao<T>) getResourceDao(theResourceType);
} catch (InvalidRequestException e) {
return null;
}
public <T extends IBaseResource> IFhirResourceDao<T> getResourceDaoOrNull(String theResourceName) {
init();
return (IFhirResourceDao<T>) myResourceNameToResourceDao.get(theResourceName);
}
@Override

View File

@ -21,7 +21,7 @@ package ca.uhn.fhir.jpa.dao;
*/
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.registry.BaseSearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
@ -44,7 +44,7 @@ public class DaoSearchParamProvider implements ISearchParamProvider {
}
@Override
public <SP extends IBaseResource> int refreshCache(BaseSearchParamRegistry<SP> theSearchParamRegistry, long theRefreshInterval) {
public int refreshCache(SearchParamRegistryImpl theSearchParamRegistry, long theRefreshInterval) {
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
return txTemplate.execute(t-> theSearchParamRegistry.doRefresh(theRefreshInterval));
}

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.Set;
@ -31,16 +32,10 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
public class FhirResourceDaoBundleDstu2 extends BaseHapiFhirResourceDao<Bundle> {
@Override
protected void preProcessResourceForStorage(Bundle theResource) {
protected void preProcessResourceForStorage(IBaseResource theResource) {
super.preProcessResourceForStorage(theResource);
Set<String> allowedBundleTypes = getConfig().getBundleTypesAllowedForStorage();
if (!allowedBundleTypes.contains(defaultString(theResource.getType()))) {
String message = "Unable to store a Bundle resource on this server with a Bundle.type value of: " + (theResource.getType() != null ? theResource.getType() : "(missing)");
throw new UnprocessableEntityException(message);
}
for (Entry next : theResource.getEntry()) {
for (Entry next : ((Bundle)theResource).getEntry()) {
next.setFullUrl((String) null);
}
}

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.dao.data.ISubscriptionTableDao;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
import ca.uhn.fhir.model.dstu2.resource.Subscription;
@ -73,12 +74,12 @@ public class FhirResourceDaoSubscriptionDstu2 extends BaseHapiFhirResourceDao<Su
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
if (theDeletedTimestampOrNull != null) {
mySubscriptionTableDao.deleteAllForSubscription(theEntity);
mySubscriptionTableDao.deleteAllForSubscription((ResourceTable) theEntity);
}
return retVal;
}

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
@ -68,6 +69,8 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao<ValueS
@Autowired
@Qualifier("myFhirContextDstu2Hl7Org")
private FhirContext myRiCtx;
@Autowired
private FhirContext myFhirContext;
private CachingValidationSupport myValidationSupport;
@ -176,14 +179,15 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao<ValueS
@Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
if (theSystem != null && theSystem.startsWith("http://hl7.org/fhir/")) {
return Collections.singletonList((IIdType) new IdDt(theSystem));
return Collections.singletonList(new IdDt(theSystem));
}
List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
Set<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(ValueSet.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
valueSetIds = new ArrayList<IIdType>();
for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next));
for (ResourcePersistentId next : ids) {
IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "ValueSet", next);
valueSetIds.add(id);
}
return valueSetIds;
}
@ -309,10 +313,11 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao<ValueS
if (theId != null) {
valueSetIds = Collections.singletonList(theId);
} else if (haveIdentifierParam) {
Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_IDENTIFIER, new TokenParam(null, theValueSetIdentifier.getValue())), theRequest);
Set<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(ValueSet.SP_IDENTIFIER, new TokenParam(null, theValueSetIdentifier.getValue())), theRequest);
valueSetIds = new ArrayList<>();
for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next));
for (ResourcePersistentId next : ids) {
IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "ValueSet", next);
valueSetIds.add(id);
}
} else {
if (theCode == null || theCode.isEmpty()) {

View File

@ -22,6 +22,9 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.delete.DeleteConflictList;
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.entity.TagDefinition;
import ca.uhn.fhir.rest.server.servlet.ServletSubRequestDetails;
@ -86,6 +89,8 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
private MatchUrlService myMatchUrlService;
@Autowired
private DaoRegistry myDaoRegistry;
@Autowired
private MatchResourceUrlService myMatchResourceUrlService;
private Bundle batch(final RequestDetails theRequestDetails, Bundle theRequest) {
ourLog.info("Beginning batch with {} resources", theRequest.getEntry().size());
@ -213,9 +218,9 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
List<IIdType> deletedResources = new ArrayList<>();
DeleteConflictList deleteConflicts = new DeleteConflictList();
Map<Entry, ResourceTable> entriesToProcess = new IdentityHashMap<>();
Set<ResourceTable> nonUpdatedEntities = new HashSet<ResourceTable>();
Set<ResourceTable> updatedEntities = new HashSet<>();
Map<Entry, IBasePersistedResource> entriesToProcess = new IdentityHashMap<>();
Set<IBasePersistedResource> nonUpdatedEntities = new HashSet<>();
Set<IBasePersistedResource> updatedEntities = new HashSet<>();
/*
* Handle: GET/PUT/POST
@ -293,7 +298,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
}
for (Map.Entry<Entry, ResourceTable> nextEntry : entriesToProcess.entrySet()) {
for (Map.Entry<Entry, IBasePersistedResource> nextEntry : entriesToProcess.entrySet()) {
nextEntry.getKey().getResponse().setLocation(nextEntry.getValue().getIdDt().toUnqualified().getValue());
nextEntry.getKey().getResponse().setEtag(nextEntry.getValue().getIdDt().getVersionIdPart());
}
@ -301,13 +306,13 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
long delay = System.currentTimeMillis() - start;
int numEntries = theRequest.getEntry().size();
long delayPer = delay / numEntries;
ourLog.info("{} completed in {}ms ({} entries at {}ms per entry)", new Object[] {theActionName, delay, numEntries, delayPer});
ourLog.info("{} completed in {}ms ({} entries at {}ms per entry)", theActionName, delay, numEntries, delayPer);
response.setType(BundleTypeEnum.TRANSACTION_RESPONSE);
return response;
}
private void handleTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date theUpdateTime, Set<IdDt> theAllIds, Map<IdDt, IdDt> theIdSubstitutions, Map<IdDt, DaoMethodOutcome> theIdToPersistedOutcome, Bundle theResponse, IdentityHashMap<Entry, Integer> theOriginalRequestOrder, List<IIdType> theDeletedResources, DeleteConflictList theDeleteConflicts, Map<Entry, ResourceTable> theEntriesToProcess, Set<ResourceTable> theNonUpdatedEntities, Set<ResourceTable> theUpdatedEntities) {
private void handleTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date theUpdateTime, Set<IdDt> theAllIds, Map<IdDt, IdDt> theIdSubstitutions, Map<IdDt, DaoMethodOutcome> theIdToPersistedOutcome, Bundle theResponse, IdentityHashMap<Entry, Integer> theOriginalRequestOrder, List<IIdType> theDeletedResources, DeleteConflictList theDeleteConflicts, Map<Entry, IBasePersistedResource> theEntriesToProcess, Set<IBasePersistedResource> theNonUpdatedEntities, Set<IBasePersistedResource> theUpdatedEntities) {
/*
* Loop through the request and process any entries of type
* PUT, POST or DELETE
@ -331,7 +336,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
}
}
if (nextResourceId.hasIdPart() && nextResourceId.getIdPart().matches("[a-zA-Z]+\\:.*") && !isPlaceholder(nextResourceId)) {
if (nextResourceId.hasIdPart() && nextResourceId.getIdPart().matches("[a-zA-Z]+:.*") && !isPlaceholder(nextResourceId)) {
throw new InvalidRequestException("Invalid placeholder ID found: " + nextResourceId.getIdPart() + " - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'");
}
@ -444,7 +449,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
*/
theDeleteConflicts.removeIf(next -> theDeletedResources.contains(next.getTargetId().toVersionless()));
myDeleteConflictService.validateDeleteConflictsEmptyOrThrowException(theDeleteConflicts);
DeleteConflictService.validateDeleteConflictsEmptyOrThrowException(getContext(), theDeleteConflicts);
/*
* Perform ID substitutions and then index each resource we have saved
@ -508,8 +513,8 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
if (nextEntry.getRequest().getMethodElement().getValueAsEnum() == HTTPVerbEnum.POST) {
String matchUrl = nextEntry.getRequest().getIfNoneExist();
if (isNotBlank(matchUrl)) {
IFhirResourceDao<?> resourceDao = getDao(nextEntry.getResource().getClass());
Set<Long> val = resourceDao.processMatchUrl(matchUrl, theRequestDetails);
Class<? extends IBaseResource> resType = nextEntry.getResource().getClass();
Set<ResourcePersistentId> val = myMatchResourceUrlService.processMatchUrl(matchUrl, resType, theRequestDetails);
if (val.size() > 1) {
throw new InvalidRequestException(
"Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
@ -623,11 +628,11 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
}
private Bundle transaction(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName) {
super.markRequestAsProcessingSubRequest(theRequestDetails);
markRequestAsProcessingSubRequest(theRequestDetails);
try {
return doTransaction(theRequestDetails, theRequest, theActionName);
} finally {
super.clearRequestAsProcessingSubRequest(theRequestDetails);
clearRequestAsProcessingSubRequest(theRequestDetails);
}
}
@ -655,15 +660,13 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
private static boolean isPlaceholder(IdDt theId) {
if (theId.getValue() != null) {
if (theId.getValue().startsWith("urn:oid:") || theId.getValue().startsWith("urn:uuid:")) {
return true;
}
return theId.getValue().startsWith("urn:oid:") || theId.getValue().startsWith("urn:uuid:");
}
return false;
}
private static String toStatusString(int theStatusCode) {
return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode));
return theStatusCode + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode));
}
@Override

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterType;
@ -116,10 +117,10 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
}
}
private List<Long> doSearch(String theResourceName, SearchParameterMap theParams, Long theReferencingPid) {
private List<ResourcePersistentId> doSearch(String theResourceName, SearchParameterMap theParams, ResourcePersistentId theReferencingPid) {
FullTextEntityManager em = org.hibernate.search.jpa.Search.getFullTextEntityManager(myEntityManager);
List<Long> pids = null;
List<ResourcePersistentId> pids = null;
/*
* Handle textual params
@ -202,12 +203,12 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
// execute search
List<?> result = jpaQuery.getResultList();
ArrayList<Long> retVal = new ArrayList<>();
ArrayList<ResourcePersistentId> retVal = new ArrayList<>();
for (Object object : result) {
Object[] nextArray = (Object[]) object;
Long next = (Long) nextArray[0];
if (next != null) {
retVal.add(next);
retVal.add(new ResourcePersistentId(next));
}
}
@ -215,9 +216,9 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
}
@Override
public List<Long> everything(String theResourceName, SearchParameterMap theParams, RequestDetails theRequest) {
public List<ResourcePersistentId> everything(String theResourceName, SearchParameterMap theParams, RequestDetails theRequest) {
Long pid = null;
ResourcePersistentId pid = null;
if (theParams.get(IAnyResource.SP_RES_ID) != null) {
String idParamValue;
IQueryParameterType idParam = theParams.get(IAnyResource.SP_RES_ID).get(0).get(0);
@ -231,8 +232,8 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
pid = myIdHelperService.translateForcedIdToPid(theResourceName, idParamValue, theRequest);
}
Long referencingPid = pid;
List<Long> retVal = doSearch(null, theParams, referencingPid);
ResourcePersistentId referencingPid = pid;
List<ResourcePersistentId> retVal = doSearch(null, theParams, referencingPid);
if (referencingPid != null) {
retVal.add(referencingPid);
}
@ -264,7 +265,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
@Transactional()
@Override
public List<Long> search(String theResourceName, SearchParameterMap theParams) {
public List<ResourcePersistentId> search(String theResourceName, SearchParameterMap theParams) {
return doSearch(theResourceName, theParams, null);
}
@ -281,7 +282,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
if (contextParts.length != 3 || "Patient".equals(contextParts[0]) == false || "$everything".equals(contextParts[2]) == false) {
throw new InvalidRequestException("Invalid context: " + theContext);
}
Long pid = myIdHelperService.translateForcedIdToPid(contextParts[0], contextParts[1], theRequest);
ResourcePersistentId pid = myIdHelperService.translateForcedIdToPid(contextParts[0], contextParts[1], theRequest);
FullTextEntityManager em = org.hibernate.search.jpa.Search.getFullTextEntityManager(myEntityManager);

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.delete.DeleteConflictList;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
@ -154,8 +155,6 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
DaoMethodOutcome patch(IIdType theId, String theConditionalUrl, PatchTypeEnum thePatchType, String thePatchBody, RequestDetails theRequestDetails);
Set<Long> processMatchUrl(String theMatchUrl, RequestDetails theRequest);
/**
* Read a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
* therefore can not fire any interceptors. Use only for internal system calls
@ -165,7 +164,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
/**
* Read a resource by its internal PID
*/
IBaseResource readByPid(Long thePid);
IBaseResource readByPid(ResourcePersistentId thePid);
/**
* @param theId
@ -205,7 +204,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
@Transactional(propagation = Propagation.SUPPORTS)
IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails, HttpServletResponse theServletResponse);
Set<Long> searchForIds(SearchParameterMap theParams, RequestDetails theRequest);
Set<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest);
/**
* Takes a map of incoming raw search parameters and translates/parses them into

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.dao;
import java.util.List;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.RequestDetails;
@ -30,9 +31,9 @@ public interface IFulltextSearchSvc {
List<Suggestion> suggestKeywords(String theContext, String theSearchParam, String theText, RequestDetails theRequest);
List<Long> search(String theResourceName, SearchParameterMap theParams);
List<ResourcePersistentId> search(String theResourceName, SearchParameterMap theParams);
List<Long> everything(String theResourceName, SearchParameterMap theParams, RequestDetails theRequest);
List<ResourcePersistentId> everything(String theResourceName, SearchParameterMap theParams, RequestDetails theRequest);
boolean isDisabled();

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.dao;
* #L%
*/
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -29,10 +30,10 @@ import java.util.Date;
public interface IJpaDao<T extends IBaseResource> {
@SuppressWarnings("unchecked")
ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable
IBasePersistedResource updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource
theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry);
ResourceTable updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion,
ResourceTable theEntity, IIdType theResourceId, IBaseResource theOldResource);
IBasePersistedResource updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion,
IBasePersistedResource theEntity, IIdType theResourceId, IBaseResource theOldResource);
}

View File

@ -20,10 +20,12 @@ package ca.uhn.fhir.jpa.dao;
* #L%
*/
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import java.io.Closeable;
import java.util.Iterator;
public interface IResultIterator extends Iterator<Long>, Closeable {
public interface IResultIterator extends Iterator<ResourcePersistentId>, Closeable {
int getSkippedCount();

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.dao;
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.Include;
@ -43,9 +44,9 @@ public interface ISearchBuilder {
Iterator<Long> createCountQuery(SearchParameterMap theParams, String theSearchUuid, RequestDetails theRequest);
void loadResourcesByPid(Collection<Long> thePids, Collection<Long> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation, RequestDetails theDetails);
void loadResourcesByPid(Collection<ResourcePersistentId> thePids, Collection<ResourcePersistentId> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation, RequestDetails theDetails);
Set<Long> loadIncludes(FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode,
Set<ResourcePersistentId> loadIncludes(FhirContext theContext, EntityManager theEntityManager, Collection<ResourcePersistentId> theMatches, Set<Include> theRevIncludes, boolean theReverseMode,
DateRangeParam theLastUpdated, String theSearchIdOrDescription, RequestDetails theRequest);
/**
@ -55,6 +56,6 @@ public interface ISearchBuilder {
void setType(Class<? extends IBaseResource> theResourceType, String theResourceName);
void setPreviouslyAddedResourcePids(List<Long> thePreviouslyAddedResourcePids);
void setPreviouslyAddedResourcePids(List<ResourcePersistentId> thePreviouslyAddedResourcePids);
}

View File

@ -25,8 +25,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -37,7 +36,6 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.StopWatch;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -54,7 +52,7 @@ public class MatchResourceUrlService {
@Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster;
public <R extends IBaseResource> Set<Long> processMatchUrl(String theMatchUrl, Class<R> theResourceType, RequestDetails theRequest) {
public <R extends IBaseResource> Set<ResourcePersistentId> processMatchUrl(String theMatchUrl, Class<R> theResourceType, RequestDetails theRequest) {
StopWatch sw = new StopWatch();
RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(theResourceType);
@ -71,7 +69,7 @@ public class MatchResourceUrlService {
throw new InternalErrorException("No DAO for resource type: " + theResourceType.getName());
}
Set<Long> retVal = dao.searchForIds(paramMap, theRequest);
Set<ResourcePersistentId> retVal = dao.searchForIds(paramMap, theRequest);
// Interceptor broadcast: JPA_PERFTRACE_INFO
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {

View File

@ -20,7 +20,15 @@ package ca.uhn.fhir.jpa.dao;
* #L%
*/
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
@ -30,6 +38,7 @@ import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.entity.ResourceSearchView;
import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
@ -40,10 +49,20 @@ import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.util.SourceParam;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.jpa.util.*;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.util.BaseIterator;
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
import ca.uhn.fhir.jpa.util.SqlQueryList;
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
import ca.uhn.fhir.model.base.composite.BaseQuantityDt;
@ -51,7 +70,11 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.*;
@ -96,7 +119,11 @@ import java.util.Map.Entry;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
/**
* The SearchBuilder is responsible for actually forming the SQL query that handles
@ -106,14 +133,14 @@ import static org.apache.commons.lang3.StringUtils.*;
@Scope("prototype")
public class SearchBuilder implements ISearchBuilder {
private static final List<Long> EMPTY_LONG_LIST = Collections.unmodifiableList(new ArrayList<>());
private static final List<ResourcePersistentId> EMPTY_LONG_LIST = Collections.unmodifiableList(new ArrayList<>());
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchBuilder.class);
/**
* See loadResourcesByPid
* for an explanation of why we use the constant 800
*/
private static final int MAXIMUM_PAGE_SIZE = 800;
private static Long NO_MORE = -1L;
private static ResourcePersistentId NO_MORE = new ResourcePersistentId(-1L);
private final boolean myDontUseHashesForSearch;
private final DaoConfig myDaoConfig;
@Autowired
@ -138,7 +165,7 @@ public class SearchBuilder implements ISearchBuilder {
private ITermReadSvc myTerminologySvc;
@Autowired
private MatchUrlService myMatchUrlService;
private List<Long> myAlsoIncludePids;
private List<ResourcePersistentId> myAlsoIncludePids;
private CriteriaBuilder myBuilder;
private BaseHapiFhirDao<?> myCallingDao;
private Map<JoinKey, Join<?, ?>> myIndexJoins = Maps.newHashMap();
@ -151,7 +178,7 @@ public class SearchBuilder implements ISearchBuilder {
private String mySearchUuid;
private int myFetchSize;
private Integer myMaxResultsToFetch;
private Set<Long> myPidSet;
private Set<ResourcePersistentId> myPidSet;
private boolean myHaveIndexJoins = false;
/**
@ -542,11 +569,11 @@ public class SearchBuilder implements ISearchBuilder {
List<Predicate> codePredicates = new ArrayList<>();
// Resources by ID
List<Long> targetPids = myIdHelperService.translateForcedIdToPids(targetIds, theRequest);
List<ResourcePersistentId> targetPids = myIdHelperService.translateForcedIdToPids(targetIds, theRequest);
if (!targetPids.isEmpty()) {
ourLog.debug("Searching for resource link with target PIDs: {}", targetPids);
Predicate pathPredicate = createResourceLinkPathPredicate(theResourceName, theParamName, join);
Predicate pidPredicate = join.get("myTargetResourcePid").in(targetPids);
Predicate pidPredicate = join.get("myTargetResourcePid").in(ResourcePersistentId.toLongList(targetPids));
codePredicates.add(myBuilder.and(pathPredicate, pidPredicate));
}
@ -573,7 +600,6 @@ public class SearchBuilder implements ISearchBuilder {
private Predicate addPredicateReferenceWithChain(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList, Join<ResourceTable, ResourceLink> theJoin, List<Predicate> theCodePredicates, ReferenceParam theRef, RequestDetails theRequest) {
final List<Class<? extends IBaseResource>> resourceTypes;
String resourceId;
if (!theRef.hasResourceType()) {
RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName);
@ -631,14 +657,11 @@ public class SearchBuilder implements ISearchBuilder {
}
}
resourceId = theRef.getValue();
} else {
try {
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theRef.getResourceType());
resourceTypes = new ArrayList<>(1);
resourceTypes.add(resDef.getImplementingClass());
resourceId = theRef.getIdPart();
} catch (DataFormatException e) {
throw new InvalidRequestException("Invalid resource type: " + theRef.getResourceType());
}
@ -712,6 +735,42 @@ public class SearchBuilder implements ISearchBuilder {
return predicate;
}
private void addPredicateSource(List<List<IQueryParameterType>> theAndOrParams, RequestDetails theRequest) {
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateSource(nextAnd, SearchFilterParser.CompareOperation.eq, theRequest);
}
}
private Predicate addPredicateSource(List<? extends IQueryParameterType> theList, SearchFilterParser.CompareOperation theOperation, RequestDetails theRequest) {
if (myDaoConfig.getStoreMetaSourceInformation() == DaoConfig.StoreMetaSourceInformationEnum.NONE) {
String msg = myContext.getLocalizer().getMessage(SearchBuilder.class, "sourceParamDisabled");
throw new InvalidRequestException(msg);
}
Join<ResourceTable, ResourceHistoryProvenanceEntity> join = myResourceTableRoot.join("myProvenance", JoinType.LEFT);
List<Predicate> codePredicates = new ArrayList<>();
for (IQueryParameterType nextParameter : theList) {
SourceParam sourceParameter = new SourceParam(nextParameter.getValueAsQueryToken(myContext));
String sourceUri = sourceParameter.getSourceUri();
String requestId = sourceParameter.getRequestId();
Predicate sourceUriPredicate = myBuilder.equal(join.get("mySourceUri"), sourceUri);
Predicate requestIdPredicate = myBuilder.equal(join.get("myRequestId"), requestId);
if (isNotBlank(sourceUri) && isNotBlank(requestId)) {
codePredicates.add(myBuilder.and(sourceUriPredicate, requestIdPredicate));
} else if (isNotBlank(sourceUri)) {
codePredicates.add(sourceUriPredicate);
} else if (isNotBlank(requestId)) {
codePredicates.add(requestIdPredicate);
}
}
Predicate retVal = myBuilder.or(toArray(codePredicates));
myPredicates.add(retVal);
return retVal;
}
private Subquery<Long> createLinkSubquery(boolean theFoundChainMatch, String theChain, String theSubResourceName, List<IQueryParameterType> theOrValues, RequestDetails theRequest) {
Subquery<Long> subQ = myResourceTableQuery.subquery(Long.class);
Root<ResourceTable> subQfrom = subQ.from(ResourceTable.class);
@ -772,8 +831,8 @@ public class SearchBuilder implements ISearchBuilder {
return chainValue;
}
private Predicate addPredicateResourceId(String theResourceName, List<List<IQueryParameterType>> theValues, RequestDetails theRequest) {
return addPredicateResourceId(theValues, theResourceName, null, theRequest);
private void addPredicateResourceId(String theResourceName, List<List<IQueryParameterType>> theValues, RequestDetails theRequest) {
addPredicateResourceId(theValues, theResourceName, null, theRequest);
}
private Predicate addPredicateResourceId(List<List<IQueryParameterType>> theValues, String theResourceName, SearchFilterParser.CompareOperation theOperation, RequestDetails theRequest) {
@ -792,10 +851,10 @@ public class SearchBuilder implements ISearchBuilder {
private Predicate createPredicateResourceId(Root<ResourceTable> theRoot, String theResourceName, List<List<IQueryParameterType>> theValues, SearchFilterParser.CompareOperation theOperation, RequestDetails theRequest) {
Predicate nextPredicate = null;
Set<Long> allOrPids = null;
Set<ResourcePersistentId> allOrPids = null;
for (List<? extends IQueryParameterType> nextValue : theValues) {
Set<Long> orPids = new HashSet<>();
Set<ResourcePersistentId> orPids = new HashSet<>();
boolean haveValue = false;
for (IQueryParameterType next : nextValue) {
String value = next.getValueAsQueryToken(myContext);
@ -807,7 +866,7 @@ public class SearchBuilder implements ISearchBuilder {
if (isNotBlank(value)) {
haveValue = true;
try {
Long pid = myIdHelperService.translateForcedIdToPid(theResourceName, valueAsId.getIdPart(), theRequest);
ResourcePersistentId pid = myIdHelperService.translateForcedIdToPid(theResourceName, valueAsId.getIdPart(), theRequest);
orPids.add(pid);
} catch (ResourceNotFoundException e) {
// This is not an error in a search, it just results in no matchesFhirResourceDaoR4InterceptorTest
@ -838,12 +897,12 @@ public class SearchBuilder implements ISearchBuilder {
switch (operation) {
default:
case eq:
codePredicates.add(theRoot.get("myId").as(Long.class).in(allOrPids));
codePredicates.add(theRoot.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(allOrPids)));
codePredicates.add(myBuilder.equal(myResourceTableRoot.get("myResourceType"), theResourceName));
nextPredicate = myBuilder.and(toArray(codePredicates));
break;
case ne:
codePredicates.add(theRoot.get("myId").as(Long.class).in(allOrPids).not());
codePredicates.add(theRoot.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(allOrPids)).not());
codePredicates.add(myBuilder.equal(myResourceTableRoot.get("myResourceType"), theResourceName));
nextPredicate = myBuilder.and(toArray(codePredicates));
break;
@ -855,41 +914,10 @@ public class SearchBuilder implements ISearchBuilder {
}
private Predicate addPredicateSource(List<? extends IQueryParameterType> theList, SearchFilterParser.CompareOperation theOperation, RequestDetails theRequest) {
if (myDaoConfig.getStoreMetaSourceInformation() == DaoConfig.StoreMetaSourceInformationEnum.NONE) {
String msg = myContext.getLocalizer().getMessage(SearchBuilder.class, "sourceParamDisabled");
throw new InvalidRequestException(msg);
}
Join<ResourceTable, ResourceHistoryProvenanceEntity> join = myResourceTableRoot.join("myProvenance", JoinType.LEFT);
List<Predicate> codePredicates = new ArrayList<>();
for (IQueryParameterType nextParameter : theList) {
SourceParam sourceParameter = new SourceParam(nextParameter.getValueAsQueryToken(myContext));
String sourceUri = sourceParameter.getSourceUri();
String requestId = sourceParameter.getRequestId();
Predicate sourceUriPredicate = myBuilder.equal(join.get("mySourceUri"), sourceUri);
Predicate requestIdPredicate = myBuilder.equal(join.get("myRequestId"), requestId);
if (isNotBlank(sourceUri) && isNotBlank(requestId)) {
codePredicates.add(myBuilder.and(sourceUriPredicate, requestIdPredicate));
} else if (isNotBlank(sourceUri)) {
codePredicates.add(sourceUriPredicate);
} else if (isNotBlank(requestId)) {
codePredicates.add(requestIdPredicate);
}
}
Predicate retVal = myBuilder.or(toArray(codePredicates));
myPredicates.add(retVal);
return retVal;
}
private Predicate addPredicateString(String theResourceName,
private void addPredicateString(String theResourceName,
String theParamName,
List<? extends IQueryParameterType> theList) {
return addPredicateString(theResourceName,
addPredicateString(theResourceName,
theParamName,
theList,
SearchFilterParser.CompareOperation.sw);
@ -2015,7 +2043,7 @@ public class SearchBuilder implements ISearchBuilder {
* @param thePidSet May be null
*/
@Override
public void setPreviouslyAddedResourcePids(@Nullable List<Long> thePidSet) {
public void setPreviouslyAddedResourcePids(@Nullable List<ResourcePersistentId> thePidSet) {
myPidSet = new HashSet<>(thePidSet);
}
@ -2081,12 +2109,12 @@ public class SearchBuilder implements ISearchBuilder {
if (myParams.get(IAnyResource.SP_RES_ID) != null) {
StringParam idParm = (StringParam) myParams.get(IAnyResource.SP_RES_ID).get(0).get(0);
Long pid = myIdHelperService.translateForcedIdToPid(myResourceName, idParm.getValue(), theRequest);
ResourcePersistentId pid = myIdHelperService.translateForcedIdToPid(myResourceName, idParm.getValue(), theRequest);
if (myAlsoIncludePids == null) {
myAlsoIncludePids = new ArrayList<>(1);
}
myAlsoIncludePids.add(pid);
myPredicates.add(myBuilder.equal(join.get("myTargetResourcePid").as(Long.class), pid));
myPredicates.add(myBuilder.equal(join.get("myTargetResourcePid").as(Long.class), pid.getIdAsLong()));
} else {
Predicate targetTypePredicate = myBuilder.equal(join.get("myTargetResourceType").as(String.class), myResourceName);
Predicate sourceTypePredicate = myBuilder.equal(myResourceTableRoot.get("myResourceType").as(String.class), myResourceName);
@ -2110,7 +2138,7 @@ public class SearchBuilder implements ISearchBuilder {
}
}
List<Long> pids;
List<ResourcePersistentId> pids;
if (myParams.getEverythingMode() != null) {
pids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
} else {
@ -2118,10 +2146,10 @@ public class SearchBuilder implements ISearchBuilder {
}
if (pids.isEmpty()) {
// Will never match
pids = Collections.singletonList(-1L);
pids = Collections.singletonList(new ResourcePersistentId(-1L));
}
myPredicates.add(myResourceTableRoot.get("myId").as(Long.class).in(pids));
myPredicates.add(myResourceTableRoot.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(pids)));
}
/*
@ -2315,21 +2343,21 @@ public class SearchBuilder implements ISearchBuilder {
return retVal;
}
private void doLoadPids(Collection<Long> thePids, Collection<Long> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation,
Map<Long, Integer> thePosition, RequestDetails theRequest) {
private void doLoadPids(Collection<ResourcePersistentId> thePids, Collection<ResourcePersistentId> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation,
Map<ResourcePersistentId, Integer> thePosition, RequestDetails theRequest) {
// -- get the resource from the searchView
Collection<ResourceSearchView> resourceSearchViewList = myResourceSearchViewDao.findByResourceIds(thePids);
Collection<ResourceSearchView> resourceSearchViewList = myResourceSearchViewDao.findByResourceIds(ResourcePersistentId.toLongList(thePids));
//-- preload all tags with tag definition if any
Map<Long, Collection<ResourceTag>> tagMap = getResourceTagMap(resourceSearchViewList);
Map<ResourcePersistentId, Collection<ResourceTag>> tagMap = getResourceTagMap(resourceSearchViewList);
Long resourceId;
ResourcePersistentId resourceId;
for (ResourceSearchView next : resourceSearchViewList) {
Class<? extends IBaseResource> resourceType = myContext.getResourceDefinition(next.getResourceType()).getImplementingClass();
resourceId = next.getId();
resourceId = new ResourcePersistentId(next.getId());
IBaseResource resource = myCallingDao.toResource(resourceType, next, tagMap.get(resourceId), theForHistoryOperation);
if (resource == null) {
@ -2360,7 +2388,7 @@ public class SearchBuilder implements ISearchBuilder {
}
}
private Map<Long, Collection<ResourceTag>> getResourceTagMap(Collection<ResourceSearchView> theResourceSearchViewList) {
private Map<ResourcePersistentId, Collection<ResourceTag>> getResourceTagMap(Collection<ResourceSearchView> theResourceSearchViewList) {
List<Long> idList = new ArrayList<>(theResourceSearchViewList.size());
@ -2370,7 +2398,7 @@ public class SearchBuilder implements ISearchBuilder {
idList.add(resource.getId());
}
Map<Long, Collection<ResourceTag>> tagMap = new HashMap<>();
Map<ResourcePersistentId, Collection<ResourceTag>> tagMap = new HashMap<>();
//-- no tags
if (idList.size() == 0)
@ -2380,11 +2408,11 @@ public class SearchBuilder implements ISearchBuilder {
Collection<ResourceTag> tagList = myResourceTagDao.findByResourceIds(idList);
//-- build the map, key = resourceId, value = list of ResourceTag
Long resourceId;
ResourcePersistentId resourceId;
Collection<ResourceTag> tagCol;
for (ResourceTag tag : tagList) {
resourceId = tag.getResourceId();
resourceId = new ResourcePersistentId(tag.getResourceId());
tagCol = tagMap.get(resourceId);
if (tagCol == null) {
tagCol = new ArrayList<>();
@ -2399,7 +2427,7 @@ public class SearchBuilder implements ISearchBuilder {
}
@Override
public void loadResourcesByPid(Collection<Long> thePids, Collection<Long> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation, RequestDetails theDetails) {
public void loadResourcesByPid(Collection<ResourcePersistentId> thePids, Collection<ResourcePersistentId> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation, RequestDetails theDetails) {
if (thePids.isEmpty()) {
ourLog.debug("The include pids are empty");
// return;
@ -2409,8 +2437,8 @@ public class SearchBuilder implements ISearchBuilder {
// when running asserts
assert new HashSet<>(thePids).size() == thePids.size() : "PID list contains duplicates: " + thePids;
Map<Long, Integer> position = new HashMap<>();
for (Long next : thePids) {
Map<ResourcePersistentId, Integer> position = new HashMap<>();
for (ResourcePersistentId next : thePids) {
position.put(next, theResourceListToPopulate.size());
theResourceListToPopulate.add(null);
}
@ -2421,11 +2449,11 @@ public class SearchBuilder implements ISearchBuilder {
* if it's lots of IDs. I suppose maybe we should be doing this as a join anyhow
* but this should work too. Sigh.
*/
List<Long> pids = new ArrayList<>(thePids);
List<ResourcePersistentId> pids = new ArrayList<>(thePids);
for (int i = 0; i < pids.size(); i += MAXIMUM_PAGE_SIZE) {
int to = i + MAXIMUM_PAGE_SIZE;
to = Math.min(to, pids.size());
List<Long> pidsSubList = pids.subList(i, to);
List<ResourcePersistentId> pidsSubList = pids.subList(i, to);
doLoadPids(pidsSubList, theIncludedPids, theResourceListToPopulate, theForHistoryOperation, position, theDetails);
}
@ -2436,7 +2464,7 @@ public class SearchBuilder implements ISearchBuilder {
* so it can't be Collections.emptySet() or some such thing
*/
@Override
public HashSet<Long> loadIncludes(FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes,
public HashSet<ResourcePersistentId> loadIncludes(FhirContext theContext, EntityManager theEntityManager, Collection<ResourcePersistentId> theMatches, Set<Include> theRevIncludes,
boolean theReverseMode, DateRangeParam theLastUpdated, String theSearchIdOrDescription, RequestDetails theRequest) {
if (theMatches.size() == 0) {
return new HashSet<>();
@ -2446,9 +2474,9 @@ public class SearchBuilder implements ISearchBuilder {
}
String searchFieldName = theReverseMode ? "myTargetResourcePid" : "mySourceResourcePid";
Collection<Long> nextRoundMatches = theMatches;
HashSet<Long> allAdded = new HashSet<>();
HashSet<Long> original = new HashSet<>(theMatches);
Collection<ResourcePersistentId> nextRoundMatches = theMatches;
HashSet<ResourcePersistentId> allAdded = new HashSet<>();
HashSet<ResourcePersistentId> original = new HashSet<>(theMatches);
ArrayList<Include> includes = new ArrayList<>(theRevIncludes);
int roundCounts = 0;
@ -2458,7 +2486,7 @@ public class SearchBuilder implements ISearchBuilder {
do {
roundCounts++;
HashSet<Long> pidsToInclude = new HashSet<>();
HashSet<ResourcePersistentId> pidsToInclude = new HashSet<>();
for (Iterator<Include> iter = includes.iterator(); iter.hasNext(); ) {
Include nextInclude = iter.next();
@ -2470,16 +2498,16 @@ public class SearchBuilder implements ISearchBuilder {
if (matchAll) {
String sql;
sql = "SELECT r FROM ResourceLink r WHERE r." + searchFieldName + " IN (:target_pids) ";
List<Collection<Long>> partitions = partition(nextRoundMatches, MAXIMUM_PAGE_SIZE);
for (Collection<Long> nextPartition : partitions) {
List<Collection<ResourcePersistentId>> partitions = partition(nextRoundMatches, MAXIMUM_PAGE_SIZE);
for (Collection<ResourcePersistentId> nextPartition : partitions) {
TypedQuery<ResourceLink> q = theEntityManager.createQuery(sql, ResourceLink.class);
q.setParameter("target_pids", nextPartition);
q.setParameter("target_pids", ResourcePersistentId.toLongList(nextPartition));
List<ResourceLink> results = q.getResultList();
for (ResourceLink resourceLink : results) {
if (theReverseMode) {
pidsToInclude.add(resourceLink.getSourceResourcePid());
pidsToInclude.add(new ResourcePersistentId(resourceLink.getSourceResourcePid()));
} else {
pidsToInclude.add(resourceLink.getTargetResourcePid());
pidsToInclude.add(new ResourcePersistentId(resourceLink.getTargetResourcePid()));
}
}
}
@ -2523,11 +2551,11 @@ public class SearchBuilder implements ISearchBuilder {
sql = "SELECT r FROM ResourceLink r WHERE r.mySourcePath = :src_path AND r." + searchFieldName + " IN (:target_pids)";
}
List<Collection<Long>> partitions = partition(nextRoundMatches, MAXIMUM_PAGE_SIZE);
for (Collection<Long> nextPartition : partitions) {
List<Collection<ResourcePersistentId>> partitions = partition(nextRoundMatches, MAXIMUM_PAGE_SIZE);
for (Collection<ResourcePersistentId> nextPartition : partitions) {
TypedQuery<ResourceLink> q = theEntityManager.createQuery(sql, ResourceLink.class);
q.setParameter("src_path", nextPath);
q.setParameter("target_pids", nextPartition);
q.setParameter("target_pids", ResourcePersistentId.toLongList(nextPartition));
if (targetResourceType != null) {
q.setParameter("target_resource_type", targetResourceType);
} else if (haveTargetTypesDefinedByParam) {
@ -2538,12 +2566,12 @@ public class SearchBuilder implements ISearchBuilder {
if (theReverseMode) {
Long pid = resourceLink.getSourceResourcePid();
if (pid != null) {
pidsToInclude.add(pid);
pidsToInclude.add(new ResourcePersistentId(pid));
}
} else {
Long pid = resourceLink.getTargetResourcePid();
if (pid != null) {
pidsToInclude.add(pid);
pidsToInclude.add(new ResourcePersistentId(pid));
}
}
}
@ -2557,7 +2585,7 @@ public class SearchBuilder implements ISearchBuilder {
pidsToInclude = new HashSet<>(filterResourceIdsByLastUpdated(theEntityManager, theLastUpdated, pidsToInclude));
}
}
for (Long next : pidsToInclude) {
for (ResourcePersistentId next : pidsToInclude) {
if (original.contains(next) == false && allAdded.contains(next) == false) {
theMatches.add(next);
}
@ -2573,7 +2601,7 @@ public class SearchBuilder implements ISearchBuilder {
// This can be used to remove results from the search result details before
// the user has a chance to know that they were in the results
if (allAdded.size() > 0) {
List<Long> includedPidList = new ArrayList<>(allAdded);
List<ResourcePersistentId> includedPidList = new ArrayList<>(allAdded);
JpaPreResourceAccessDetails accessDetails = new JpaPreResourceAccessDetails(includedPidList, () -> this);
HookParams params = new HookParams()
.add(IPreResourceAccessDetails.class, accessDetails)
@ -2583,7 +2611,7 @@ public class SearchBuilder implements ISearchBuilder {
for (int i = includedPidList.size() - 1; i >= 0; i--) {
if (accessDetails.isDontReturnResourceAtIndex(i)) {
Long value = includedPidList.remove(i);
ResourcePersistentId value = includedPidList.remove(i);
if (value != null) {
theMatches.remove(value);
}
@ -2596,14 +2624,14 @@ public class SearchBuilder implements ISearchBuilder {
return allAdded;
}
private List<Collection<Long>> partition(Collection<Long> theNextRoundMatches, int theMaxLoad) {
private List<Collection<ResourcePersistentId>> partition(Collection<ResourcePersistentId> theNextRoundMatches, int theMaxLoad) {
if (theNextRoundMatches.size() <= theMaxLoad) {
return Collections.singletonList(theNextRoundMatches);
} else {
List<Collection<Long>> retVal = new ArrayList<>();
Collection<Long> current = null;
for (Long next : theNextRoundMatches) {
List<Collection<ResourcePersistentId>> retVal = new ArrayList<>();
Collection<ResourcePersistentId> current = null;
for (ResourcePersistentId next : theNextRoundMatches) {
if (current == null) {
current = new ArrayList<>(theMaxLoad);
retVal.add(current);
@ -2834,28 +2862,28 @@ public class SearchBuilder implements ISearchBuilder {
return null;
}
private Predicate processFilter(SearchFilterParser.Filter filter,
private Predicate processFilter(SearchFilterParser.Filter theFilter,
String theResourceName, RequestDetails theRequest) {
if (filter instanceof SearchFilterParser.FilterParameter) {
return processFilterParameter((SearchFilterParser.FilterParameter) filter,
if (theFilter instanceof SearchFilterParser.FilterParameter) {
return processFilterParameter((SearchFilterParser.FilterParameter) theFilter,
theResourceName, theRequest);
} else if (filter instanceof SearchFilterParser.FilterLogical) {
} else if (theFilter instanceof SearchFilterParser.FilterLogical) {
// Left side
Predicate leftPredicate = processFilter(((SearchFilterParser.FilterLogical) filter).getFilter1(),
Predicate xPredicate = processFilter(((SearchFilterParser.FilterLogical) theFilter).getFilter1(),
theResourceName, theRequest);
// Right side
Predicate rightPredicate = processFilter(((SearchFilterParser.FilterLogical) filter).getFilter2(),
Predicate yPredicate = processFilter(((SearchFilterParser.FilterLogical) theFilter).getFilter2(),
theResourceName, theRequest);
if (((SearchFilterParser.FilterLogical) filter).getOperation() == SearchFilterParser.FilterLogicalOperation.and) {
return myBuilder.and(leftPredicate, rightPredicate);
} else if (((SearchFilterParser.FilterLogical) filter).getOperation() == SearchFilterParser.FilterLogicalOperation.or) {
return myBuilder.or(leftPredicate, rightPredicate);
if (((SearchFilterParser.FilterLogical) theFilter).getOperation() == SearchFilterParser.FilterLogicalOperation.and) {
return myBuilder.and(xPredicate, yPredicate);
} else if (((SearchFilterParser.FilterLogical) theFilter).getOperation() == SearchFilterParser.FilterLogicalOperation.or) {
return myBuilder.or(xPredicate, yPredicate);
}
} else if (filter instanceof SearchFilterParser.FilterParameterGroup) {
return processFilter(((SearchFilterParser.FilterParameterGroup) filter).getContained(),
} else if (theFilter instanceof SearchFilterParser.FilterParameterGroup) {
return processFilter(((SearchFilterParser.FilterParameterGroup) theFilter).getContained(),
theResourceName, theRequest);
}
return null;
@ -2867,29 +2895,30 @@ public class SearchBuilder implements ISearchBuilder {
return;
}
if (theParamName.equals(IAnyResource.SP_RES_ID)) {
switch (theParamName) {
case IAnyResource.SP_RES_ID:
addPredicateResourceId(theResourceName, theAndOrParams, theRequest);
break;
} else if (theParamName.equals(IAnyResource.SP_RES_LANGUAGE)) {
case IAnyResource.SP_RES_LANGUAGE:
addPredicateLanguage(theAndOrParams);
break;
} else if (theParamName.equals(Constants.PARAM_HAS)) {
case Constants.PARAM_HAS:
addPredicateHas(theAndOrParams, theRequest);
break;
} else if (theParamName.equals(Constants.PARAM_TAG) || theParamName.equals(Constants.PARAM_PROFILE) || theParamName.equals(Constants.PARAM_SECURITY)) {
case Constants.PARAM_TAG:
case Constants.PARAM_PROFILE:
case Constants.PARAM_SECURITY:
addPredicateTag(theAndOrParams, theParamName);
break;
} else if (theParamName.equals(Constants.PARAM_SOURCE)) {
case Constants.PARAM_SOURCE:
addPredicateSource(theAndOrParams, theRequest);
break;
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateSource(nextAnd, SearchFilterParser.CompareOperation.eq, theRequest);
}
} else {
default:
RuntimeSearchParam nextParamDef = mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName);
if (nextParamDef != null) {
@ -2975,6 +3004,7 @@ public class SearchBuilder implements ISearchBuilder {
throw new InvalidRequestException("Unknown search parameter " + theParamName + " for resource type " + theResourceName);
}
}
break;
}
}
@ -3079,16 +3109,16 @@ public class SearchBuilder implements ISearchBuilder {
}
public class IncludesIterator extends BaseIterator<Long> implements Iterator<Long> {
public class IncludesIterator extends BaseIterator<ResourcePersistentId> implements Iterator<ResourcePersistentId> {
private final RequestDetails myRequest;
private Iterator<Long> myCurrentIterator;
private Iterator<ResourcePersistentId> myCurrentIterator;
private int myCurrentOffset;
private ArrayList<Long> myCurrentPids;
private Long myNext;
private ArrayList<ResourcePersistentId> myCurrentPids;
private ResourcePersistentId myNext;
private int myPageSize = myDaoConfig.getEverythingIncludesFetchPageSize();
IncludesIterator(Set<Long> thePidSet, RequestDetails theRequest) {
IncludesIterator(Set<ResourcePersistentId> thePidSet, RequestDetails theRequest) {
myCurrentPids = new ArrayList<>(thePidSet);
myCurrentIterator = EMPTY_LONG_LIST.iterator();
myCurrentOffset = 0;
@ -3113,9 +3143,9 @@ public class SearchBuilder implements ISearchBuilder {
break;
}
myCurrentOffset = end;
Collection<Long> pidsToScan = myCurrentPids.subList(start, end);
Collection<ResourcePersistentId> pidsToScan = myCurrentPids.subList(start, end);
Set<Include> includes = Collections.singleton(new Include("*", true));
Set<Long> newPids = loadIncludes(myContext, myEntityManager, pidsToScan, includes, false, myParams.getLastUpdated(), mySearchUuid, myRequest);
Set<ResourcePersistentId> newPids = loadIncludes(myContext, myEntityManager, pidsToScan, includes, false, myParams.getLastUpdated(), mySearchUuid, myRequest);
myCurrentIterator = newPids.iterator();
}
@ -3128,16 +3158,16 @@ public class SearchBuilder implements ISearchBuilder {
}
@Override
public Long next() {
public ResourcePersistentId next() {
fetchNext();
Long retVal = myNext;
ResourcePersistentId retVal = myNext;
myNext = null;
return retVal;
}
}
private final class QueryIterator extends BaseIterator<Long> implements IResultIterator {
private final class QueryIterator extends BaseIterator<ResourcePersistentId> implements IResultIterator {
private final SearchRuntimeDetails mySearchRuntimeDetails;
private final RequestDetails myRequest;
@ -3145,8 +3175,8 @@ public class SearchBuilder implements ISearchBuilder {
private final boolean myHavePerftraceFoundIdHook;
private boolean myFirst = true;
private IncludesIterator myIncludesIterator;
private Long myNext;
private Iterator<Long> myPreResultsIterator;
private ResourcePersistentId myNext;
private Iterator<ResourcePersistentId> myPreResultsIterator;
private ScrollableResultsIterator<Long> myResultsIterator;
private SortSpec mySort;
private boolean myStillNeedToFetchIncludes;
@ -3199,7 +3229,7 @@ public class SearchBuilder implements ISearchBuilder {
if (myPreResultsIterator != null && myPreResultsIterator.hasNext()) {
while (myPreResultsIterator.hasNext()) {
Long next = myPreResultsIterator.next();
ResourcePersistentId next = myPreResultsIterator.next();
if (next != null)
if (myPidSet.add(next)) {
myNext = next;
@ -3210,15 +3240,16 @@ public class SearchBuilder implements ISearchBuilder {
if (myNext == null) {
while (myResultsIterator.hasNext()) {
Long next = myResultsIterator.next();
Long nextLong = myResultsIterator.next();
if (myHavePerftraceFoundIdHook) {
HookParams params = new HookParams()
.add(Integer.class, System.identityHashCode(this))
.add(Object.class, next);
.add(Object.class, nextLong);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, params);
}
if (next != null) {
if (nextLong != null) {
ResourcePersistentId next = new ResourcePersistentId(nextLong);
if (myPidSet.add(next)) {
myNext = next;
break;
@ -3236,7 +3267,7 @@ public class SearchBuilder implements ISearchBuilder {
}
if (myIncludesIterator != null) {
while (myIncludesIterator.hasNext()) {
Long next = myIncludesIterator.next();
ResourcePersistentId next = myIncludesIterator.next();
if (next != null)
if (myPidSet.add(next)) {
myNext = next;
@ -3294,9 +3325,9 @@ public class SearchBuilder implements ISearchBuilder {
}
@Override
public Long next() {
public ResourcePersistentId next() {
fetchNext();
Long retVal = myNext;
ResourcePersistentId retVal = myNext;
myNext = null;
Validate.isTrue(!NO_MORE.equals(retVal), "No more elements");
return retVal;
@ -3430,7 +3461,7 @@ public class SearchBuilder implements ISearchBuilder {
return likeExpression.replace("%", "[%]") + "%";
}
private static List<Long> filterResourceIdsByLastUpdated(EntityManager theEntityManager, final DateRangeParam theLastUpdated, Collection<Long> thePids) {
private static List<ResourcePersistentId> filterResourceIdsByLastUpdated(EntityManager theEntityManager, final DateRangeParam theLastUpdated, Collection<ResourcePersistentId> thePids) {
if (thePids.isEmpty()) {
return Collections.emptyList();
}
@ -3440,12 +3471,12 @@ public class SearchBuilder implements ISearchBuilder {
cq.select(from.get("myId").as(Long.class));
List<Predicate> lastUpdatedPredicates = createLastUpdatedPredicates(theLastUpdated, builder, from);
lastUpdatedPredicates.add(from.get("myId").as(Long.class).in(thePids));
lastUpdatedPredicates.add(from.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(thePids)));
cq.where(SearchBuilder.toArray(lastUpdatedPredicates));
TypedQuery<Long> query = theEntityManager.createQuery(cq);
return query.getResultList();
return ResourcePersistentId.fromLongList(query.getResultList());
}

View File

@ -27,10 +27,9 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IResourceIndexedSearchParamStringDao extends JpaRepository<ResourceIndexedSearchParamString, Long> {
import java.util.List;
@Query("select count(*) from ResourceIndexedSearchParamString t WHERE t.myResourcePid = :resid")
int countForResourceId(@Param("resid") Long theResourcePid);
public interface IResourceIndexedSearchParamStringDao extends JpaRepository<ResourceIndexedSearchParamString, Long> {
@Modifying
@Query("delete from ResourceIndexedSearchParamString t WHERE t.myResourcePid = :resid")

View File

@ -32,18 +32,6 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
public class FhirResourceDaoBundleDstu3 extends BaseHapiFhirResourceDao<Bundle> {
@Override
protected void preProcessResourceForStorage(Bundle theResource) {
super.preProcessResourceForStorage(theResource);
Set<String> allowedBundleTypes = getConfig().getBundleTypesAllowedForStorage();
if (theResource.getType() == null || !allowedBundleTypes.contains(defaultString(theResource.getType().toCode()))) {
String message = "Unable to store a Bundle resource on this server with a Bundle.type value of: " + (theResource.getType() != null ? theResource.getType().toCode() : "(missing)");
throw new UnprocessableEntityException(message);
}
}
// nothing
}

View File

@ -20,9 +20,12 @@ package ca.uhn.fhir.jpa.dao.dstu3;
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
@ -37,7 +40,6 @@ import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
@ -63,6 +65,8 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
private ValidationSupportChain myValidationSupport;
@Autowired
protected ITermCodeSystemStorageSvc myTerminologyCodeSystemStorageSvc;
@Autowired
private FhirContext myFhirContext;
public FhirResourceDaoCodeSystemDstu3() {
super();
@ -70,10 +74,11 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
@Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest );
Set<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest );
List<IIdType> valueSetIds = new ArrayList<>();
for (Long next : ids) {
valueSetIds.add(new IdType("CodeSystem", next));
for (ResourcePersistentId next : ids) {
IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "CodeSystem", next);
valueSetIds.add(id);
}
return valueSetIds;
}
@ -135,7 +140,7 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
if (!retVal.isUnchangedInCurrentOperation()) {
@ -145,7 +150,7 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
org.hl7.fhir.r4.model.CodeSystem cs = VersionConvertor_30_40.convertCodeSystem(csDstu3);
addPidToResource(theEntity, cs);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, theEntity);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity);
}

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.term.TranslationMatch;
import ca.uhn.fhir.jpa.term.TranslationRequest;
import ca.uhn.fhir.jpa.term.TranslationResult;
@ -157,7 +158,7 @@ public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<Conc
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoSubscription;
import ca.uhn.fhir.jpa.dao.data.ISubscriptionTableDao;
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.dstu3.model.Subscription;
@ -65,12 +66,12 @@ public class FhirResourceDaoSubscriptionDstu3 extends BaseHapiFhirResourceDao<Su
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
if (theDeletedTimestampOrNull != null) {
mySubscriptionTableDao.deleteAllForSubscription(theEntity);
mySubscriptionTableDao.deleteAllForSubscription((ResourceTable) theEntity);
}
return retVal;
}

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.util.LogicUtil;
@ -411,7 +412,7 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueS
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);

View File

@ -43,7 +43,7 @@ import java.util.List;
public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
@Autowired
private TransactionProcessor<Bundle, BundleEntryComponent> myTransactionProcessor;
private TransactionProcessor myTransactionProcessor;
@Override
@PostConstruct

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.IResourceLinkResolver;
import ca.uhn.fhir.rest.api.server.RequestDetails;
@ -60,7 +61,7 @@ public class DaoResourceLinkResolver implements IResourceLinkResolver {
@Override
public ResourceTable findTargetResource(RuntimeSearchParam theNextSpDef, String theNextPathsUnsplit, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId, RequestDetails theRequest) {
ResourceTable target;
Long valueOf;
ResourcePersistentId valueOf;
try {
valueOf = myIdHelperService.translateForcedIdToPid(theTypeString, theId, theRequest);
ourLog.trace("Translated {}/{} to resource PID {}", theType, theId, valueOf);
@ -76,12 +77,12 @@ public class DaoResourceLinkResolver implements IResourceLinkResolver {
newResource.setId(resName + "/" + theId);
IFhirResourceDao<IBaseResource> placeholderResourceDao = (IFhirResourceDao<IBaseResource>) myDaoRegistry.getResourceDao(newResource.getClass());
ourLog.debug("Automatically creating empty placeholder resource: {}", newResource.getIdElement().getValue());
valueOf = placeholderResourceDao.update(newResource).getEntity().getId();
valueOf = placeholderResourceDao.update(newResource).getEntity().getPersistentId();
} else {
throw new InvalidRequestException("Resource " + resName + "/" + theId + " not found, specified in path: " + theNextPathsUnsplit);
}
}
target = myEntityManager.find(ResourceTable.class, valueOf);
target = myEntityManager.find(ResourceTable.class, valueOf.getIdAsLong());
RuntimeResourceDefinition targetResourceDef = myContext.getResourceDefinition(theType);
if (target == null) {
String resName = targetResourceDef.getName();

View File

@ -20,8 +20,10 @@ package ca.uhn.fhir.jpa.dao.index;
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
@ -61,7 +63,7 @@ public class IdHelperService {
* @throws ResourceNotFoundException If the ID can not be found
*/
@Nonnull
public Long translateForcedIdToPid(IIdType theId, RequestDetails theRequestDetails) {
public ResourcePersistentId translateForcedIdToPid(IIdType theId, RequestDetails theRequestDetails) {
return translateForcedIdToPid(theId.getResourceType(), theId.getIdPart(), theRequestDetails);
}
@ -69,10 +71,10 @@ public class IdHelperService {
* @throws ResourceNotFoundException If the ID can not be found
*/
@Nonnull
public Long translateForcedIdToPid(String theResourceName, String theResourceId, RequestDetails theRequestDetails) throws ResourceNotFoundException {
public ResourcePersistentId translateForcedIdToPid(String theResourceName, String theResourceId, RequestDetails theRequestDetails) throws ResourceNotFoundException {
// We only pass 1 input in so only 0..1 will come back
IdDt id = new IdDt(theResourceName, theResourceId);
List<Long> matches = translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, theRequestDetails, myForcedIdDao, Collections.singletonList(id));
List<ResourcePersistentId> matches = translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, theRequestDetails, myForcedIdDao, Collections.singletonList(id));
assert matches.size() <= 1;
if (matches.isEmpty()) {
throw new ResourceNotFoundException(id);
@ -80,23 +82,23 @@ public class IdHelperService {
return matches.get(0);
}
public List<Long> translateForcedIdToPids(Collection<IIdType> theId, RequestDetails theRequestDetails) {
public List<ResourcePersistentId> translateForcedIdToPids(Collection<IIdType> theId, RequestDetails theRequestDetails) {
return IdHelperService.translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, theRequestDetails, myForcedIdDao, theId);
}
private static List<Long> translateForcedIdToPids(DaoConfig theDaoConfig, IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequest, IForcedIdDao theForcedIdDao, Collection<IIdType> theId) {
private static List<ResourcePersistentId> translateForcedIdToPids(DaoConfig theDaoConfig, IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequest, IForcedIdDao theForcedIdDao, Collection<IIdType> theId) {
theId.forEach(id -> Validate.isTrue(id.hasIdPart()));
if (theId.isEmpty()) {
return Collections.emptyList();
}
List<Long> retVal = new ArrayList<>();
List<ResourcePersistentId> retVal = new ArrayList<>();
ListMultimap<String, String> typeToIds = MultimapBuilder.hashKeys().arrayListValues().build();
for (IIdType nextId : theId) {
if (theDaoConfig.getResourceClientIdStrategy() != DaoConfig.ClientIdStrategyEnum.ANY && isValidPid(nextId)) {
retVal.add(nextId.getIdPartAsLong());
retVal.add(new ResourcePersistentId(nextId.getIdPartAsLong()));
} else {
if (nextId.hasResourceType()) {
typeToIds.put(nextId.getResourceType(), nextId.getIdPart());
@ -119,18 +121,34 @@ public class IdHelperService {
.add(StorageProcessingMessage.class, msg);
JpaInterceptorBroadcaster.doCallHooks(theInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
retVal.addAll(theForcedIdDao.findByForcedId(nextIds));
theForcedIdDao
.findByForcedId(nextIds)
.stream()
.map(t->new ResourcePersistentId(t))
.forEach(t->retVal.add(t));
} else {
retVal.addAll(theForcedIdDao.findByTypeAndForcedId(nextResourceType, nextIds));
theForcedIdDao
.findByTypeAndForcedId(nextResourceType, nextIds)
.stream()
.map(t->new ResourcePersistentId(t))
.forEach(t->retVal.add(t));
}
}
return retVal;
}
String translatePidIdToForcedId(String theResourceType, Long theId) {
ForcedId forcedId = myForcedIdDao.findByResourcePid(theId);
public IIdType translatePidIdToForcedId(FhirContext theCtx, String theResourceType, ResourcePersistentId theId) {
IIdType retVal = theCtx.getVersion().newIdType();
retVal.setValue(translatePidIdToForcedId(theResourceType, theId));
return retVal;
}
public String translatePidIdToForcedId(String theResourceType, ResourcePersistentId theId) {
ForcedId forcedId = myForcedIdDao.findByResourcePid(theId.getIdAsLong());
if (forcedId != null) {
return forcedId.getResourceType() + '/' + forcedId.getForcedId();
} else {

View File

@ -25,9 +25,9 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedCompositeStringUniqueDao;
import ca.uhn.fhir.jpa.dao.MatchResourceUrlService;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedCompositeStringUniqueDao;
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedCompositeStringUnique;
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
@ -54,7 +54,14 @@ import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -238,7 +245,7 @@ public class SearchParamWithInlineReferencesExtractor {
throw new InvalidRequestException(msg);
}
Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass();
Set<Long> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType, theRequest);
Set<ResourcePersistentId> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType, theRequest);
if (matches.isEmpty()) {
String msg = myContext.getLocalizer().getMessage(BaseHapiFhirDao.class, "invalidMatchUrlNoMatches", nextId.getValue());
throw new ResourceNotFoundException(msg);
@ -247,7 +254,7 @@ public class SearchParamWithInlineReferencesExtractor {
String msg = myContext.getLocalizer().getMessage(BaseHapiFhirDao.class, "invalidMatchUrlMultipleMatches", nextId.getValue());
throw new PreconditionFailedException(msg);
}
Long next = matches.iterator().next();
ResourcePersistentId next = matches.iterator().next();
String newId = myIdHelperService.translatePidIdToForcedId(resourceTypeString, next);
ourLog.debug("Replacing inline match URL[{}] with ID[{}}", nextId.getValue(), newId);
nextRef.setReference(newId);

View File

@ -33,16 +33,6 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
public class FhirResourceDaoBundleR4 extends BaseHapiFhirResourceDao<Bundle> {
@Override
protected void preProcessResourceForStorage(Bundle theResource) {
super.preProcessResourceForStorage(theResource);
Set<String> allowedBundleTypes = getConfig().getBundleTypesAllowedForStorage();
if (theResource.getType() == null || !allowedBundleTypes.contains(defaultString(theResource.getType().toCode()))) {
String message = "Unable to store a Bundle resource on this server with a Bundle.type value of: " + (theResource.getType() != null ? theResource.getType().toCode() : "(missing)");
throw new UnprocessableEntityException(message);
}
}
// nothing for now
}

View File

@ -20,9 +20,12 @@ package ca.uhn.fhir.jpa.dao.r4;
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
@ -39,7 +42,6 @@ import org.hl7.fhir.r4.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.IdType;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Nonnull;
@ -60,14 +62,17 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
private ValidationSupportChain myValidationSupport;
@Autowired
protected ITermCodeSystemStorageSvc myTerminologyCodeSystemStorageSvc;
@Autowired
private FhirContext myFhirContext;
@Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
Set<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
valueSetIds = new ArrayList<>();
for (Long next : ids) {
valueSetIds.add(new IdType("CodeSystem", next));
for (ResourcePersistentId next : ids) {
IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "CodeSystem", next);
valueSetIds.add(id);
}
return valueSetIds;
}
@ -132,7 +137,7 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
@ -140,7 +145,7 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
CodeSystem cs = (CodeSystem) theResource;
addPidToResource(theEntity, theResource);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, theEntity);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity);
}
return retVal;

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
@ -157,7 +158,7 @@ public class FhirResourceDaoConceptMapR4 extends BaseHapiFhirResourceDao<Concept
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoSubscription;
import ca.uhn.fhir.jpa.dao.data.ISubscriptionTableDao;
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -65,7 +66,7 @@ public class FhirResourceDaoSubscriptionR4 extends BaseHapiFhirResourceDao<Subsc
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.util.LogicUtil;
@ -392,7 +393,7 @@ public class FhirResourceDaoValueSetR4 extends BaseHapiFhirResourceDao<ValueSet>
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);

View File

@ -45,7 +45,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoR4.class);
@Autowired
private TransactionProcessor<Bundle, BundleEntryComponent> myTransactionProcessor;
private TransactionProcessor myTransactionProcessor;
@Override
@PostConstruct

View File

@ -30,16 +30,6 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
public class FhirResourceDaoBundleR5 extends BaseHapiFhirResourceDao<Bundle> {
@Override
protected void preProcessResourceForStorage(Bundle theResource) {
super.preProcessResourceForStorage(theResource);
Set<String> allowedBundleTypes = getConfig().getBundleTypesAllowedForStorage();
if (theResource.getType() == null || !allowedBundleTypes.contains(defaultString(theResource.getType().toCode()))) {
String message = "Unable to store a Bundle resource on this server with a Bundle.type value of: " + (theResource.getType() != null ? theResource.getType().toCode() : "(missing)");
throw new UnprocessableEntityException(message);
}
}
// nothing
}

View File

@ -20,10 +20,14 @@ package ca.uhn.fhir.jpa.dao.r5;
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -39,7 +43,6 @@ import org.hl7.fhir.r5.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.IdType;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Nonnull;
@ -60,14 +63,19 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
private ValidationSupportChain myValidationSupport;
@Autowired
protected ITermCodeSystemStorageSvc myTerminologyCodeSystemStorageSvc;
@Autowired
protected IdHelperService myIdHelperService;
@Autowired
private FhirContext myFhirContext;
@Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
Set<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
valueSetIds = new ArrayList<>();
for (Long next : ids) {
valueSetIds.add(new IdType("CodeSystem", next));
for (ResourcePersistentId next : ids) {
IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "CodeSystem", next);
valueSetIds.add(id);
}
return valueSetIds;
}
@ -132,7 +140,7 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
if (!retVal.isUnchangedInCurrentOperation()) {
@ -140,7 +148,7 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
CodeSystem cs = (CodeSystem) theResource;
addPidToResource(theEntity, theResource);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(org.hl7.fhir.convertors.conv40_50.CodeSystem.convertCodeSystem(cs), theEntity);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(org.hl7.fhir.convertors.conv40_50.CodeSystem.convertCodeSystem(cs), (ResourceTable) theEntity);
}
return retVal;

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.TranslationMatch;
@ -158,8 +159,8 @@ public class FhirResourceDaoConceptMapR5 extends BaseHapiFhirResourceDao<Concept
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
if (!retVal.isUnchangedInCurrentOperation()) {

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoSubscription;
import ca.uhn.fhir.jpa.dao.data.ISubscriptionTableDao;
import ca.uhn.fhir.jpa.entity.SubscriptionTable;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.EncodingEnum;
@ -74,7 +75,7 @@ public class FhirResourceDaoSubscriptionR5 extends BaseHapiFhirResourceDao<Subsc
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion,
Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.util.LogicUtil;
@ -404,7 +405,7 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao<ValueSet>
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);

View File

@ -45,7 +45,7 @@ public class FhirSystemDaoR5 extends BaseHapiFhirSystemDao<Bundle, Meta> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoR5.class);
@Autowired
private TransactionProcessor<Bundle, BundleEntryComponent> myTransactionProcessor;
private TransactionProcessor myTransactionProcessor;
@Override
@PostConstruct

View File

@ -132,12 +132,12 @@ public class DeleteConflictService {
}
}
public void validateDeleteConflictsEmptyOrThrowException(DeleteConflictList theDeleteConflicts) {
public static void validateDeleteConflictsEmptyOrThrowException(FhirContext theFhirContext, DeleteConflictList theDeleteConflicts) {
if (theDeleteConflicts.isEmpty()) {
return;
}
IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(myFhirContext);
IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(theFhirContext);
String firstMsg = null;
Iterator<DeleteConflict> iterator = theDeleteConflicts.iterator();
@ -154,7 +154,7 @@ public class DeleteConflictService {
if (firstMsg == null) {
firstMsg = msg;
}
OperationOutcomeUtil.addIssue(myFhirContext, oo, BaseHapiFhirDao.OO_SEVERITY_ERROR, msg, null, "processing");
OperationOutcomeUtil.addIssue(theFhirContext, oo, BaseHapiFhirDao.OO_SEVERITY_ERROR, msg, null, "processing");
}
throw new ResourceVersionConflictException(firstMsg, oo);

View File

@ -42,6 +42,7 @@ import org.hl7.fhir.utilities.graphql.Value;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nullable;
import java.util.List;
public class JpaStorageServices extends BaseHapiFhirDao<IBaseResource> implements IGraphQLStorageServices {
@ -145,4 +146,10 @@ public class JpaStorageServices extends BaseHapiFhirDao<IBaseResource> implement
public IBaseBundle search(Object theAppInfo, String theType, List<Argument> theSearchParams) throws FHIRException {
throw new NotImplementedOperationException("Not yet able to handle this GraphQL request");
}
@Nullable
@Override
protected String getResourceName() {
return null;
}
}

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.interceptor;
*/
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.util.ICallable;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -36,12 +37,12 @@ import java.util.List;
@NotThreadSafe
public class JpaPreResourceAccessDetails implements IPreResourceAccessDetails {
private final List<Long> myResourcePids;
private final List<ResourcePersistentId> myResourcePids;
private final boolean[] myBlocked;
private final ICallable<ISearchBuilder> mySearchBuilderSupplier;
private List<IBaseResource> myResources;
public JpaPreResourceAccessDetails(List<Long> theResourcePids, ICallable<ISearchBuilder> theSearchBuilderSupplier) {
public JpaPreResourceAccessDetails(List<ResourcePersistentId> theResourcePids, ICallable<ISearchBuilder> theSearchBuilderSupplier) {
myResourcePids = theResourcePids;
myBlocked = new boolean[myResourcePids.size()];
mySearchBuilderSupplier = theSearchBuilderSupplier;

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.search;
*/
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
@ -34,7 +35,7 @@ public interface ISearchCoordinatorSvc {
void cancelAllActiveSearches();
List<Long> getResources(String theUuid, int theFrom, int theTo, @Nullable RequestDetails theRequestDetails);
List<ResourcePersistentId> getResources(String theUuid, int theFrom, int theTo, @Nullable RequestDetails theRequestDetails);
IBundleProvider registerSearch(IDao theCallingDao, SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective, @Nullable RequestDetails theRequestDetails);

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
@ -175,7 +176,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
Class<? extends IBaseResource> resourceType = myContext.getResourceDefinition(resourceName).getImplementingClass();
sb.setType(resourceType, resourceName);
final List<Long> pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex, myRequest);
final List<ResourcePersistentId> pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex, myRequest);
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@ -310,15 +311,15 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
// Note: Leave as protected, HSPC depends on this
@SuppressWarnings("WeakerAccess")
protected List<IBaseResource> toResourceList(ISearchBuilder theSearchBuilder, List<Long> thePids) {
Set<Long> includedPids = new HashSet<>();
protected List<IBaseResource> toResourceList(ISearchBuilder theSearchBuilder, List<ResourcePersistentId> thePids) {
Set<ResourcePersistentId> includedPids = new HashSet<>();
if (mySearchEntity.getSearchType() == SearchTypeEnum.SEARCH) {
includedPids.addAll(theSearchBuilder.loadIncludes(myContext, myEntityManager, thePids, mySearchEntity.toRevIncludesList(), true, mySearchEntity.getLastUpdated(), myUuid, myRequest));
includedPids.addAll(theSearchBuilder.loadIncludes(myContext, myEntityManager, thePids, mySearchEntity.toIncludesList(), false, mySearchEntity.getLastUpdated(), myUuid, myRequest));
}
List<Long> includedPidList = new ArrayList<>(includedPids);
List<ResourcePersistentId> includedPidList = new ArrayList<>(includedPids);
// Execute the query and make sure we return distinct results
List<IBaseResource> resources = new ArrayList<>();

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.search;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl.SearchTask;
@ -66,7 +67,7 @@ public class PersistedJpaSearchFirstPageBundleProvider extends PersistedJpaBundl
mySearchTask.awaitInitialSync();
ourLog.trace("Fetching search resource PIDs from task: {}", mySearchTask.getClass());
final List<Long> pids = mySearchTask.getResourcePids(theFromIndex, theToIndex);
final List<ResourcePersistentId> pids = mySearchTask.getResourcePids(theFromIndex, theToIndex);
ourLog.trace("Done fetching search resource PIDs");
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);

View File

@ -29,6 +29,7 @@ import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchInclude;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
@ -173,7 +174,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
*/
@Override
@Transactional(propagation = Propagation.NEVER)
public List<Long> getResources(final String theUuid, int theFrom, int theTo, @Nullable RequestDetails theRequestDetails) {
public List<ResourcePersistentId> getResources(final String theUuid, int theFrom, int theTo, @Nullable RequestDetails theRequestDetails) {
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@ -193,7 +194,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
if (myNeverUseLocalSearchForUnitTests == false) {
if (searchTask != null) {
ourLog.trace("Local search found");
List<Long> resourcePids = searchTask.getResourcePids(theFrom, theTo);
List<ResourcePersistentId> resourcePids = searchTask.getResourcePids(theFrom, theTo);
ourLog.trace("Local search returned {} pids, wanted {}-{} - Search: {}", resourcePids.size(), theFrom, theTo, searchTask.getSearch());
/*
@ -249,7 +250,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
ourLog.trace("Finished looping");
List<Long> pids = mySearchResultCacheSvc.fetchResultPids(search, theFrom, theTo);
List<ResourcePersistentId> pids = mySearchResultCacheSvc.fetchResultPids(search, theFrom, theTo);
if (pids == null) {
throw newResourceGoneException(theUuid);
}
@ -446,7 +447,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
return txTemplate.execute(t -> {
// Load the results synchronously
final List<Long> pids = new ArrayList<>();
final List<ResourcePersistentId> pids = new ArrayList<>();
try (IResultIterator resultIter = theSb.createQuery(theParams, searchRuntimeDetails, theRequestDetails)) {
while (resultIter.hasNext()) {
@ -485,10 +486,10 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
* On the other hand for async queries we load includes/revincludes
* individually for pages as we return them to clients
*/
final Set<Long> includedPids = new HashSet<>();
final Set<ResourcePersistentId> includedPids = new HashSet<>();
includedPids.addAll(theSb.loadIncludes(myContext, myEntityManager, pids, theParams.getRevIncludes(), true, theParams.getLastUpdated(), "(synchronous)", theRequestDetails));
includedPids.addAll(theSb.loadIncludes(myContext, myEntityManager, pids, theParams.getIncludes(), false, theParams.getLastUpdated(), "(synchronous)", theRequestDetails));
List<Long> includedPidsList = new ArrayList<>(includedPids);
List<ResourcePersistentId> includedPidsList = new ArrayList<>(includedPids);
List<IBaseResource> resources = new ArrayList<>();
theSb.loadResourcesByPid(pids, includedPidsList, resources, false, theRequestDetails);
@ -580,10 +581,10 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private final SearchParameterMap myParams;
private final IDao myCallingDao;
private final String myResourceType;
private final ArrayList<Long> mySyncedPids = new ArrayList<>();
private final ArrayList<ResourcePersistentId> mySyncedPids = new ArrayList<>();
private final CountDownLatch myInitialCollectionLatch = new CountDownLatch(1);
private final CountDownLatch myCompletionLatch;
private final ArrayList<Long> myUnsyncedPids = new ArrayList<>();
private final ArrayList<ResourcePersistentId> myUnsyncedPids = new ArrayList<>();
private final RequestDetails myRequest;
private Search mySearch;
private boolean myAbortRequested;
@ -591,7 +592,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private int myCountSavedThisPass = 0;
private int myCountBlockedThisPass = 0;
private boolean myAdditionalPrefetchThresholdsRemaining;
private List<Long> myPreviouslyAddedResourcePids;
private List<ResourcePersistentId> myPreviouslyAddedResourcePids;
private Integer myMaxResultsToFetch;
private SearchRuntimeDetails mySearchRuntimeDetails;
@ -635,7 +636,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
return myInitialCollectionLatch;
}
void setPreviouslyAddedResourcePids(List<Long> thePreviouslyAddedResourcePids) {
void setPreviouslyAddedResourcePids(List<ResourcePersistentId> thePreviouslyAddedResourcePids) {
myPreviouslyAddedResourcePids = thePreviouslyAddedResourcePids;
myCountSavedTotal = myPreviouslyAddedResourcePids.size();
}
@ -649,7 +650,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
}
@Nonnull
List<Long> getResourcePids(int theFromIndex, int theToIndex) {
List<ResourcePersistentId> getResourcePids(int theFromIndex, int theToIndex) {
ourLog.debug("Requesting search PIDs from {}-{}", theFromIndex, theToIndex);
boolean keepWaiting;
@ -673,6 +674,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
break;
case FAILED:
case FINISHED:
case GONE:
default:
keepWaiting = false;
break;
@ -690,7 +692,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
ourLog.debug("Proceeding, as we have {} results", mySyncedPids.size());
ArrayList<Long> retVal = new ArrayList<>();
ArrayList<ResourcePersistentId> retVal = new ArrayList<>();
synchronized (mySyncedPids) {
verifySearchHasntFailedOrThrowInternalErrorException(mySearch);
@ -713,7 +715,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(@NotNull TransactionStatus theArg0) {
protected void doInTransactionWithoutResult(@Nonnull @NotNull TransactionStatus theArg0) {
doSaveSearch();
}
@ -725,12 +727,12 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(@NotNull TransactionStatus theArg0) {
protected void doInTransactionWithoutResult(@Nonnull @NotNull TransactionStatus theArg0) {
if (mySearch.getId() == null) {
doSaveSearch();
}
ArrayList<Long> unsyncedPids = myUnsyncedPids;
ArrayList<ResourcePersistentId> unsyncedPids = myUnsyncedPids;
int countBlocked = 0;
// Interceptor call: STORAGE_PREACCESS_RESOURCES
@ -847,7 +849,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theStatus) {
doSearch();
}
});
@ -962,7 +964,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
protected void doInTransactionWithoutResult(@Nonnull TransactionStatus theArg0) {
mySearch.setTotalCount(count.intValue());
if (wantOnlyCount) {
mySearch.setStatus(SearchStatusEnum.FINISHED);
@ -1093,7 +1095,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.afterPropertiesSet();
txTemplate.execute(t -> {
List<Long> previouslyAddedResourcePids = mySearchResultCacheSvc.fetchAllResultPids(getSearch());
List<ResourcePersistentId> previouslyAddedResourcePids = mySearchResultCacheSvc.fetchAllResultPids(getSearch());
if (previouslyAddedResourcePids == null) {
throw newResourceGoneException(getSearch().getUuid());
}

View File

@ -20,19 +20,17 @@ package ca.uhn.fhir.jpa.search.cache;
* #L%
*/
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchResult;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -46,7 +44,7 @@ public class DatabaseSearchResultCacheSvcImpl implements ISearchResultCacheSvc {
@Override
@Transactional(Transactional.TxType.REQUIRED)
public List<Long> fetchResultPids(Search theSearch, int theFrom, int theTo) {
public List<ResourcePersistentId> fetchResultPids(Search theSearch, int theFrom, int theTo) {
final Pageable page = toPage(theFrom, theTo);
if (page == null) {
return Collections.emptyList();
@ -58,28 +56,28 @@ public class DatabaseSearchResultCacheSvcImpl implements ISearchResultCacheSvc {
ourLog.debug("fetchResultPids for range {}-{} returned {} pids", theFrom, theTo, retVal.size());
return new ArrayList<>(retVal);
return ResourcePersistentId.fromLongList(retVal);
}
@Override
@Transactional(Transactional.TxType.REQUIRED)
public List<Long> fetchAllResultPids(Search theSearch) {
public List<ResourcePersistentId> fetchAllResultPids(Search theSearch) {
List<Long> retVal = mySearchResultDao.findWithSearchPidOrderIndependent(theSearch.getId());
ourLog.trace("fetchAllResultPids returned {} pids", retVal.size());
return retVal;
return ResourcePersistentId.fromLongList(retVal);
}
@Override
@Transactional(Transactional.TxType.REQUIRED)
public void storeResults(Search theSearch, List<Long> thePreviouslyStoredResourcePids, List<Long> theNewResourcePids) {
public void storeResults(Search theSearch, List<ResourcePersistentId> thePreviouslyStoredResourcePids, List<ResourcePersistentId> theNewResourcePids) {
List<SearchResult> resultsToSave = Lists.newArrayList();
ourLog.trace("Storing {} results with {} previous for search", theNewResourcePids.size(), thePreviouslyStoredResourcePids.size());
int order = thePreviouslyStoredResourcePids.size();
for (Long nextPid : theNewResourcePids) {
for (ResourcePersistentId nextPid : theNewResourcePids) {
SearchResult nextResult = new SearchResult(theSearch);
nextResult.setResourcePid(nextPid);
nextResult.setResourcePid(nextPid.getIdAsLong());
nextResult.setOrder(order);
resultsToSave.add(nextResult);
ourLog.trace("Saving ORDER[{}] Resource {}", order, nextResult.getResourcePid());
@ -90,10 +88,4 @@ public class DatabaseSearchResultCacheSvcImpl implements ISearchResultCacheSvc {
mySearchResultDao.saveAll(resultsToSave);
}
@VisibleForTesting
void setSearchDaoResultForUnitTest(ISearchResultDao theSearchResultDao) {
mySearchResultDao = theSearchResultDao;
}
}

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.search.cache;
* #L%
*/
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.entity.Search;
import javax.annotation.Nullable;
@ -31,7 +32,7 @@ public interface ISearchResultCacheSvc {
* @param thePreviouslyStoredResourcePids A list of resource PIDs that have previously been saved to this search
* @param theNewResourcePids A list of new resoure PIDs to add to this search (these ones have not been previously saved)
*/
void storeResults(Search theSearch, List<Long> thePreviouslyStoredResourcePids, List<Long> theNewResourcePids);
void storeResults(Search theSearch, List<ResourcePersistentId> thePreviouslyStoredResourcePids, List<ResourcePersistentId> theNewResourcePids);
/**
* Fetch a sunset of the search result IDs from the cache
@ -43,7 +44,7 @@ public interface ISearchResultCacheSvc {
* have been removed from the cache for some reason, such as expiry or manual purge)
*/
@Nullable
List<Long> fetchResultPids(Search theSearch, int theFrom, int theTo);
List<ResourcePersistentId> fetchResultPids(Search theSearch, int theFrom, int theTo);
/**
* Fetch all result PIDs for a given search with no particular order required
@ -53,6 +54,6 @@ public interface ISearchResultCacheSvc {
* have been removed from the cache for some reason, such as expiry or manual purge)
*/
@Nullable
List<Long> fetchAllResultPids(Search theSearch);
List<ResourcePersistentId> fetchAllResultPids(Search theSearch);
}

View File

@ -25,6 +25,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.sched.FireAtIntervalJob;
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
import ca.uhn.fhir.jpa.model.sched.ScheduledJobDefinition;
@ -37,8 +38,6 @@ import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
@ -252,12 +251,12 @@ public class SubscriptionTriggeringSvcImpl implements ISubscriptionTriggeringSvc
toIndex = Math.min(toIndex, theJobDetails.getCurrentSearchCount());
}
ourLog.info("Triggering job[{}] search {} requesting resources {} - {}", theJobDetails.getJobId(), theJobDetails.getCurrentSearchUuid(), fromIndex, toIndex);
List<Long> resourceIds = mySearchCoordinatorSvc.getResources(theJobDetails.getCurrentSearchUuid(), fromIndex, toIndex, null);
List<ResourcePersistentId> resourceIds = mySearchCoordinatorSvc.getResources(theJobDetails.getCurrentSearchUuid(), fromIndex, toIndex, null);
ourLog.info("Triggering job[{}] delivering {} resources", theJobDetails.getJobId(), resourceIds.size());
int highestIndexSubmitted = theJobDetails.getCurrentSearchLastUploadedIndex();
for (Long next : resourceIds) {
for (ResourcePersistentId next : resourceIds) {
IBaseResource nextResource = resourceDao.readByPid(next);
Future<Void> future = submitResource(theJobDetails.getSubscriptionId(), nextResource);
futures.add(Pair.of(nextResource.getIdElement().getIdPart(), future));

View File

@ -33,6 +33,7 @@ import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
import ca.uhn.fhir.jpa.model.sched.ScheduledJobDefinition;
@ -338,8 +339,8 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
Optional<TermValueSet> optionalTermValueSet;
if (theValueSetToExpand.hasId()) {
Long valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSetToExpand.getIdElement());
optionalTermValueSet = myValueSetDao.findByResourcePid(valueSetResourcePid);
ResourcePersistentId valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSetToExpand.getIdElement());
optionalTermValueSet = myValueSetDao.findByResourcePid(valueSetResourcePid.getIdAsLong());
} else if (theValueSetToExpand.hasUrl()) {
optionalTermValueSet = myValueSetDao.findByUrl(theValueSetToExpand.getUrl());
} else {
@ -1113,8 +1114,8 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
@Override
public boolean isValueSetPreExpandedForCodeValidation(ValueSet theValueSet) {
Long valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSet.getIdElement());
Optional<TermValueSet> optionalTermValueSet = myValueSetDao.findByResourcePid(valueSetResourcePid);
ResourcePersistentId valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSet.getIdElement());
Optional<TermValueSet> optionalTermValueSet = myValueSetDao.findByResourcePid(valueSetResourcePid.getIdAsLong());
if (!optionalTermValueSet.isPresent()) {
ourLog.warn("ValueSet is not present in terminology tables. Will perform in-memory code validation. {}", getValueSetInfo(theValueSet));
@ -1136,14 +1137,14 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
ValueSet theValueSet, String theSystem, String theCode, String theDisplay, Coding theCoding, CodeableConcept theCodeableConcept) {
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet.hasId(), "ValueSet.id is required");
Long valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSet.getIdElement());
ResourcePersistentId valueSetResourcePid = myConceptStorageSvc.getValueSetResourcePid(theValueSet.getIdElement());
List<TermValueSetConcept> concepts = new ArrayList<>();
if (isNotBlank(theCode)) {
if (isNotBlank(theSystem)) {
if (Constants.codeSystemNotNeeded(theSystem)) {
concepts.addAll(myValueSetConceptDao.findByValueSetResourcePidAndCode(valueSetResourcePid.getIdAsLong(), theCode));
} else if (isNotBlank(theSystem)) {
concepts.addAll(findByValueSetResourcePidSystemAndCode(valueSetResourcePid, theSystem, theCode));
} if (Constants.codeSystemNotNeeded(theSystem)) {
concepts.addAll(myValueSetConceptDao.findByValueSetResourcePidAndCode(valueSetResourcePid, theCode));
}
} else if (theCoding != null) {
if (theCoding.hasSystem() && theCoding.hasCode()) {
@ -1173,9 +1174,9 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
return null;
}
private List<TermValueSetConcept> findByValueSetResourcePidSystemAndCode(Long theResourcePid, String theSystem, String theCode) {
private List<TermValueSetConcept> findByValueSetResourcePidSystemAndCode(ResourcePersistentId theResourcePid, String theSystem, String theCode) {
List<TermValueSetConcept> retVal = new ArrayList<>();
Optional<TermValueSetConcept> optionalTermValueSetConcept = myValueSetConceptDao.findByValueSetResourcePidSystemAndCode(theResourcePid, theSystem, theCode);
Optional<TermValueSetConcept> optionalTermValueSetConcept = myValueSetConceptDao.findByValueSetResourcePidSystemAndCode(theResourcePid.getIdAsLong(), theSystem, theCode);
optionalTermValueSetConcept.ifPresent(retVal::add);
return retVal;
}

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.entity.*;
@ -114,11 +115,11 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
private IResourceTableDao myResourceTableDao;
@Override
public Long getValueSetResourcePid(IIdType theIdType) {
public ResourcePersistentId getValueSetResourcePid(IIdType theIdType) {
return getValueSetResourcePid(theIdType, null);
}
private Long getValueSetResourcePid(IIdType theIdType, RequestDetails theRequestDetails) {
private ResourcePersistentId getValueSetResourcePid(IIdType theIdType, RequestDetails theRequestDetails) {
return myIdHelperService.translateForcedIdToPid(theIdType, theRequestDetails);
}
@ -315,7 +316,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
if (theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.COMPLETE || theCodeSystem.getContent() == null || theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.NOTPRESENT) {
ourLog.info("CodeSystem {} has a status of {}, going to store concepts in terminology tables", theResourceEntity.getIdDt().getValue(), theCodeSystem.getContentElement().getValueAsString());
Long codeSystemResourcePid = getCodeSystemResourcePid(theCodeSystem.getIdElement());
ResourcePersistentId codeSystemResourcePid = getCodeSystemResourcePid(theCodeSystem.getIdElement());
/*
* If this is a not-present codesystem, we don't want to store a new version if one
@ -349,8 +350,8 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
Validate.notBlank(theCodeSystemResource.getUrl(), "theCodeSystemResource must have a URL");
IIdType csId = myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(theCodeSystemResource);
Long codeSystemResourcePid = myIdHelperService.translateForcedIdToPid(csId, theRequest);
ResourceTable resource = myResourceTableDao.getOne(codeSystemResourcePid);
ResourcePersistentId codeSystemResourcePid = myIdHelperService.translateForcedIdToPid(csId, theRequest);
ResourceTable resource = myResourceTableDao.getOne(codeSystemResourcePid.getIdAsLong());
ourLog.info("CodeSystem resource has ID: {}", csId.getValue());
@ -366,14 +367,14 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void storeNewCodeSystemVersion(Long theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) {
public void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) {
ourLog.debug("Storing code system");
ValidateUtil.isTrueOrThrowInvalidRequest(theCodeSystemVersion.getResource() != null, "No resource supplied");
ValidateUtil.isNotBlankOrThrowInvalidRequest(theSystemUri, "No system URI supplied");
// Grab the existing versions so we can delete them later
List<TermCodeSystemVersion> existing = myCodeSystemVersionDao.findByCodeSystemResourcePid(theCodeSystemResourcePid);
List<TermCodeSystemVersion> existing = myCodeSystemVersionDao.findByCodeSystemResourcePid(theCodeSystemResourcePid.getIdAsLong());
/*
* For now we always delete old versions. At some point it would be nice to allow configuration to keep old versions.
@ -598,11 +599,11 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
}
private Long getCodeSystemResourcePid(IIdType theIdType) {
private ResourcePersistentId getCodeSystemResourcePid(IIdType theIdType) {
return getCodeSystemResourcePid(theIdType, null);
}
private Long getCodeSystemResourcePid(IIdType theIdType, RequestDetails theRequestDetails) {
private ResourcePersistentId getCodeSystemResourcePid(IIdType theIdType, RequestDetails theRequestDetails) {
return myIdHelperService.translateForcedIdToPid(theIdType, theRequestDetails);
}
@ -676,10 +677,10 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
}
@Nonnull
private TermCodeSystem getOrCreateTermCodeSystem(Long theCodeSystemResourcePid, String theSystemUri, String theSystemName, ResourceTable theCodeSystemResourceTable) {
private TermCodeSystem getOrCreateTermCodeSystem(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, ResourceTable theCodeSystemResourceTable) {
TermCodeSystem codeSystem = myCodeSystemDao.findByCodeSystemUri(theSystemUri);
if (codeSystem == null) {
codeSystem = myCodeSystemDao.findByResourcePid(theCodeSystemResourcePid);
codeSystem = myCodeSystemDao.findByResourcePid(theCodeSystemResourcePid.getIdAsLong());
if (codeSystem == null) {
codeSystem = new TermCodeSystem();
}

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.term.api;
* #L%
*/
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
@ -40,7 +41,7 @@ public interface ITermCodeSystemStorageSvc {
void deleteCodeSystem(TermCodeSystem theCodeSystem);
void storeNewCodeSystemVersion(Long theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable);
void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable);
/**
* @return Returns the ID of the created/updated code system
@ -55,5 +56,5 @@ public interface ITermCodeSystemStorageSvc {
int saveConcept(TermConcept theNextConcept);
Long getValueSetResourcePid(IIdType theIdElement);
ResourcePersistentId getValueSetResourcePid(IIdType theIdElement);
}

View File

@ -24,7 +24,7 @@ import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
import static org.junit.Assert.fail;
@Configuration
@Import(TestJPAConfig.class)

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.dao.dstu2;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
@ -1537,7 +1538,7 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
String methodName = "testSearchValueQuantity";
QuantityParam param;
Set<Long> found;
Set<ResourcePersistentId> found;
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param), null);
int initialSize = found.size();

View File

@ -3,7 +3,7 @@ package ca.uhn.fhir.jpa.dao.dstu2;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.JpaResourceDao;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3Test;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
@ -221,8 +221,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertThat(toUnqualifiedVersionlessIdValues(found), hasItem(id2.getValue()));
}
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(found, not(hasItem(id2.getIdPartAsLong())));
Set<ResourcePersistentId> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(ResourcePersistentId.toLongList(found), not(hasItem(id2.getIdPartAsLong())));
}
}
@ -1548,7 +1548,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
"}\n";
//@formatter:on
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
@ -2677,7 +2677,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
@ -2825,7 +2825,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.dao.dstu2;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
@ -166,9 +167,9 @@ public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
p2.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd);
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")), null);
Set<ResourcePersistentId> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong()));
assertThat(ResourcePersistentId.toLongList(ids), contains(p1id.getIdPartAsLong()));
// Update the name
p1.getNameFirstRep().getGivenFirstRep().setValue("testUpdateMaintainsSearchParamsDstu2BBB");

View File

@ -6,6 +6,7 @@ import static org.junit.Assert.assertThat;
import java.util.List;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import org.junit.AfterClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -65,8 +66,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// OR
{
@ -74,8 +75,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// AND
{
@ -84,8 +85,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// AND OR
{
@ -94,8 +95,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// All Resource Types
{
@ -103,8 +104,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")).addOr(new StringParam("DDD")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(null, map);
assertThat(found, containsInAnyOrder(id1, id2, id3));
List<ResourcePersistentId> found = mySearchDao.search(null, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2, id3));
}
}
@ -133,8 +134,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// OR
{
@ -142,8 +143,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// AND
{
@ -152,8 +153,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// AND OR
{
@ -162,8 +163,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// Tag Contents
{
@ -171,8 +172,8 @@ public class FhirSearchDaoDstu2Test extends BaseJpaDstu2Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("div")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, empty());
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), empty());
}
}

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
@ -101,7 +102,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA");
parentC.addChild(childCA, RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
}
@ -132,7 +133,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
parentB.addChild(childI, RelationshipTypeEnum.ISA);
}
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
}
private void createExternalCsAndLocalVs() {
@ -167,7 +168,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
TermConcept beagle = new TermConcept(cs, "beagle").setDisplay("Beagle");
dogs.addChild(beagle, RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM,"SYSTEM NAME", "SYSTEM VERSION" , cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM,"SYSTEM NAME", "SYSTEM VERSION" , cs, table);
return codeSystem;
}
@ -686,7 +687,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
cs.setResource(table);
TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
cs.getConcepts().add(parentA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION" , cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION" , cs, table);
StringType code = new StringType("ParentA");
StringType system = new StringType("http://snomed.info/sct");

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
@ -43,6 +44,7 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.defaultString;
@ -214,12 +216,12 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
IIdType id2 = myObservationDao.create(o2, mySrd).getId();
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")), null);
assertThat(found, hasItem(id2.getIdPartAsLong()));
Set<ResourcePersistentId> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")), null);
assertThat(ResourcePersistentId.toLongList(found), hasItem(id2.getIdPartAsLong()));
}
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(found, not(hasItem(id2.getIdPartAsLong())));
Set<ResourcePersistentId> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(ResourcePersistentId.toLongList(found), not(hasItem(id2.getIdPartAsLong())));
}
}
@ -421,7 +423,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
String name = "profiles-resources";
ourLog.info("Uploading " + name);
String vsContents;
vsContents = IOUtils.toString(FhirResourceDaoDstu3Test.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/profile/" + name + ".xml"), "UTF-8");
vsContents = IOUtils.toString(FhirResourceDaoDstu3Test.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/profile/" + name + ".xml"), StandardCharsets.UTF_8);
bundle = myFhirCtx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
for (BundleEntryComponent i : bundle.getEntry()) {
@ -603,13 +605,13 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
* be fixed.
*/
assertEquals(org.hl7.fhir.dstu2.model.OperationOutcome.IssueSeverity.ERROR.toCode(), BaseHapiFhirDao.OO_SEVERITY_ERROR);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.ERROR.toCode(), BaseHapiFhirResourceDao.OO_SEVERITY_ERROR);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.ERROR.toCode(), BaseHapiFhirDao.OO_SEVERITY_ERROR);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.ERROR.toCode(), BaseHapiFhirDao.OO_SEVERITY_ERROR);
assertEquals(org.hl7.fhir.dstu2.model.OperationOutcome.IssueSeverity.INFORMATION.toCode(), BaseHapiFhirDao.OO_SEVERITY_INFO);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.INFORMATION.toCode(), BaseHapiFhirResourceDao.OO_SEVERITY_INFO);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.INFORMATION.toCode(), BaseHapiFhirDao.OO_SEVERITY_INFO);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.INFORMATION.toCode(), BaseHapiFhirDao.OO_SEVERITY_INFO);
assertEquals(org.hl7.fhir.dstu2.model.OperationOutcome.IssueSeverity.WARNING.toCode(), BaseHapiFhirDao.OO_SEVERITY_WARN);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.WARNING.toCode(), BaseHapiFhirResourceDao.OO_SEVERITY_WARN);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.WARNING.toCode(), BaseHapiFhirDao.OO_SEVERITY_WARN);
assertEquals(org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity.WARNING.toCode(), BaseHapiFhirDao.OO_SEVERITY_WARN);
}
@ -985,7 +987,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
@Test
public void testDeleteResource() {
int initialHistory = myPatientDao.history((Date) null, null, mySrd).size();
int initialHistory = myPatientDao.history(null, null, mySrd).size();
IIdType id1;
IIdType id2;
@ -1007,7 +1009,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
patient.addIdentifier().setSystem("ZZZZZZZ").setValue("ZZZZZZZZZ");
id2b = myPatientDao.update(patient, mySrd).getId();
}
ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[]{id1, id2, id2b});
ourLog.info("ID1:{} ID2:{} ID2b:{}", id1, id2, id2b);
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
@ -1028,7 +1030,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
// good
}
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
IBundleProvider history = myPatientDao.history(null, null, mySrd);
assertEquals(4 + initialHistory, history.size().intValue());
List<IBaseResource> resources = history.getResources(0, 4);
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) resources.get(0)));
@ -1400,7 +1402,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
}
// By type
history = myPatientDao.history((Date) null, null, mySrd);
history = myPatientDao.history(null, null, mySrd);
assertEquals(fullSize + 1, history.size().intValue());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
@ -1467,7 +1469,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
}
// By type
history = myPatientDao.history((Date) null, null, mySrd);
history = myPatientDao.history(null, null, mySrd);
assertEquals(fullSize + 1, history.size().intValue());
for (int i = 0; i < fullSize; i++) {
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
@ -1524,7 +1526,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
inPatient.getMeta().addProfile("http://example.com/1");
IIdType id = myPatientDao.create(inPatient, mySrd).getId().toUnqualifiedVersionless();
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
IBundleProvider history = myPatientDao.history(null, null, mySrd);
assertEquals(1, history.size().intValue());
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
assertEquals("version1", inPatient.getName().get(0).getFamily());
@ -1538,7 +1540,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
inPatient.getMeta().addProfile("http://example.com/2");
myPatientDao.metaAddOperation(id, inPatient.getMeta(), mySrd);
history = myPatientDao.history((Date) null, null, mySrd);
history = myPatientDao.history(null, null, mySrd);
assertEquals(1, history.size().intValue());
outPatient = (Patient) history.getResources(0, 1).get(0);
assertEquals("version1", inPatient.getName().get(0).getFamily());
@ -1554,7 +1556,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
inPatient.getName().get(0).setFamily("version2");
myPatientDao.update(inPatient, mySrd);
history = myPatientDao.history((Date) null, null, mySrd);
history = myPatientDao.history(null, null, mySrd);
assertEquals(2, history.size().intValue());
outPatient = (Patient) history.getResources(0, 2).get(0);
assertEquals("version2", outPatient.getName().get(0).getFamily());
@ -1582,9 +1584,9 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
IBundleProvider history = myPatientDao.history(id, null, null, mySrd);
List<IBaseResource> entries = history.getResources(0, 3);
ourLog.info(((IAnyResource) entries.get(0)).getIdElement() + " - " + ((IAnyResource) entries.get(0)).getMeta().getLastUpdated());
ourLog.info(((IAnyResource) entries.get(1)).getIdElement() + " - " + ((IAnyResource) entries.get(1)).getMeta().getLastUpdated());
ourLog.info(((IAnyResource) entries.get(2)).getIdElement() + " - " + ((IAnyResource) entries.get(2)).getMeta().getLastUpdated());
ourLog.info(entries.get(0).getIdElement() + " - " + entries.get(0).getMeta().getLastUpdated());
ourLog.info(entries.get(1).getIdElement() + " - " + entries.get(1).getMeta().getLastUpdated());
ourLog.info(entries.get(2).getIdElement() + " - " + entries.get(2).getMeta().getLastUpdated());
assertEquals(3, history.size().intValue());
assertEquals(id.withVersion("3"), entries.get(0).getIdElement());
@ -1648,7 +1650,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
// No since
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
IBundleProvider history = myPatientDao.history(null, null, mySrd);
assertEquals(1, history.size().intValue());
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
assertEquals("version1", inPatient.getName().get(0).getFamily());
@ -1999,7 +2001,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
"}\n";
//@formatter:on
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
@ -2050,7 +2052,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
dr01.setSubject(new Reference(patientId01));
IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId();
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[]{patientId01, patientId02, obsId01, obsId02, drId01});
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", patientId01, patientId02, obsId01, obsId02, drId01);
List<Observation> result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getIdPart())).setLoadSynchronous(true)));
assertEquals(1, result.size());
@ -2061,7 +2063,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
assertEquals(obsId02.getIdPart(), result.get(0).getIdElement().getIdPart());
result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam("999999999999")).setLoadSynchronous(true)));
;
assertEquals(0, result.size());
}
@ -2145,7 +2146,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
TokenParam value = new TokenParam("urn:system", "001testPersistSearchParams");
List<Patient> found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_IDENTIFIER, value).setLoadSynchronous(true)));
;
assertEquals(1, found.size());
assertEquals(id, found.get(0).getIdElement().getIdPartAsLong().longValue());
@ -2402,7 +2402,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
id1 = myPatientDao.create(patient, mySrd).getId();
Meta metaAdd = new Meta();
metaAdd.addTag().setSystem((String) null).setCode("Dog").setDisplay("Puppies");
metaAdd.addTag().setSystem(null).setCode("Dog").setDisplay("Puppies");
metaAdd.addSecurity().setSystem("seclabel:sys:1").setCode("seclabel:code:1").setDisplay("seclabel:dis:1");
metaAdd.addProfile("http://profile/1");
myPatientDao.metaAddOperation(id1, metaAdd, mySrd);
@ -2472,7 +2472,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
{
Meta metaDel = new Meta();
metaDel.addTag().setSystem((String) null).setCode("Dog");
metaDel.addTag().setSystem(null).setCode("Dog");
metaDel.addSecurity().setSystem("seclabel:sys:1").setCode("seclabel:code:1");
metaDel.addProfile("http://profile/1");
myPatientDao.metaDeleteOperation(id1, metaDel, mySrd);
@ -3192,7 +3192,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
@ -3371,7 +3371,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.api.MethodOutcome;
@ -41,7 +42,7 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
}
@Test
public void testCreateAndUpdateWithoutRequest() throws Exception {
public void testCreateAndUpdateWithoutRequest() {
String methodName = "testUpdateByUrl";
Patient p = new Patient();
@ -447,9 +448,9 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
p2.addName().setFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd).getId();
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
Set<ResourcePersistentId> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong()));
assertThat(ResourcePersistentId.toLongList(ids), contains(p1id.getIdPartAsLong()));
// Update the name
p1.getName().get(0).getGiven().get(0).setValue("testUpdateMaintainsSearchParamsDstu2BBB");
@ -503,7 +504,7 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
{
Patient p1 = myPatientDao.read(p1id, mySrd);
List<Coding> tagList = p1.getMeta().getTag();
Set<String> secListValues = new HashSet<String>();
Set<String> secListValues = new HashSet<>();
for (Coding next : tagList) {
secListValues.add(next.getSystemElement().getValue() + "|" + next.getCodeElement().getValue());
}
@ -528,7 +529,7 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
Patient patient = new Patient();
patient.addName().setFamily(name);
List<IdType> tl = new ArrayList<IdType>();
List<IdType> tl = new ArrayList<>();
tl.add(new IdType("http://foo/bar"));
patient.getMeta().getProfile().addAll(tl);
@ -549,7 +550,7 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
patient.setId(id);
patient.addName().setFamily(name);
List<IdType> tl = new ArrayList<IdType>();
List<IdType> tl = new ArrayList<>();
tl.add(new IdType("http://foo/baz"));
patient.getMeta().getProfile().clear();
patient.getMeta().getProfile().addAll(tl);

View File

@ -6,6 +6,7 @@ import static org.junit.Assert.assertThat;
import java.util.List;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import org.hl7.fhir.dstu3.model.Organization;
import org.hl7.fhir.dstu3.model.Patient;
import org.junit.AfterClass;
@ -65,8 +66,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// OR
{
@ -74,8 +75,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// AND
{
@ -84,8 +85,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// AND OR
{
@ -94,8 +95,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// All Resource Types
{
@ -103,8 +104,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")).addOr(new StringParam("DDD")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(null, map);
assertThat(found, containsInAnyOrder(id1, id2, id3));
List<ResourcePersistentId> found = mySearchDao.search(null, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2, id3));
}
}
@ -138,8 +139,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// OR
{
@ -147,8 +148,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// AND
{
@ -157,8 +158,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// AND OR
{
@ -167,8 +168,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// Tag Contents
{
@ -176,8 +177,8 @@ public class FhirSearchDaoDstu3Test extends BaseJpaDstu3Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("div")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, empty());
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), empty());
}
}

View File

@ -22,7 +22,7 @@ import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
import ca.uhn.fhir.jpa.search.warm.ICacheWarmingSvc;
import ca.uhn.fhir.jpa.searchparam.registry.BaseSearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionRegistry;
import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl;
import ca.uhn.fhir.jpa.term.TermDeferredStorageSvcImpl;
@ -277,7 +277,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
@Qualifier("mySearchParameterDaoR4")
protected IFhirResourceDao<SearchParameter> mySearchParameterDao;
@Autowired
protected BaseSearchParamRegistry mySearchParamRegistry;
protected SearchParamRegistryImpl mySearchParamRegistry;
@Autowired
protected IStaleSearchDeletingSvc myStaleSearchDeletingSvc;
@Autowired

View File

@ -19,6 +19,7 @@ import org.junit.Test;
import java.util.List;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.*;
@ -43,7 +44,7 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test {
myObservationDao.create(o, mySrd);
fail();
} catch (InvalidRequestException e) {
assertEquals("Resource Patient/FOO not found, specified in path: Observation.subject", e.getMessage());
assertThat(e.getMessage(), startsWith("Resource Patient/FOO not found, specified in path: Observation.subject"));
}
}
@ -98,7 +99,7 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test {
myObservationDao.update(o, mySrd);
fail();
} catch (InvalidRequestException e) {
assertEquals("Resource Patient/FOO not found, specified in path: Observation.subject", e.getMessage());
assertThat(e.getMessage(), startsWith("Resource Patient/FOO not found, specified in path: Observation.subject"));
}
}

View File

@ -32,12 +32,14 @@ public class FhirResourceDaoR4DeleteTest extends BaseJpaR4Test {
runInTransaction(()->{
ResourceTable resourceTable = myResourceTableDao.findById(id.getIdPartAsLong()).get();
assertNotNull(resourceTable.getDeleted());
assertTrue(resourceTable.isDeleted());
});
// Current version should be marked as deleted
runInTransaction(()->{
ResourceHistoryTable resourceTable = myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(id.getIdPartAsLong(), 1);
assertNull(resourceTable.getDeleted());
assertNotNull(resourceTable.getPersistentId());
});
runInTransaction(()->{
ResourceHistoryTable resourceTable = myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(id.getIdPartAsLong(), 2);

View File

@ -3867,6 +3867,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
result = myValueSetDao.search(new SearchParameterMap().setLoadSynchronous(true).add(ValueSet.SP_URL, new UriParam("http://hl7.org/fhir/ValueSet/FOOOOOO")));
assertThat(toUnqualifiedVersionlessIds(result), empty());
}
@Test

View File

@ -8,6 +8,7 @@ import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
@ -181,7 +182,7 @@ public class FhirResourceDaoR4SearchWithElasticSearchTest extends BaseJpaTest {
TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA");
parentC.addChild(childCA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
}
@ -199,7 +200,7 @@ public class FhirResourceDaoR4SearchWithElasticSearchTest extends BaseJpaTest {
}
private ArrayList<String> toCodesContains(List<ValueSet.ValueSetExpansionContainsComponent> theContains) {
ArrayList<String> retVal = new ArrayList<String>();
ArrayList<String> retVal = new ArrayList<>();
for (ValueSet.ValueSetExpansionContainsComponent next : theContains) {
retVal.add(next.getCode());
}

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
@ -95,7 +96,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA");
parentC.addChild(childCA, RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
}
@ -131,7 +132,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
TermConcept beagle = new TermConcept(cs, "beagle").setDisplay("Beagle");
dogs.addChild(beagle, RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
}
@ -162,7 +163,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
parentB.addChild(childI, RelationshipTypeEnum.ISA);
}
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
}
private void createLocalCsAndVs() {
@ -474,7 +475,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
concept = new TermConcept(cs, "LA9999-7");
cs.getConcepts().add(concept);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
ValueSet valueSet = new ValueSet();
valueSet.setUrl(URL_MY_VALUE_SET);
@ -801,7 +802,7 @@ public class FhirResourceDaoR4TerminologyTest extends BaseJpaR4Test {
cs.setResource(table);
TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
cs.getConcepts().add(parentA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION" , cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), "http://snomed.info/sct", "Snomed CT", "SYSTEM VERSION" , cs, table);
StringType code = new StringType("ParentA");
StringType system = new StringType("http://snomed.info/sct");

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
@ -317,12 +318,12 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
IIdType id2 = myObservationDao.create(o2, mySrd).getId();
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")), null);
assertThat(found, hasItem(id2.getIdPartAsLong()));
Set<ResourcePersistentId> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")), null);
assertThat(ResourcePersistentId.toLongList(found), hasItem(id2.getIdPartAsLong()));
}
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(found, not(hasItem(id2.getIdPartAsLong())));
Set<ResourcePersistentId> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(ResourcePersistentId.toLongList(found), not(hasItem(id2.getIdPartAsLong())));
}
}
@ -2297,7 +2298,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
"}\n";
//@formatter:on
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
@ -3592,7 +3593,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
@ -3771,7 +3772,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
Set<ResourcePersistentId> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -568,9 +569,9 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
p2.addName().setFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd).getId();
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
Set<ResourcePersistentId> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong()));
assertThat(ResourcePersistentId.toLongList(ids), contains(p1id.getIdPartAsLong()));
// Update the name
p1.getName().get(0).getGiven().get(0).setValue("testUpdateMaintainsSearchParamsDstu2BBB");

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.param.StringAndListParam;
@ -66,8 +67,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// OR
{
@ -75,8 +76,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// AND
{
@ -85,8 +86,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// AND OR
{
@ -95,8 +96,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// All Resource Types
{
@ -104,8 +105,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")).addOr(new StringParam("DDD")));
map.add(Constants.PARAM_CONTENT, content);
List<Long> found = mySearchDao.search(null, map);
assertThat(found, containsInAnyOrder(id1, id2, id3));
List<ResourcePersistentId> found = mySearchDao.search(null, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2, id3));
}
}
@ -139,8 +140,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// OR
{
@ -148,8 +149,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("AAAS")).addOr(new StringParam("AAAB")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// AND
{
@ -158,8 +159,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1));
}
// AND OR
{
@ -168,8 +169,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("CCC")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, containsInAnyOrder(id1, id2));
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), containsInAnyOrder(id1, id2));
}
// Tag Contents
{
@ -177,8 +178,8 @@ public class FhirSearchDaoR4Test extends BaseJpaR4Test {
content.addAnd(new StringOrListParam().addOr(new StringParam("div")));
map.add(Constants.PARAM_TEXT, content);
List<Long> found = mySearchDao.search(resourceName, map);
assertThat(found, empty());
List<ResourcePersistentId> found = mySearchDao.search(resourceName, map);
assertThat(ResourcePersistentId.toLongList(found), empty());
}
}

View File

@ -3,8 +3,12 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
@ -13,7 +17,15 @@ import ca.uhn.fhir.util.TestUtil;
import com.google.common.collect.Sets;
import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport;
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Consent;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Quantity;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.SearchParameter;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@ -21,7 +33,13 @@ import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
@ -32,7 +50,7 @@ public class SearchParamExtractorR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(SearchParamExtractorR4Test.class);
private static FhirContext ourCtx = FhirContext.forR4();
private static IValidationSupport ourValidationSupport;
private ISearchParamRegistry mySearchParamRegistry;
private MySearchParamRegistry mySearchParamRegistry;
@Before
public void before() {
@ -77,10 +95,11 @@ public class SearchParamExtractorR4Test {
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), ourCtx, ourValidationSupport, mySearchParamRegistry);
RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam("Encounter", "location");
assertNotNull(param);
List<PathAndRef> links = extractor.extractResourceLinks(enc, param);
ISearchParamExtractor.SearchParamSet<PathAndRef> links = extractor.extractResourceLinks(enc);
assertEquals(1, links.size());
assertEquals("Encounter.location.location", links.get(0).getPath());
assertEquals("Location/123", ((Reference) links.get(0).getRef()).getReference());
assertEquals("location", links.iterator().next().getSearchParamName());
assertEquals("Encounter.location.location", links.iterator().next().getPath());
assertEquals("Location/123", ((Reference) links.iterator().next().getRef()).getReference());
}
@Test
@ -91,10 +110,10 @@ public class SearchParamExtractorR4Test {
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), ourCtx, ourValidationSupport, mySearchParamRegistry);
RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam("Consent", Consent.SP_SOURCE_REFERENCE);
assertNotNull(param);
List<PathAndRef> links = extractor.extractResourceLinks(consent, param);
ISearchParamExtractor.SearchParamSet<PathAndRef> links = extractor.extractResourceLinks(consent);
assertEquals(1, links.size());
assertEquals("Consent.source", links.get(0).getPath());
assertEquals("Consent/999", ((Reference) links.get(0).getRef()).getReference());
assertEquals("Consent.source", links.iterator().next().getPath());
assertEquals("Consent/999", ((Reference) links.iterator().next().getRef()).getReference());
}
@ -103,13 +122,15 @@ public class SearchParamExtractorR4Test {
String path = "Patient.extension('http://patext').value.as(Reference)";
RuntimeSearchParam sp = new RuntimeSearchParam("extpat", "Patient SP", path, RestSearchParameterTypeEnum.REFERENCE, new HashSet<>(), Sets.newHashSet("Patient"), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE);
mySearchParamRegistry.addSearchParam(sp);
Patient patient = new Patient();
patient.addExtension("http://patext", new Reference("Organization/AAA"));
SearchParamExtractorR4 extractor = new SearchParamExtractorR4(new ModelConfig(), ourCtx, ourValidationSupport, mySearchParamRegistry);
List<PathAndRef> links = extractor.extractResourceLinks(patient, sp);
ISearchParamExtractor.SearchParamSet<PathAndRef> links = extractor.extractResourceLinks(patient);
assertEquals(1, links.size());
}
@Test
@ -129,6 +150,10 @@ public class SearchParamExtractorR4Test {
}
private static class MySearchParamRegistry implements ISearchParamRegistry {
private List<RuntimeSearchParam> myExtraSearchParams = new ArrayList<>();
@Override
public void forceRefresh() {
// nothing
@ -158,9 +183,17 @@ public class SearchParamExtractorR4Test {
sps.put(nextSp.getName(), nextSp);
}
for (RuntimeSearchParam next : myExtraSearchParams) {
sps.put(next.getName(), next);
}
return sps;
}
public void addSearchParam(RuntimeSearchParam theSearchParam) {
myExtraSearchParams.add(theSearchParam);
}
@Override
public List<JpaRuntimeSearchParam> getActiveUniqueSearchParams(String theResourceName, Set<String> theParamNames) {
throw new UnsupportedOperationException();

View File

@ -19,7 +19,7 @@ import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
import ca.uhn.fhir.jpa.search.warm.ICacheWarmingSvc;
import ca.uhn.fhir.jpa.searchparam.registry.BaseSearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionRegistry;
import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl;
import ca.uhn.fhir.jpa.term.TermDeferredStorageSvcImpl;
@ -261,7 +261,7 @@ public abstract class BaseJpaR5Test extends BaseJpaTest {
@Qualifier("mySearchParameterDaoR5")
protected IFhirResourceDao<SearchParameter> mySearchParameterDao;
@Autowired
protected BaseSearchParamRegistry mySearchParamRegistry;
protected SearchParamRegistryImpl mySearchParamRegistry;
@Autowired
protected IStaleSearchDeletingSvc myStaleSearchDeletingSvc;
@Autowired

View File

@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryDstu3;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainDstu3;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.parser.StrictErrorHandler;
@ -58,7 +58,7 @@ public abstract class BaseResourceProviderDstu3Test extends BaseJpaDstu3Test {
protected static RestfulServer ourRestServer;
protected static String ourServerBase;
protected static GenericWebApplicationContext ourWebApplicationContext;
protected static SearchParamRegistryDstu3 ourSearchParamRegistry;
protected static SearchParamRegistryImpl ourSearchParamRegistry;
protected static DatabaseBackedPagingProvider ourPagingProvider;
protected static ISearchCoordinatorSvc ourSearchCoordinatorSvc;
private static Server ourServer;
@ -153,7 +153,7 @@ public abstract class BaseResourceProviderDstu3Test extends BaseJpaDstu3Test {
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(subsServletHolder.getServlet().getServletConfig().getServletContext());
myValidationSupport = wac.getBean(JpaValidationSupportChainDstu3.class);
ourSearchCoordinatorSvc = wac.getBean(ISearchCoordinatorSvc.class);
ourSearchParamRegistry = wac.getBean(SearchParamRegistryDstu3.class);
ourSearchParamRegistry = wac.getBean(SearchParamRegistryImpl.class);
ourSubscriptionTriggeringProvider = wac.getBean(SubscriptionTriggeringProvider.class);
myFhirCtx.getRestfulClientFactory().setSocketTimeout(5000000);

View File

@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoR4TerminologyTest;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -151,7 +152,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3
code.addPropertyString("HELLO", "12345-2");
cs.getConcepts().add(code);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getPersistentId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
});
}
@ -849,7 +850,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3
TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B");
cs.getConcepts().add(parentB);
theTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
theTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem;
}

View File

@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.provider.GraphQLProvider;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryR4;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.subscription.SubscriptionMatcherInterceptor;
import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionLoader;
import ca.uhn.fhir.jpa.util.ResourceCountCache;
@ -61,7 +61,7 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test {
protected static int ourPort;
protected static RestfulServer ourRestServer;
protected static String ourServerBase;
protected static SearchParamRegistryR4 ourSearchParamRegistry;
protected static SearchParamRegistryImpl ourSearchParamRegistry;
private static DatabaseBackedPagingProvider ourPagingProvider;
protected static ISearchCoordinatorSvc mySearchCoordinatorSvc;
private static GenericWebApplicationContext ourWebApplicationContext;
@ -163,7 +163,7 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test {
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(subsServletHolder.getServlet().getServletConfig().getServletContext());
myValidationSupport = wac.getBean(JpaValidationSupportChainR4.class);
mySearchCoordinatorSvc = wac.getBean(ISearchCoordinatorSvc.class);
ourSearchParamRegistry = wac.getBean(SearchParamRegistryR4.class);
ourSearchParamRegistry = wac.getBean(SearchParamRegistryImpl.class);
ourSubscriptionMatcherInterceptor = wac.getBean(SubscriptionMatcherInterceptor.class);
ourSubscriptionMatcherInterceptor.start();

View File

@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.entity.ResourceReindexJobEntity;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -37,13 +38,16 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.in;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@ -59,15 +63,14 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
@After
public void after() throws Exception {
super.after();
myModelConfig.setDefaultSearchParamsCanBeOverridden(new ModelConfig().isDefaultSearchParamsCanBeOverridden());
myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
}
@Override
public void before() throws Exception {
super.before();
myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
}
@Override
@ -462,8 +465,6 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
Interceptor interceptor = new Interceptor();
myInterceptorRegistry.registerInterceptor(interceptor);
try {
myDaoConfig.setAllowContainsSearches(true);
// Add a custom search parameter
SearchParameter fooSp = new SearchParameter();
fooSp.addBase("Questionnaire");
@ -520,6 +521,8 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
ids.add(myQuestionnaireDao.create(q).getId().getIdPartAsLong());
}
myCaptureQueriesListener.clear();
int foundCount = 0;
Bundle bundle = null;
List<Long> actualIds = new ArrayList<>();
@ -543,17 +546,42 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
} while (bundle.getLink("next") != null);
String queries = " * " + myCaptureQueriesListener
.getSelectQueries()
.stream()
.map(t->t.getSql(true, false))
.collect(Collectors.joining("\n * "));
ourLog.info("Found: {}", found);
runInTransaction(() -> {
List currentResults = myEntityManager.createNativeQuery("select distinct resourceta0_.RES_ID as col_0_0_ from HFJ_RESOURCE resourceta0_ left outer join HFJ_SPIDX_STRING myparamsst1_ on resourceta0_.RES_ID=myparamsst1_.RES_ID where myparamsst1_.HASH_NORM_PREFIX='5901791607832193956' and (myparamsst1_.SP_VALUE_NORMALIZED like 'SECTION%') limit '500'") .getResultList();
List currentResources = myEntityManager.createNativeQuery("select resourceta0_.RES_ID as col_0_0_ from HFJ_RESOURCE resourceta0_") .getResultList();
List<Search> searches = mySearchEntityDao.findAll();
assertEquals(1, searches.size());
Search search = searches.get(0);
String message = "\nWanted: " + (ids) + "\n" +
"Actual: " + (actualIds) + "\n" +
"Found : " + (found) + "\n" +
search.toString();
String message = "\nWanted : " + (ids) + "\n" +
"Actual : " + (actualIds) + "\n" +
"Found : " + (found) + "\n" +
"Current: " + currentResults + "\n" +
"Current: " + currentResources + "\n" +
search.toString() +
"\nQueries :\n" + queries;
for (Long next :ids) {
if (!actualIds.contains(next)) {
List<ResourceIndexedSearchParamString> indexes = myResourceIndexedSearchParamStringDao
.findAll()
.stream()
.filter(t->t.getResourcePid().equals(next))
.collect(Collectors.toList());
message += "\n\nResource " + next + " has prefixes:\n * " + indexes.stream().map(t->t.toString()).collect(Collectors.joining("\n * "));
break;
}
}
assertEquals(message, 200, search.getNumFound());
assertEquals(message, 200, search.getTotalCount().intValue());
assertEquals(message, SearchStatusEnum.FINISHED, search.getStatus());

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -1053,7 +1054,7 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test {
TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B");
cs.getConcepts().add(parentB);
theTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
theTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
return codeSystem;
}

View File

@ -14,6 +14,7 @@ import ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl;
import ca.uhn.fhir.rest.gclient.IClientExecutable;
import ca.uhn.fhir.rest.gclient.IQuery;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.test.utilities.UnregisterScheduledProcessor;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.r4.model.Bundle;
@ -24,6 +25,7 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.util.AopTestUtils;
import java.util.Date;
@ -33,6 +35,11 @@ import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@TestPropertySource(properties = {
// Since scheduled tasks can cause searches, which messes up the
// value returned by SearchBuilder.getLastHandlerMechanismForUnitTest()
UnregisterScheduledProcessor.SCHEDULING_DISABLED_EQUALS_TRUE
})
public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StaleSearchDeletingSvcR4Test.class);

View File

@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.provider.GraphQLProvider;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryR5;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.subscription.SubscriptionMatcherInterceptor;
import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionLoader;
import ca.uhn.fhir.jpa.util.ResourceCountCache;
@ -61,7 +61,7 @@ public abstract class BaseResourceProviderR5Test extends BaseJpaR5Test {
protected static int ourPort;
protected static RestfulServer ourRestServer;
protected static String ourServerBase;
protected static SearchParamRegistryR5 ourSearchParamRegistry;
protected static SearchParamRegistryImpl ourSearchParamRegistry;
private static DatabaseBackedPagingProvider ourPagingProvider;
protected static ISearchCoordinatorSvc mySearchCoordinatorSvc;
private static GenericWebApplicationContext ourWebApplicationContext;
@ -164,7 +164,7 @@ public abstract class BaseResourceProviderR5Test extends BaseJpaR5Test {
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(subsServletHolder.getServlet().getServletConfig().getServletContext());
myValidationSupport = wac.getBean(JpaValidationSupportChainR5.class);
mySearchCoordinatorSvc = wac.getBean(ISearchCoordinatorSvc.class);
ourSearchParamRegistry = wac.getBean(SearchParamRegistryR5.class);
ourSearchParamRegistry = wac.getBean(SearchParamRegistryImpl.class);
ourSubscriptionMatcherInterceptor = wac.getBean(SubscriptionMatcherInterceptor.class);
ourSubscriptionMatcherInterceptor.start();

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
@ -1063,7 +1064,7 @@ public class ResourceProviderR5ValueSetTest extends BaseResourceProviderR5Test {
TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B");
cs.getConcepts().add(parentB);
theTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
theTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION" , cs, table);
return codeSystem;
}

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc;
@ -110,19 +111,19 @@ public class SearchCoordinatorSvcImplTest {
}).when(myCallingDao).injectDependenciesIntoBundleProvider(any(PersistedJpaBundleProvider.class));
}
private List<Long> createPidSequence(int to) {
List<Long> pids = new ArrayList<>();
private List<ResourcePersistentId> createPidSequence(int to) {
List<ResourcePersistentId> pids = new ArrayList<>();
for (long i = 10; i < to; i++) {
pids.add(i);
pids.add(new ResourcePersistentId(i));
}
return pids;
}
private Answer<Void> loadPids() {
return theInvocation -> {
List<Long> pids = (List<Long>) theInvocation.getArguments()[0];
List<ResourcePersistentId> pids = (List<ResourcePersistentId>) theInvocation.getArguments()[0];
List<IBaseResource> resources = (List<IBaseResource>) theInvocation.getArguments()[2];
for (Long nextPid : pids) {
for (ResourcePersistentId nextPid : pids) {
Patient pt = new Patient();
pt.setId(nextPid.toString());
resources.add(pt);
@ -136,7 +137,7 @@ public class SearchCoordinatorSvcImplTest {
SearchParameterMap params = new SearchParameterMap();
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(800);
List<ResourcePersistentId> pids = createPidSequence(800);
IResultIterator iter = new FailAfterNIterator(new SlowIterator(pids.iterator(), 2), 300);
when(mySearchBuilder.createQuery(same(params), any(), any())).thenReturn(iter);
@ -154,10 +155,10 @@ public class SearchCoordinatorSvcImplTest {
@Test
public void testAsyncSearchLargeResultSetBigCountSameCoordinator() {
List<Long> allResults = new ArrayList<>();
List<ResourcePersistentId> allResults = new ArrayList<>();
doAnswer(t -> {
List<Long> oldResults = t.getArgument(1, List.class);
List<Long> newResults = t.getArgument(2, List.class);
List<ResourcePersistentId> oldResults = t.getArgument(1, List.class);
List<ResourcePersistentId> newResults = t.getArgument(2, List.class);
ourLog.info("Saving {} new results - have {} old results", newResults.size(), oldResults.size());
assertEquals(allResults.size(), oldResults.size());
allResults.addAll(newResults);
@ -168,13 +169,13 @@ public class SearchCoordinatorSvcImplTest {
SearchParameterMap params = new SearchParameterMap();
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(800);
List<ResourcePersistentId> pids = createPidSequence(800);
SlowIterator iter = new SlowIterator(pids.iterator(), 1);
when(mySearchBuilder.createQuery(any(), any(), any())).thenReturn(iter);
doAnswer(loadPids()).when(mySearchBuilder).loadResourcesByPid(any(Collection.class), any(Collection.class), any(List.class), anyBoolean(), any());
when(mySearchResultCacheSvc.fetchResultPids(any(), anyInt(), anyInt())).thenAnswer(t -> {
List<Long> returnedValues = iter.getReturnedValues();
List<ResourcePersistentId> returnedValues = iter.getReturnedValues();
int offset = t.getArgument(1, Integer.class);
int end = t.getArgument(2, Integer.class);
end = Math.min(end, returnedValues.size());
@ -218,8 +219,8 @@ public class SearchCoordinatorSvcImplTest {
verify(mySearchCacheSvc, atLeastOnce()).save(searchCaptor.capture());
assertEquals(790, allResults.size());
assertEquals(10, allResults.get(0).longValue());
assertEquals(799, allResults.get(789).longValue());
assertEquals(10, allResults.get(0).getIdAsLong().longValue());
assertEquals(799, allResults.get(789).getIdAsLong().longValue());
myExpectedNumberOfSearchBuildersCreated = 4;
}
@ -274,7 +275,7 @@ public class SearchCoordinatorSvcImplTest {
SearchParameterMap params = new SearchParameterMap();
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(800);
List<ResourcePersistentId> pids = createPidSequence(800);
SlowIterator iter = new SlowIterator(pids.iterator(), 2);
when(mySearchBuilder.createQuery(same(params), any(), any())).thenReturn(iter);
@ -298,7 +299,7 @@ public class SearchCoordinatorSvcImplTest {
SearchParameterMap params = new SearchParameterMap();
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(800);
List<ResourcePersistentId> pids = createPidSequence(800);
SlowIterator iter = new SlowIterator(pids.iterator(), 500);
when(mySearchBuilder.createQuery(same(params), any(), any())).thenReturn(iter);
@ -342,7 +343,7 @@ public class SearchCoordinatorSvcImplTest {
SearchParameterMap params = new SearchParameterMap();
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(800);
List<ResourcePersistentId> pids = createPidSequence(800);
IResultIterator iter = new SlowIterator(pids.iterator(), 2);
when(mySearchBuilder.createQuery(same(params), any(), any())).thenReturn(iter);
when(mySearchCacheSvc.save(any())).thenAnswer(t -> t.getArguments()[0]);
@ -387,7 +388,7 @@ public class SearchCoordinatorSvcImplTest {
SearchParameterMap params = new SearchParameterMap();
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(100);
List<ResourcePersistentId> pids = createPidSequence(100);
SlowIterator iter = new SlowIterator(pids.iterator(), 2);
when(mySearchBuilder.createQuery(same(params), any(), any())).thenReturn(iter);
@ -435,9 +436,10 @@ public class SearchCoordinatorSvcImplTest {
}
when(mySearchResultCacheSvc.fetchResultPids(any(Search.class), anyInt(), anyInt())).thenAnswer(theInvocation -> {
ArrayList<Long> results = new ArrayList<>();
ArrayList<ResourcePersistentId> results = new ArrayList<>();
for (long i = theInvocation.getArgument(1, Integer.class); i < theInvocation.getArgument(2, Integer.class); i++) {
results.add(i + 10L);
Long nextPid = i + 10L;
results.add(new ResourcePersistentId(nextPid));
}
return results;
@ -470,7 +472,7 @@ public class SearchCoordinatorSvcImplTest {
params.setLoadSynchronous(true);
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(800);
List<ResourcePersistentId> pids = createPidSequence(800);
when(mySearchBuilder.createQuery(same(params), any(), any())).thenReturn(new ResultIterator(pids.iterator()));
doAnswer(loadPids()).when(mySearchBuilder).loadResourcesByPid(any(Collection.class), any(Collection.class), any(List.class), anyBoolean(), any());
@ -491,7 +493,7 @@ public class SearchCoordinatorSvcImplTest {
params.setLoadSynchronousUpTo(100);
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(800);
List<ResourcePersistentId> pids = createPidSequence(800);
when(mySearchBuilder.createQuery(same(params), any(), nullable(RequestDetails.class))).thenReturn(new ResultIterator(pids.iterator()));
pids = createPidSequence(110);
@ -563,7 +565,7 @@ public class SearchCoordinatorSvcImplTest {
}
public static class FailAfterNIterator extends BaseIterator<Long> implements IResultIterator {
public static class FailAfterNIterator extends BaseIterator<ResourcePersistentId> implements IResultIterator {
private int myCount;
private IResultIterator myWrap;
@ -579,7 +581,7 @@ public class SearchCoordinatorSvcImplTest {
}
@Override
public Long next() {
public ResourcePersistentId next() {
myCount--;
if (myCount == 0) {
throw new NullPointerException("FAILED");
@ -598,11 +600,11 @@ public class SearchCoordinatorSvcImplTest {
}
}
public static class ResultIterator extends BaseIterator<Long> implements IResultIterator {
public static class ResultIterator extends BaseIterator<ResourcePersistentId> implements IResultIterator {
private final Iterator<Long> myWrap;
private final Iterator<ResourcePersistentId> myWrap;
ResultIterator(Iterator<Long> theWrap) {
ResultIterator(Iterator<ResourcePersistentId> theWrap) {
myWrap = theWrap;
}
@ -612,7 +614,7 @@ public class SearchCoordinatorSvcImplTest {
}
@Override
public Long next() {
public ResourcePersistentId next() {
return myWrap.next();
}
@ -633,22 +635,22 @@ public class SearchCoordinatorSvcImplTest {
* <p>
* Don't use it in real code!
*/
public static class SlowIterator extends BaseIterator<Long> implements IResultIterator {
public static class SlowIterator extends BaseIterator<ResourcePersistentId> implements IResultIterator {
private static final Logger ourLog = LoggerFactory.getLogger(SlowIterator.class);
private final IResultIterator myResultIteratorWrap;
private int myDelay;
private Iterator<Long> myWrap;
private List<Long> myReturnedValues = new ArrayList<>();
private Iterator<ResourcePersistentId> myWrap;
private List<ResourcePersistentId> myReturnedValues = new ArrayList<>();
private AtomicInteger myCountReturned = new AtomicInteger(0);
SlowIterator(Iterator<Long> theWrap, int theDelay) {
SlowIterator(Iterator<ResourcePersistentId> theWrap, int theDelay) {
myWrap = theWrap;
myDelay = theDelay;
myResultIteratorWrap = null;
}
List<Long> getReturnedValues() {
List<ResourcePersistentId> getReturnedValues() {
return myReturnedValues;
}
@ -666,13 +668,13 @@ public class SearchCoordinatorSvcImplTest {
}
@Override
public Long next() {
public ResourcePersistentId next() {
try {
Thread.sleep(myDelay);
} catch (InterruptedException e) {
// ignore
}
Long retVal = myWrap.next();
ResourcePersistentId retVal = myWrap.next();
myReturnedValues.add(retVal);
myCountReturned.incrementAndGet();
return retVal;

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeSystem;
@ -90,7 +91,7 @@ public abstract class BaseTermR4Test extends BaseJpaR4Test {
TermConcept parentB = new TermConcept(cs, "ParentB");
cs.getConcepts().add(parentB);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return id;
}

View File

@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
@ -97,7 +98,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
TermConcept parentB = new TermConcept(cs, "ParentB");
cs.getConcepts().add(parentB);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return id;
}
@ -116,7 +117,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
TermConcept parentA = new TermConcept(cs, "CS2");
cs.getConcepts().add(parentA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), CS_URL_2, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL_2, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
}
@ -185,7 +186,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
code2.getDisplay());
cs.getConcepts().add(code4);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), LOINC_URI, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), LOINC_URI, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
});
}
@ -201,7 +202,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
// Update
cs = new TermCodeSystemVersion();
@ -210,7 +211,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
id = myCodeSystemDao.update(codeSystem, null, true, true, mySrd).getId().toUnqualified();
table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalArgumentException::new);
cs.setResource(table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getPersistentId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
// Try to update to a different resource
codeSystem = new CodeSystem();
@ -1780,7 +1781,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
child.addChild(parent, RelationshipTypeEnum.ISA);
try {
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getId(), "http://foo", "SYSTEM NAME", "SYSTEM VERSION", cs, table);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(table.getPersistentId(), "http://foo", "SYSTEM NAME", "SYSTEM VERSION", cs, table);
fail();
} catch (InvalidRequestException e) {
assertEquals("CodeSystem contains circular reference around code parent", e.getMessage());
@ -1905,7 +1906,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
runInTransaction(() -> {
ResourceTable resTable = myEntityManager.find(ResourceTable.class, csId.getIdPartAsLong());
version.setResource(resTable);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(csId.getIdPartAsLong(), cs.getUrl(), "My System", "SYSTEM VERSION", version, resTable);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(csId.getIdPartAsLong()), cs.getUrl(), "My System", "SYSTEM VERSION", version, resTable);
});
org.hl7.fhir.dstu3.model.ValueSet vs = new org.hl7.fhir.dstu3.model.ValueSet();

View File

@ -0,0 +1,40 @@
package ca.uhn.fhir.jpa.model.cross;
/*-
* #%L
* HAPI FHIR Model
* %%
* Copyright (C) 2014 - 2019 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.hl7.fhir.instance.model.api.IIdType;
import java.util.Date;
public interface IBasePersistedResource {
IIdType getIdDt();
boolean isDeleted();
/**
* If the resource is deleted, returns the date/time that the resource was deleted at. Otherwie, returns <code>null</code>
*/
Date getDeleted();
ResourcePersistentId getPersistentId();
}

View File

@ -0,0 +1,88 @@
package ca.uhn.fhir.jpa.model.cross;
/*-
* #%L
* HAPI FHIR Model
* %%
* Copyright (C) 2014 - 2019 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.util.ObjectUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* This class is an abstraction for however primary keys are stored in the underlying storage engine. This might be
* a Long, a String, or something else.
*/
public class ResourcePersistentId {
private Object myId;
public ResourcePersistentId(Object theId) {
myId = theId;
}
@Override
public boolean equals(Object theO) {
if (!(theO instanceof ResourcePersistentId)) {
return false;
}
ResourcePersistentId that = (ResourcePersistentId) theO;
return ObjectUtil.equals(myId, that.myId);
}
@Override
public int hashCode() {
return myId.hashCode();
}
public Object getId() {
return myId;
}
public void setId(Object theId) {
myId = theId;
}
public Long getIdAsLong() {
return (Long) myId;
}
@Override
public String toString() {
return myId.toString();
}
public static List<Long> toLongList(Collection<ResourcePersistentId> thePids) {
List<Long> retVal = new ArrayList<>(thePids.size());
for (ResourcePersistentId next : thePids) {
retVal.add(next.getIdAsLong());
}
return retVal;
}
public static List<ResourcePersistentId> fromLongList(List<Long> theResultList) {
List<ResourcePersistentId> retVal = new ArrayList<>(theResultList.size());
for (Long next : theResultList) {
retVal.add(new ResourcePersistentId(next));
}
return retVal;
}
}

View File

@ -21,6 +21,8 @@ package ca.uhn.fhir.jpa.model.entity;
*/
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.api.Constants;
@ -31,7 +33,7 @@ import java.util.Collection;
import java.util.Date;
@MappedSuperclass
public abstract class BaseHasResource implements IBaseResourceEntity {
public abstract class BaseHasResource implements IBaseResourceEntity, IBasePersistedResource {
@Column(name = "RES_DELETED_AT", nullable = true)
@Temporal(TemporalType.TIMESTAMP)
@ -85,10 +87,6 @@ public abstract class BaseHasResource implements IBaseResourceEntity {
return cloneDate(myDeleted);
}
public void setDeleted(Date theDate) {
myDeleted = theDate;
}
@Override
public FhirVersionEnum getFhirVersion() {
return myFhirVersion;
@ -121,6 +119,15 @@ public abstract class BaseHasResource implements IBaseResourceEntity {
}
}
@Override
public boolean isDeleted() {
return myDeleted != null;
}
public void setDeleted(Date theDate) {
myDeleted = theDate;
}
@Override
public InstantDt getPublished() {
if (myPublished != null) {

View File

@ -61,6 +61,13 @@ public class ModelConfig {
private boolean mySubscriptionMatchingEnabled = true;
private String myWebsocketContextPath = DEFAULT_WEBSOCKET_CONTEXT_PATH;
/**
* Constructor
*/
public ModelConfig() {
super();
}
/**
* If set to {@code true} the default search params (i.e. the search parameters that are
* defined by the FHIR specification itself) may be overridden by uploading search

Some files were not shown because too many files have changed in this diff Show More