4244 - Deprecate usages of ResourcePersitentId in jpa (#4245)

* init rev

* id to jpa and mongo id

* 3444 - replaced methods and constructors of ResourcePersistentId with child constructors and methods

* 3444 - replaced methods and constructors of ResourcePersistentId with child constructors and methods

* fixed conflicts, pulled from master

* fixed code for passing tests successfully

* changed PersistentId to Jpa in MdmSearchInterceptor

* added the todo comments with questions

* added one more question

* renamed TODO questions

* first pass at converting to generic ResourcePersistentId

* fix test

* fix test

* fix test

* make ResourcePersistentId abstract

* Generic type MdmLink

* Final TODOs

* Final TODOs

* cleanup

* fix test

* fix id to string

* fix cyclic package dep

* add <?> to Base so we can extract interface

* Revert "add <?> to Base so we can extract interface"

This reverts commit a806f3d2bc.

* switch to interface

* javadoc

* replace base with interface

* fix test

* add generic template to mdmdao

* remove unneccessary JpaPid casts

* remove unneccessary JpaPid casts

* remove unneccessary JpaPid casts

* remove unneccessary MongoPid casts

* fix test

* fix regression

* fix compile issues arising from merging master

* fix beans

* bump version to 6.3.3-SNAPSHOT

* change logs

* review feedback

* review feedback

* fixme

Co-authored-by: Ken Stevens <ken@smilecdr.com>
This commit is contained in:
kateryna-mironova 2022-12-09 09:30:51 -05:00 committed by GitHub
parent d639a2a86d
commit 017cc4e29c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
277 changed files with 1894 additions and 2087 deletions

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -3,14 +3,14 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-bom</artifactId> <artifactId>hapi-fhir-bom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>HAPI FHIR BOM</name> <name>HAPI FHIR BOM</name>
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId> <artifactId>hapi-fhir-cli</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom</relativePath> <relativePath>../../hapi-deployable-pom</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -1,5 +1,5 @@
--- ---
type: fix type: fix
issue: 3379 issue: 3379
title: "Fixed an issue where FindCandidateByLinkSvc still uses long to store persistent ids rather than ResourcePersistentId, title: "Fixed an issue where FindCandidateByLinkSvc still uses long to store persistent ids rather than IResourcePersistentId,
also fixed an issue where MdmLinkCreateSvc was not setting the resource type of MdmLinks properly" also fixed an issue where MdmLinkCreateSvc was not setting the resource type of MdmLinks properly"

View File

@ -0,0 +1,5 @@
---
type: change
issue: 4244
title: "Replace usages of ResourcePersistentId with an interface IResourcePersistentId and parameterize specific
implementations of it in classes that rely on a specific implementation."

View File

@ -11,7 +11,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -37,6 +37,7 @@ import ca.uhn.fhir.jpa.dao.IResultIterator;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.dao.mdm.MdmExpansionCacheSvc; import ca.uhn.fhir.jpa.dao.mdm.MdmExpansionCacheSvc;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -47,7 +48,6 @@ import ca.uhn.fhir.mdm.model.MdmPidTuple;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions; import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.HasOrListParam; import ca.uhn.fhir.rest.param.HasOrListParam;
import ca.uhn.fhir.rest.param.HasParam; import ca.uhn.fhir.rest.param.HasParam;
import ca.uhn.fhir.rest.param.ReferenceOrListParam; import ca.uhn.fhir.rest.param.ReferenceOrListParam;
@ -72,6 +72,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -81,7 +82,7 @@ import java.util.stream.Collectors;
import static ca.uhn.fhir.rest.api.Constants.PARAM_HAS; import static ca.uhn.fhir.rest.api.Constants.PARAM_HAS;
import static ca.uhn.fhir.rest.api.Constants.PARAM_ID; import static ca.uhn.fhir.rest.api.Constants.PARAM_ID;
public class JpaBulkExportProcessor implements IBulkExportProcessor { public class JpaBulkExportProcessor implements IBulkExportProcessor<JpaPid> {
private static final Logger ourLog = LoggerFactory.getLogger(JpaBulkExportProcessor.class); private static final Logger ourLog = LoggerFactory.getLogger(JpaBulkExportProcessor.class);
public static final int QUERY_CHUNK_SIZE = 100; public static final int QUERY_CHUNK_SIZE = 100;
@ -100,10 +101,10 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
private DaoRegistry myDaoRegistry; private DaoRegistry myDaoRegistry;
@Autowired @Autowired
protected SearchBuilderFactory mySearchBuilderFactory; protected SearchBuilderFactory<JpaPid> mySearchBuilderFactory;
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<JpaPid> myIdHelperService;
@Autowired @Autowired
private IMdmLinkDao myMdmLinkDao; private IMdmLinkDao myMdmLinkDao;
@ -118,12 +119,12 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
@Transactional @Transactional
@Override @Override
public Iterator<ResourcePersistentId> getResourcePidIterator(ExportPIDIteratorParameters theParams) { public Iterator<JpaPid> getResourcePidIterator(ExportPIDIteratorParameters theParams) {
String resourceType = theParams.getResourceType(); String resourceType = theParams.getResourceType();
String jobId = theParams.getJobId(); String jobId = theParams.getJobId();
RuntimeResourceDefinition def = myContext.getResourceDefinition(resourceType); RuntimeResourceDefinition def = myContext.getResourceDefinition(resourceType);
Set<ResourcePersistentId> pids; LinkedHashSet<JpaPid> pids;
if (theParams.getExportStyle() == BulkDataExportOptions.ExportStyle.PATIENT) { if (theParams.getExportStyle() == BulkDataExportOptions.ExportStyle.PATIENT) {
pids = getPidsForPatientStyleExport(theParams, resourceType, jobId, def); pids = getPidsForPatientStyleExport(theParams, resourceType, jobId, def);
} else if (theParams.getExportStyle() == BulkDataExportOptions.ExportStyle.GROUP) { } else if (theParams.getExportStyle() == BulkDataExportOptions.ExportStyle.GROUP) {
@ -136,8 +137,8 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
return pids.iterator(); return pids.iterator();
} }
private Set<ResourcePersistentId> getPidsForPatientStyleExport(ExportPIDIteratorParameters theParams, String resourceType, String jobId, RuntimeResourceDefinition def) { private LinkedHashSet<JpaPid> getPidsForPatientStyleExport(ExportPIDIteratorParameters theParams, String resourceType, String jobId, RuntimeResourceDefinition def) {
Set<ResourcePersistentId> pids = new HashSet<>(); LinkedHashSet<JpaPid> pids = new LinkedHashSet<>();
// Patient // Patient
if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.DISABLED) { if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.DISABLED) {
String errorMessage = "You attempted to start a Patient Bulk Export, but the system has `Index Missing Fields` disabled. It must be enabled for Patient Bulk Export"; String errorMessage = "You attempted to start a Patient Bulk Export, but the system has `Index Missing Fields` disabled. It must be enabled for Patient Bulk Export";
@ -152,12 +153,12 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
//Ensure users did not monkey with the patient compartment search parameter. //Ensure users did not monkey with the patient compartment search parameter.
validateSearchParametersForPatient(map, theParams); validateSearchParametersForPatient(map, theParams);
ISearchBuilder searchBuilder = getSearchBuilderForResourceType(theParams.getResourceType()); ISearchBuilder<JpaPid> searchBuilder = getSearchBuilderForResourceType(theParams.getResourceType());
filterBySpecificPatient(theParams, resourceType, patientSearchParam, map); filterBySpecificPatient(theParams, resourceType, patientSearchParam, map);
SearchRuntimeDetails searchRuntime = new SearchRuntimeDetails(null, jobId); SearchRuntimeDetails searchRuntime = new SearchRuntimeDetails(null, jobId);
IResultIterator resultIterator = searchBuilder.createQuery(map, searchRuntime, null, RequestPartitionId.allPartitions()); IResultIterator<JpaPid> resultIterator = searchBuilder.createQuery(map, searchRuntime, null, RequestPartitionId.allPartitions());
while (resultIterator.hasNext()) { while (resultIterator.hasNext()) {
pids.add(resultIterator.next()); pids.add(resultIterator.next());
} }
@ -190,15 +191,15 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
return referenceOrListParam; return referenceOrListParam;
} }
private Set<ResourcePersistentId> getPidsForSystemStyleExport(ExportPIDIteratorParameters theParams, String theJobId, RuntimeResourceDefinition theDef) { private LinkedHashSet<JpaPid> getPidsForSystemStyleExport(ExportPIDIteratorParameters theParams, String theJobId, RuntimeResourceDefinition theDef) {
Set<ResourcePersistentId> pids = new HashSet<>(); LinkedHashSet<JpaPid> pids = new LinkedHashSet<>();
// System // System
List<SearchParameterMap> maps = myBulkExportHelperSvc.createSearchParameterMapsForResourceType(theDef, theParams); List<SearchParameterMap> maps = myBulkExportHelperSvc.createSearchParameterMapsForResourceType(theDef, theParams);
ISearchBuilder searchBuilder = getSearchBuilderForResourceType(theParams.getResourceType()); ISearchBuilder<JpaPid> searchBuilder = getSearchBuilderForResourceType(theParams.getResourceType());
for (SearchParameterMap map : maps) { for (SearchParameterMap map : maps) {
// requires a transaction // requires a transaction
IResultIterator resultIterator = searchBuilder.createQuery(map, IResultIterator<JpaPid> resultIterator = searchBuilder.createQuery(map,
new SearchRuntimeDetails(null, theJobId), new SearchRuntimeDetails(null, theJobId),
null, null,
RequestPartitionId.allPartitions()); RequestPartitionId.allPartitions());
@ -209,8 +210,8 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
return pids; return pids;
} }
private Set<ResourcePersistentId> getPidsForGroupStyleExport(ExportPIDIteratorParameters theParams, String theResourceType, RuntimeResourceDefinition theDef) { private LinkedHashSet<JpaPid> getPidsForGroupStyleExport(ExportPIDIteratorParameters theParams, String theResourceType, RuntimeResourceDefinition theDef) {
Set<ResourcePersistentId> pids; LinkedHashSet<JpaPid> pids;
if (theResourceType.equalsIgnoreCase("Patient")) { if (theResourceType.equalsIgnoreCase("Patient")) {
ourLog.info("Expanding Patients of a Group Bulk Export."); ourLog.info("Expanding Patients of a Group Bulk Export.");
@ -224,9 +225,9 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
return pids; return pids;
} }
private Set<ResourcePersistentId> getRelatedResourceTypePids(ExportPIDIteratorParameters theParams, RuntimeResourceDefinition theDef) { private LinkedHashSet<JpaPid> getRelatedResourceTypePids(ExportPIDIteratorParameters theParams, RuntimeResourceDefinition theDef) {
Set<ResourcePersistentId> pids = new HashSet<>(); LinkedHashSet<JpaPid> pids = new LinkedHashSet<>();
Set<ResourcePersistentId> expandedMemberResourceIds = expandAllPatientPidsFromGroup(theParams); Set<JpaPid> expandedMemberResourceIds = expandAllPatientPidsFromGroup(theParams);
assert expandedMemberResourceIds != null && !expandedMemberResourceIds.isEmpty(); assert expandedMemberResourceIds != null && !expandedMemberResourceIds.isEmpty();
if (ourLog.isDebugEnabled()) { if (ourLog.isDebugEnabled()) {
ourLog.debug("{} has been expanded to members:[{}]", theParams.getGroupId(), expandedMemberResourceIds); ourLog.debug("{} has been expanded to members:[{}]", theParams.getGroupId(), expandedMemberResourceIds);
@ -234,17 +235,17 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
//Next, let's search for the target resources, with their correct patient references, chunked. //Next, let's search for the target resources, with their correct patient references, chunked.
//The results will be jammed into myReadPids //The results will be jammed into myReadPids
QueryChunker<ResourcePersistentId> queryChunker = new QueryChunker<>(); QueryChunker<JpaPid> queryChunker = new QueryChunker<>();
queryChunker.chunk(expandedMemberResourceIds, QUERY_CHUNK_SIZE, (idChunk) -> { queryChunker.chunk(expandedMemberResourceIds, QUERY_CHUNK_SIZE, (idChunk) -> {
queryResourceTypeWithReferencesToPatients(pids, idChunk, theParams, theDef); queryResourceTypeWithReferencesToPatients(pids, idChunk, theParams, theDef);
}); });
return pids; return pids;
} }
private Set<ResourcePersistentId> getSingletonGroupList(ExportPIDIteratorParameters theParams) { private LinkedHashSet<JpaPid> getSingletonGroupList(ExportPIDIteratorParameters theParams) {
IBaseResource group = myDaoRegistry.getResourceDao("Group").read(new IdDt(theParams.getGroupId()), SystemRequestDetails.newSystemRequestAllPartitions()); IBaseResource group = myDaoRegistry.getResourceDao("Group").read(new IdDt(theParams.getGroupId()), SystemRequestDetails.newSystemRequestAllPartitions());
ResourcePersistentId pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), group); JpaPid pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), group);
Set<ResourcePersistentId> pids = new HashSet<>(); LinkedHashSet<JpaPid> pids = new LinkedHashSet<>();
pids.add(pidOrNull); pids.add(pidOrNull);
return pids; return pids;
} }
@ -252,7 +253,7 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
/** /**
* Get a ISearchBuilder for the given resource type this partition is responsible for. * Get a ISearchBuilder for the given resource type this partition is responsible for.
*/ */
protected ISearchBuilder getSearchBuilderForResourceType(String theResourceType) { protected ISearchBuilder<JpaPid> getSearchBuilderForResourceType(String theResourceType) {
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceType); IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceType);
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResourceType); RuntimeResourceDefinition def = myContext.getResourceDefinition(theResourceType);
Class<? extends IBaseResource> typeClass = def.getImplementingClass(); Class<? extends IBaseResource> typeClass = def.getImplementingClass();
@ -307,21 +308,21 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
* In case we are doing a Group Bulk Export and resourceType `Patient` is requested, we can just return the group members, * In case we are doing a Group Bulk Export and resourceType `Patient` is requested, we can just return the group members,
* possibly expanded by MDM, and don't have to go and fetch other resource DAOs. * possibly expanded by MDM, and don't have to go and fetch other resource DAOs.
*/ */
private Set<ResourcePersistentId> getExpandedPatientList(ExportPIDIteratorParameters theParameters) { private LinkedHashSet<JpaPid> getExpandedPatientList(ExportPIDIteratorParameters theParameters) {
List<ResourcePersistentId> members = getMembersFromGroupWithFilter(theParameters); List<JpaPid> members = getMembersFromGroupWithFilter(theParameters);
List<IIdType> ids = members.stream().map(member -> new IdDt("Patient/" + member)).collect(Collectors.toList()); List<IIdType> ids = members.stream().map(member -> new IdDt("Patient/" + member)).collect(Collectors.toList());
ourLog.info("While extracting patients from a group, we found {} patients.", ids.size()); ourLog.info("While extracting patients from a group, we found {} patients.", ids.size());
ourLog.info("Found patients: {}", ids.stream().map(id -> id.getValue()).collect(Collectors.joining(", "))); ourLog.info("Found patients: {}", ids.stream().map(id -> id.getValue()).collect(Collectors.joining(", ")));
// Are bulk exports partition aware or care about partition at all? This does // Are bulk exports partition aware or care about partition at all? This does
List<ResourcePersistentId> pidsOrThrowException = members; List<JpaPid> pidsOrThrowException = members;
Set<ResourcePersistentId> patientPidsToExport = new HashSet<>(pidsOrThrowException); LinkedHashSet<JpaPid> patientPidsToExport = new LinkedHashSet<>(pidsOrThrowException);
if (theParameters.isExpandMdm()) { if (theParameters.isExpandMdm()) {
SystemRequestDetails srd = SystemRequestDetails.newSystemRequestAllPartitions(); SystemRequestDetails srd = SystemRequestDetails.newSystemRequestAllPartitions();
IBaseResource group = myDaoRegistry.getResourceDao("Group").read(new IdDt(theParameters.getGroupId()), srd); IBaseResource group = myDaoRegistry.getResourceDao("Group").read(new IdDt(theParameters.getGroupId()), srd);
ResourcePersistentId pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), group); JpaPid pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), group);
List<MdmPidTuple> goldenPidSourcePidTuple = myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH); List<MdmPidTuple<JpaPid>> goldenPidSourcePidTuple = myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH);
goldenPidSourcePidTuple.forEach(tuple -> { goldenPidSourcePidTuple.forEach(tuple -> {
patientPidsToExport.add(tuple.getGoldenPid()); patientPidsToExport.add(tuple.getGoldenPid());
patientPidsToExport.add(tuple.getSourcePid()); patientPidsToExport.add(tuple.getSourcePid());
@ -336,19 +337,19 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
* *
* @return A list of strings representing the Patient IDs of the members (e.g. ["P1", "P2", "P3"] * @return A list of strings representing the Patient IDs of the members (e.g. ["P1", "P2", "P3"]
*/ */
private List<ResourcePersistentId> getMembersFromGroupWithFilter(ExportPIDIteratorParameters theParameters) { private List<JpaPid> getMembersFromGroupWithFilter(ExportPIDIteratorParameters theParameters) {
RuntimeResourceDefinition def = myContext.getResourceDefinition("Patient"); RuntimeResourceDefinition def = myContext.getResourceDefinition("Patient");
List<String> pids = new ArrayList<>(); List<String> pids = new ArrayList<>();
List<ResourcePersistentId> resPids = new ArrayList<>(); List<JpaPid> resPids = new ArrayList<>();
List<SearchParameterMap> maps = myBulkExportHelperSvc.createSearchParameterMapsForResourceType(def, theParameters); List<SearchParameterMap> maps = myBulkExportHelperSvc.createSearchParameterMapsForResourceType(def, theParameters);
maps.forEach(map -> addMembershipToGroupClause(map, theParameters.getGroupId())); maps.forEach(map -> addMembershipToGroupClause(map, theParameters.getGroupId()));
for (SearchParameterMap map : maps) { for (SearchParameterMap map : maps) {
ISearchBuilder searchBuilder = getSearchBuilderForResourceType("Patient"); ISearchBuilder<JpaPid> searchBuilder = getSearchBuilderForResourceType("Patient");
ourLog.debug("Searching for members of group {} with job id {} with map {}", theParameters.getGroupId(), theParameters.getJobId(), map); ourLog.debug("Searching for members of group {} with job id {} with map {}", theParameters.getGroupId(), theParameters.getJobId(), map);
IResultIterator resultIterator = searchBuilder.createQuery(map, IResultIterator<JpaPid> resultIterator = searchBuilder.createQuery(map,
new SearchRuntimeDetails(null, theParameters.getJobId()), new SearchRuntimeDetails(null, theParameters.getJobId()),
null, null,
RequestPartitionId.allPartitions()); RequestPartitionId.allPartitions());
@ -376,7 +377,7 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
/** /**
* @param thePidTuples * @param thePidTuples
*/ */
private void populateMdmResourceCache(List<MdmPidTuple> thePidTuples) { private void populateMdmResourceCache(List<MdmPidTuple<JpaPid>> thePidTuples) {
if (myMdmExpansionCacheSvc.hasBeenPopulated()) { if (myMdmExpansionCacheSvc.hasBeenPopulated()) {
return; return;
} }
@ -385,7 +386,7 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
// patient/gold-1 -> [patient/1, patient/2] // patient/gold-1 -> [patient/1, patient/2]
// patient/gold-2 -> [patient/3, patient/4] // patient/gold-2 -> [patient/3, patient/4]
//} //}
Map<ResourcePersistentId, Set<ResourcePersistentId>> goldenResourceToSourcePidMap = new HashMap<>(); Map<JpaPid, Set<JpaPid>> goldenResourceToSourcePidMap = new HashMap<>();
extract(thePidTuples, goldenResourceToSourcePidMap); extract(thePidTuples, goldenResourceToSourcePidMap);
//Next, lets convert it to an inverted index for fast lookup //Next, lets convert it to an inverted index for fast lookup
@ -410,21 +411,21 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
myMdmExpansionCacheSvc.setCacheContents(sourceResourceIdToGoldenResourceIdMap); myMdmExpansionCacheSvc.setCacheContents(sourceResourceIdToGoldenResourceIdMap);
} }
private void extract(List<MdmPidTuple> theGoldenPidTargetPidTuples, Map<ResourcePersistentId, Set<ResourcePersistentId>> theGoldenResourceToSourcePidMap) { private void extract(List<MdmPidTuple<JpaPid>> theGoldenPidTargetPidTuples, Map<JpaPid, Set<JpaPid>> theGoldenResourceToSourcePidMap) {
for (MdmPidTuple goldenPidTargetPidTuple : theGoldenPidTargetPidTuples) { for (MdmPidTuple<JpaPid> goldenPidTargetPidTuple : theGoldenPidTargetPidTuples) {
ResourcePersistentId goldenPid = goldenPidTargetPidTuple.getGoldenPid(); JpaPid goldenPid = goldenPidTargetPidTuple.getGoldenPid();
ResourcePersistentId sourcePid = goldenPidTargetPidTuple.getSourcePid(); JpaPid sourcePid = goldenPidTargetPidTuple.getSourcePid();
theGoldenResourceToSourcePidMap.computeIfAbsent(goldenPid, key -> new HashSet<>()).add(sourcePid); theGoldenResourceToSourcePidMap.computeIfAbsent(goldenPid, key -> new HashSet<>()).add(sourcePid);
} }
} }
private void queryResourceTypeWithReferencesToPatients(Set<ResourcePersistentId> myReadPids, private void queryResourceTypeWithReferencesToPatients(Set<JpaPid> theReadPids,
List<ResourcePersistentId> resourcePersistentIdChunk, List<JpaPid> JpaPidChunk,
ExportPIDIteratorParameters theParams, ExportPIDIteratorParameters theParams,
RuntimeResourceDefinition theDef) { RuntimeResourceDefinition theDef) {
//Convert Resource Persistent IDs to actual client IDs. //Convert Resource Persistent IDs to actual client IDs.
Set<ResourcePersistentId> pidSet = new HashSet<>(resourcePersistentIdChunk); Set<JpaPid> pidSet = new HashSet<>(JpaPidChunk);
Set<String> resourceIds = myIdHelperService.translatePidsToFhirResourceIds(pidSet); Set<String> resourceIds = myIdHelperService.translatePidsToFhirResourceIds(pidSet);
//Build SP map //Build SP map
@ -436,7 +437,7 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
validateSearchParametersForGroup(expandedSpMap, theParams.getResourceType()); validateSearchParametersForGroup(expandedSpMap, theParams.getResourceType());
// Fetch and cache a search builder for this resource type // Fetch and cache a search builder for this resource type
ISearchBuilder searchBuilder = getSearchBuilderForResourceType(theParams.getResourceType()); ISearchBuilder<JpaPid> searchBuilder = getSearchBuilderForResourceType(theParams.getResourceType());
// Now, further filter the query with patient references defined by the chunk of IDs we have. // Now, further filter the query with patient references defined by the chunk of IDs we have.
if (PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(theParams.getResourceType())) { if (PATIENT_BULK_EXPORT_FORWARD_REFERENCE_RESOURCE_TYPES.contains(theParams.getResourceType())) {
@ -446,20 +447,20 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
} }
//Execute query and all found pids to our local iterator. //Execute query and all found pids to our local iterator.
IResultIterator resultIterator = searchBuilder.createQuery(expandedSpMap, IResultIterator<JpaPid> resultIterator = searchBuilder.createQuery(expandedSpMap,
new SearchRuntimeDetails(null, theParams.getJobId()), new SearchRuntimeDetails(null, theParams.getJobId()),
null, null,
RequestPartitionId.allPartitions()); RequestPartitionId.allPartitions());
while (resultIterator.hasNext()) { while (resultIterator.hasNext()) {
myReadPids.add(resultIterator.next()); theReadPids.add(resultIterator.next());
} }
// add _include to results to support ONC // add _include to results to support ONC
Set<Include> includes = Collections.singleton(new Include("*", true)); Set<Include> includes = Collections.singleton(new Include("*", true));
SystemRequestDetails requestDetails = SystemRequestDetails.newSystemRequestAllPartitions(); SystemRequestDetails requestDetails = SystemRequestDetails.newSystemRequestAllPartitions();
Set<ResourcePersistentId> includeIds = searchBuilder.loadIncludes(myContext, myEntityManager, myReadPids, includes, false, expandedSpMap.getLastUpdated(), theParams.getJobId(), requestDetails, null); Set<JpaPid> includeIds = searchBuilder.loadIncludes(myContext, myEntityManager, theReadPids, includes, false, expandedSpMap.getLastUpdated(), theParams.getJobId(), requestDetails, null);
// gets rid of the Patient duplicates // gets rid of the Patient duplicates
myReadPids.addAll(includeIds.stream().filter((id) -> !id.getResourceType().equals("Patient")).collect(Collectors.toSet())); theReadPids.addAll(includeIds.stream().filter((id) -> !id.getResourceType().equals("Patient")).collect(Collectors.toSet()));
} }
} }
@ -504,11 +505,11 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
* *
* @return a Set of Strings representing the resource IDs of all members of a group. * @return a Set of Strings representing the resource IDs of all members of a group.
*/ */
private Set<ResourcePersistentId> expandAllPatientPidsFromGroup(ExportPIDIteratorParameters theParams) { private Set<JpaPid> expandAllPatientPidsFromGroup(ExportPIDIteratorParameters theParams) {
Set<ResourcePersistentId> expandedIds = new HashSet<>(); Set<JpaPid> expandedIds = new HashSet<>();
SystemRequestDetails requestDetails = SystemRequestDetails.newSystemRequestAllPartitions(); SystemRequestDetails requestDetails = SystemRequestDetails.newSystemRequestAllPartitions();
IBaseResource group = myDaoRegistry.getResourceDao("Group").read(new IdDt(theParams.getGroupId()), requestDetails); IBaseResource group = myDaoRegistry.getResourceDao("Group").read(new IdDt(theParams.getGroupId()), requestDetails);
ResourcePersistentId pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), group); JpaPid pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), group);
//Attempt to perform MDM Expansion of membership //Attempt to perform MDM Expansion of membership
if (theParams.isExpandMdm()) { if (theParams.isExpandMdm()) {
@ -517,24 +518,24 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor {
//Now manually add the members of the group (its possible even with mdm expansion that some members dont have MDM matches, //Now manually add the members of the group (its possible even with mdm expansion that some members dont have MDM matches,
//so would be otherwise skipped //so would be otherwise skipped
List<ResourcePersistentId> membersFromGroupWithFilter = getMembersFromGroupWithFilter(theParams); List<JpaPid> membersFromGroupWithFilter = getMembersFromGroupWithFilter(theParams);
ourLog.debug("Group with ID [{}] has been expanded to: {}", theParams.getGroupId(), membersFromGroupWithFilter); ourLog.debug("Group with ID [{}] has been expanded to: {}", theParams.getGroupId(), membersFromGroupWithFilter);
expandedIds.addAll(membersFromGroupWithFilter); expandedIds.addAll(membersFromGroupWithFilter);
return expandedIds; return expandedIds;
} }
private Set<ResourcePersistentId> performMembershipExpansionViaMdmTable(ResourcePersistentId pidOrNull) { private Set<JpaPid> performMembershipExpansionViaMdmTable(JpaPid pidOrNull) {
List<MdmPidTuple> goldenPidTargetPidTuples = myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH); List<MdmPidTuple<JpaPid>> goldenPidTargetPidTuples = myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(pidOrNull, MdmMatchResultEnum.MATCH);
//Now lets translate these pids into resource IDs //Now lets translate these pids into resource IDs
Set<ResourcePersistentId> uniquePids = new HashSet<>(); Set<JpaPid> uniquePids = new HashSet<>();
goldenPidTargetPidTuples.forEach(tuple -> { goldenPidTargetPidTuples.forEach(tuple -> {
uniquePids.add(tuple.getGoldenPid()); uniquePids.add(tuple.getGoldenPid());
uniquePids.add(tuple.getSourcePid()); uniquePids.add(tuple.getSourcePid());
}); });
PersistentIdToForcedIdMap pidToForcedIdMap = myIdHelperService.translatePidsToForcedIds(uniquePids); PersistentIdToForcedIdMap pidToForcedIdMap = myIdHelperService.translatePidsToForcedIds(uniquePids);
Map<ResourcePersistentId, Set<ResourcePersistentId>> goldenResourceToSourcePidMap = new HashMap<>(); Map<JpaPid, Set<JpaPid>> goldenResourceToSourcePidMap = new HashMap<>();
extract(goldenPidTargetPidTuples, goldenResourceToSourcePidMap); extract(goldenPidTargetPidTuples, goldenResourceToSourcePidMap);
populateMdmResourceCache(goldenPidTargetPidTuples); populateMdmResourceCache(goldenPidTargetPidTuples);

View File

@ -25,12 +25,11 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.QueryChunker; import ca.uhn.fhir.jpa.util.QueryChunker;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -60,7 +59,7 @@ public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
@Autowired @Autowired
IResourceTableDao myResourceTableDao; IResourceTableDao myResourceTableDao;
@Autowired @Autowired
IIdHelperService myIdHelperService; IIdHelperService<JpaPid> myIdHelperService;
@Override @Override
@Nonnull @Nonnull
@ -72,8 +71,9 @@ public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
ourLog.debug("About to retrieve version map for resource type: {}", theResourceName); ourLog.debug("About to retrieve version map for resource type: {}", theResourceName);
} }
List<Long> matchingIds = dao.searchForIds(theSearchParamMap, new SystemRequestDetails().setRequestPartitionId(theRequestPartitionId)).stream() List<JpaPid> jpaPids = dao.searchForIds(theSearchParamMap, new SystemRequestDetails().setRequestPartitionId(theRequestPartitionId));
.map(ResourcePersistentId::getIdAsLong) List<Long> matchingIds = jpaPids.stream()
.map(JpaPid::getId)
.collect(Collectors.toList()); .collect(Collectors.toList());
List<ResourceTable> allById = new ArrayList<>(); List<ResourceTable> allById = new ArrayList<>();
@ -137,16 +137,15 @@ public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
return retval; return retval;
} }
List<ResourcePersistentId> resourcePersistentIds = myIdHelperService.resolveResourcePersistentIdsWithCache(thePartitionId, List<JpaPid> jpaPids = myIdHelperService.resolveResourcePersistentIdsWithCache(thePartitionId, new ArrayList<>(theIds));
theIds.stream().collect(Collectors.toList()));
// we'll use this map to fetch pids that require versions // we'll use this map to fetch pids that require versions
HashMap<Long, ResourcePersistentId> pidsToVersionToResourcePid = new HashMap<>(); HashMap<Long, JpaPid> pidsToVersionToResourcePid = new HashMap<>();
// fill in our map // fill in our map
for (ResourcePersistentId pid : resourcePersistentIds) { for (JpaPid pid : jpaPids) {
if (pid.getVersion() == null) { if (pid.getVersion() == null) {
pidsToVersionToResourcePid.put(pid.getIdAsLong(), pid); pidsToVersionToResourcePid.put(pid.getId(), pid);
} }
Optional<IIdType> idOp = theIds.stream() Optional<IIdType> idOp = theIds.stream()
.filter(i -> i.getIdPart().equals(pid.getAssociatedResourceId().getIdPart())) .filter(i -> i.getIdPart().equals(pid.getAssociatedResourceId().getIdPart()))

View File

@ -27,7 +27,6 @@ import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao; import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider; import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider;
import ca.uhn.fhir.jpa.dao.index.IJpaIdHelperService;
import ca.uhn.fhir.jpa.delete.batch2.DeleteExpungeSqlBuilder; import ca.uhn.fhir.jpa.delete.batch2.DeleteExpungeSqlBuilder;
import ca.uhn.fhir.jpa.delete.batch2.DeleteExpungeSvcImpl; import ca.uhn.fhir.jpa.delete.batch2.DeleteExpungeSvcImpl;
import ca.uhn.fhir.jpa.reindex.Batch2DaoSvcImpl; import ca.uhn.fhir.jpa.reindex.Batch2DaoSvcImpl;

View File

@ -26,7 +26,6 @@ import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil;
import ca.uhn.fhir.jpa.config.util.ValidationSupportConfigUtil; import ca.uhn.fhir.jpa.config.util.ValidationSupportConfigUtil;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl; import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.mdm.MdmLinkDaoJpaImpl;
import ca.uhn.fhir.jpa.dao.search.HSearchSortHelperImpl; import ca.uhn.fhir.jpa.dao.search.HSearchSortHelperImpl;
import ca.uhn.fhir.jpa.dao.search.IHSearchSortHelper; import ca.uhn.fhir.jpa.dao.search.IHSearchSortHelper;
import ca.uhn.fhir.jpa.provider.DaoRegistryResourceSupportedSvc; import ca.uhn.fhir.jpa.provider.DaoRegistryResourceSupportedSvc;
@ -35,7 +34,6 @@ import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl; import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain; import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain;
import ca.uhn.fhir.mdm.dao.IMdmLinkDao;
import ca.uhn.fhir.rest.api.IResourceSupportedSvc; import ca.uhn.fhir.rest.api.IResourceSupportedSvc;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport; import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
@ -87,9 +85,4 @@ public class HapiJpaConfig {
public ResourceCountCache resourceCountsCache(IFhirSystemDao<?, ?> theSystemDao) { public ResourceCountCache resourceCountsCache(IFhirSystemDao<?, ?> theSystemDao) {
return ResourceCountCacheUtil.newResourceCountCache(theSystemDao); return ResourceCountCacheUtil.newResourceCountCache(theSystemDao);
} }
@Bean
public static IMdmLinkDao mdmLinkDao(){
return new MdmLinkDaoJpaImpl();
}
} }

View File

@ -37,22 +37,26 @@ import ca.uhn.fhir.jpa.dao.expunge.ExpungeOperation;
import ca.uhn.fhir.jpa.dao.expunge.ExpungeService; import ca.uhn.fhir.jpa.dao.expunge.ExpungeService;
import ca.uhn.fhir.jpa.dao.expunge.IExpungeEverythingService; import ca.uhn.fhir.jpa.dao.expunge.IExpungeEverythingService;
import ca.uhn.fhir.jpa.dao.expunge.IResourceExpungeService; import ca.uhn.fhir.jpa.dao.expunge.IResourceExpungeService;
import ca.uhn.fhir.jpa.dao.expunge.ResourceExpungeService; import ca.uhn.fhir.jpa.dao.expunge.JpaResourceExpungeService;
import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider; import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider;
import ca.uhn.fhir.jpa.dao.index.DaoResourceLinkResolver; import ca.uhn.fhir.jpa.dao.index.DaoResourceLinkResolver;
import ca.uhn.fhir.jpa.dao.index.DaoSearchParamSynchronizer; import ca.uhn.fhir.jpa.dao.index.DaoSearchParamSynchronizer;
import ca.uhn.fhir.jpa.dao.index.IdHelperService; import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.dao.index.SearchParamWithInlineReferencesExtractor; import ca.uhn.fhir.jpa.dao.index.SearchParamWithInlineReferencesExtractor;
import ca.uhn.fhir.jpa.dao.mdm.JpaMdmLinkImplFactory;
import ca.uhn.fhir.jpa.dao.mdm.MdmLinkDaoJpaImpl;
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
import ca.uhn.fhir.jpa.delete.DeleteConflictFinderService; import ca.uhn.fhir.jpa.delete.DeleteConflictFinderService;
import ca.uhn.fhir.jpa.delete.DeleteConflictService; import ca.uhn.fhir.jpa.delete.DeleteConflictService;
import ca.uhn.fhir.jpa.delete.ThreadSafeResourceDeleterSvc; import ca.uhn.fhir.jpa.delete.ThreadSafeResourceDeleterSvc;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.graphql.DaoRegistryGraphQLStorageServices; import ca.uhn.fhir.jpa.graphql.DaoRegistryGraphQLStorageServices;
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor; import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
import ca.uhn.fhir.jpa.interceptor.JpaConsentContextServices; import ca.uhn.fhir.jpa.interceptor.JpaConsentContextServices;
import ca.uhn.fhir.jpa.interceptor.OverridePathBasedReferentialIntegrityForDeletesInterceptor; import ca.uhn.fhir.jpa.interceptor.OverridePathBasedReferentialIntegrityForDeletesInterceptor;
import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder; import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.sched.ISchedulerService; import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
import ca.uhn.fhir.jpa.packages.IHapiPackageCacheManager; import ca.uhn.fhir.jpa.packages.IHapiPackageCacheManager;
import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc; import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc;
@ -131,10 +135,12 @@ import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl; import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl;
import ca.uhn.fhir.jpa.validation.ValidationSettings; import ca.uhn.fhir.jpa.validation.ValidationSettings;
import ca.uhn.fhir.mdm.dao.IMdmLinkDao;
import ca.uhn.fhir.mdm.dao.IMdmLinkImplFactory;
import ca.uhn.fhir.mdm.svc.MdmLinkExpandSvc; import ca.uhn.fhir.mdm.svc.MdmLinkExpandSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter; import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationInterceptor; import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationSvc; import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationSvc;
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices; import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices;
@ -299,7 +305,7 @@ public class JpaConfig {
@Bean @Bean
@Primary @Primary
public IResourceLinkResolver daoResourceLinkResolver() { public IResourceLinkResolver daoResourceLinkResolver() {
return new DaoResourceLinkResolver(); return new DaoResourceLinkResolver<JpaPid>();
} }
@Bean @Bean
@ -679,7 +685,7 @@ public class JpaConfig {
@Bean @Bean
@Scope("prototype") @Scope("prototype")
public ExpungeOperation expungeOperation(String theResourceName, ResourcePersistentId theResourceId, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) { public ExpungeOperation expungeOperation(String theResourceName, IResourcePersistentId theResourceId, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
return new ExpungeOperation(theResourceName, theResourceId, theExpungeOptions, theRequestDetails); return new ExpungeOperation(theResourceName, theResourceId, theExpungeOptions, theRequestDetails);
} }
@ -690,7 +696,7 @@ public class JpaConfig {
@Bean @Bean
public IResourceExpungeService resourceExpungeService() { public IResourceExpungeService resourceExpungeService() {
return new ResourceExpungeService(); return new JpaResourceExpungeService();
} }
@Bean @Bean
@ -791,5 +797,11 @@ public class JpaConfig {
return new ObservationLastNIndexPersistSvc(); return new ObservationLastNIndexPersistSvc();
} }
@Bean
public IMdmLinkDao<JpaPid, MdmLink> mdmLinkDao(){
return new MdmLinkDaoJpaImpl();
}
@Bean
IMdmLinkImplFactory<MdmLink> mdmLinkImplFactory() {return new JpaMdmLinkImplFactory();}
} }

View File

@ -27,7 +27,6 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IDao; import ca.uhn.fhir.jpa.api.dao.IDao;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc; import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.dao.data.IResourceSearchViewDao; import ca.uhn.fhir.jpa.dao.data.IResourceSearchViewDao;
@ -47,7 +46,6 @@ import ca.uhn.fhir.jpa.search.builder.tasks.SearchTask;
import ca.uhn.fhir.jpa.search.builder.tasks.SearchTaskParameters; import ca.uhn.fhir.jpa.search.builder.tasks.SearchTaskParameters;
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc;
import ca.uhn.fhir.jpa.search.lastn.IElasticsearchSvc;
import ca.uhn.fhir.rest.server.IPagingProvider; import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
@ -164,8 +162,7 @@ public class SearchConfig {
return new SearchTask(theParams, return new SearchTask(theParams,
myManagedTxManager, myManagedTxManager,
myContext, myContext,
mySearchStrategyFactory, myInterceptorBroadcaster,
myInterceptorBroadcaster,
mySearchBuilderFactory, mySearchBuilderFactory,
mySearchResultCacheSvc, mySearchResultCacheSvc,
myDaoConfig, myDaoConfig,
@ -181,7 +178,6 @@ public class SearchConfig {
return new SearchContinuationTask(theParams, return new SearchContinuationTask(theParams,
myManagedTxManager, myManagedTxManager,
myContext, myContext,
mySearchStrategyFactory,
myInterceptorBroadcaster, myInterceptorBroadcaster,
mySearchBuilderFactory, mySearchBuilderFactory,
mySearchResultCacheSvc, mySearchResultCacheSvc,

View File

@ -30,13 +30,12 @@ import ca.uhn.fhir.jpa.dao.index.SearchParamWithInlineReferencesExtractor;
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
import ca.uhn.fhir.jpa.delete.DeleteConflictService; import ca.uhn.fhir.jpa.delete.DeleteConflictService;
import ca.uhn.fhir.jpa.entity.PartitionEntity; import ca.uhn.fhir.jpa.entity.PartitionEntity;
import ca.uhn.fhir.jpa.entity.ResourceSearchView;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource; import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.BaseTag; import ca.uhn.fhir.jpa.model.entity.BaseTag;
import ca.uhn.fhir.jpa.model.entity.IBaseResourceEntity;
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum; import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryProvenanceEntity; import ca.uhn.fhir.jpa.model.entity.ResourceHistoryProvenanceEntity;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
@ -60,21 +59,16 @@ import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.util.QueryChunker; import ca.uhn.fhir.jpa.util.QueryChunker;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.StorageResponseCodeEnum;
import ca.uhn.fhir.model.api.Tag; import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseCodingDt; import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.LenientErrorHandler;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum; import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -86,7 +80,6 @@ import ca.uhn.fhir.util.CoverageIgnore;
import ca.uhn.fhir.util.HapiExtensions; import ca.uhn.fhir.util.HapiExtensions;
import ca.uhn.fhir.util.MetaUtil; import ca.uhn.fhir.util.MetaUtil;
import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.UrlUtil;
import ca.uhn.fhir.util.XmlUtil; import ca.uhn.fhir.util.XmlUtil;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
@ -108,7 +101,6 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IDomainResource; import org.hl7.fhir.instance.model.api.IDomainResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
@ -205,11 +197,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
@PersistenceContext(type = PersistenceContextType.TRANSACTION) @PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager; protected EntityManager myEntityManager;
@Autowired @Autowired
protected IIdHelperService myIdHelperService; protected IIdHelperService<JpaPid> myIdHelperService;
@Autowired @Autowired
protected IForcedIdDao myForcedIdDao; protected IForcedIdDao myForcedIdDao;
@Autowired @Autowired
protected ISearchCoordinatorSvc mySearchCoordinatorSvc; protected ISearchCoordinatorSvc<JpaPid> mySearchCoordinatorSvc;
@Autowired @Autowired
protected ITermReadSvc myTerminologySvc; protected ITermReadSvc myTerminologySvc;
@Autowired @Autowired
@ -1110,7 +1102,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
*/ */
if (thePerformIndexing) { if (thePerformIndexing) {
if (newParams == null) { if (newParams == null) {
myExpungeService.deleteAllSearchParams(new ResourcePersistentId(entity.getId())); myExpungeService.deleteAllSearchParams(JpaPid.fromId(entity.getId()));
} else { } else {
// Synchronize search param indexes // Synchronize search param indexes
@ -1425,16 +1417,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
doCallHooks(theTransactionDetails, theRequestDetails, interceptorPointcut, hookParams); doCallHooks(theTransactionDetails, theRequestDetails, interceptorPointcut, hookParams);
} }
protected void addPidToResource(IBasePersistedResource theEntity, IBaseResource theResource) { protected void addPidToResource(IResourceLookup<JpaPid> theEntity, IBaseResource theResource) {
if (theResource instanceof IAnyResource) { if (theResource instanceof IAnyResource) {
IDao.RESOURCE_PID.put((IAnyResource) theResource, theEntity.getPersistentId().getIdAsLong()); IDao.RESOURCE_PID.put((IAnyResource) theResource, theEntity.getPersistentId().getId());
} else if (theResource instanceof IResource) { } else if (theResource instanceof IResource) {
IDao.RESOURCE_PID.put((IResource) theResource, theEntity.getPersistentId().getIdAsLong()); IDao.RESOURCE_PID.put((IResource) theResource, theEntity.getPersistentId().getId());
} }
} }
private void validateChildReferenceTargetTypes(IBase theElement, String thePath) { private void validateChildReferenceTargetTypes(IBase theElement, String thePath) {
if (theElement == null) { if (theElement == null) {
return; return;

View File

@ -46,6 +46,7 @@ import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService; import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
import ca.uhn.fhir.jpa.delete.DeleteConflictUtil; import ca.uhn.fhir.jpa.delete.DeleteConflictUtil;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource; import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.BaseTag; import ca.uhn.fhir.jpa.model.entity.BaseTag;
import ca.uhn.fhir.jpa.model.entity.ForcedId; import ca.uhn.fhir.jpa.model.entity.ForcedId;
@ -84,7 +85,7 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter; import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.HasParam; import ca.uhn.fhir.rest.param.HasParam;
import ca.uhn.fhir.rest.param.HistorySearchDateRangeParam; import ca.uhn.fhir.rest.param.HistorySearchDateRangeParam;
@ -163,9 +164,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Autowired @Autowired
protected HapiTransactionService myTransactionService; protected HapiTransactionService myTransactionService;
@Autowired @Autowired
private MatchResourceUrlService myMatchResourceUrlService; private MatchResourceUrlService<JpaPid> myMatchResourceUrlService;
@Autowired @Autowired
private SearchBuilderFactory mySearchBuilderFactory; private SearchBuilderFactory<JpaPid> mySearchBuilderFactory;
@Autowired @Autowired
private DaoRegistry myDaoRegistry; private DaoRegistry myDaoRegistry;
@Autowired @Autowired
@ -288,12 +289,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
entity.setVersion(1); entity.setVersion(1);
if (isNotBlank(theMatchUrl) && theProcessMatchUrl) { if (isNotBlank(theMatchUrl) && theProcessMatchUrl) {
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theTransactionDetails, theRequest); Set<JpaPid> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theTransactionDetails, theRequest);
if (match.size() > 1) { if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "CREATE", theMatchUrl, match.size()); String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "CREATE", theMatchUrl, match.size());
throw new PreconditionFailedException(Msg.code(958) + msg); throw new PreconditionFailedException(Msg.code(958) + msg);
} else if (match.size() == 1) { } else if (match.size() == 1) {
ResourcePersistentId pid = match.iterator().next(); JpaPid pid = match.iterator().next();
Supplier<LazyDaoMethodOutcome.EntityAndResource> entitySupplier = () -> { Supplier<LazyDaoMethodOutcome.EntityAndResource> entitySupplier = () -> {
return myTxTemplate.execute(tx -> { return myTxTemplate.execute(tx -> {
@ -308,12 +309,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return myTxTemplate.execute(tx -> { return myTxTemplate.execute(tx -> {
IIdType retVal = myIdHelperService.translatePidIdToForcedId(myFhirContext, myResourceName, pid); IIdType retVal = myIdHelperService.translatePidIdToForcedId(myFhirContext, myResourceName, pid);
if (!retVal.hasVersionIdPart()) { if (!retVal.hasVersionIdPart()) {
IIdType idWithVersion = myMemoryCacheService.getIfPresent(MemoryCacheService.CacheEnum.RESOURCE_CONDITIONAL_CREATE_VERSION, pid.getIdAsLong()); IIdType idWithVersion = myMemoryCacheService.getIfPresent(MemoryCacheService.CacheEnum.RESOURCE_CONDITIONAL_CREATE_VERSION, pid.getId());
if (idWithVersion == null) { if (idWithVersion == null) {
Long version = myResourceTableDao.findCurrentVersionByPid(pid.getIdAsLong()); Long version = myResourceTableDao.findCurrentVersionByPid(pid.getId());
if (version != null) { if (version != null) {
retVal = myFhirContext.getVersion().newIdType().setParts(retVal.getBaseUrl(), retVal.getResourceType(), retVal.getIdPart(), Long.toString(version)); retVal = myFhirContext.getVersion().newIdType().setParts(retVal.getBaseUrl(), retVal.getResourceType(), retVal.getIdPart(), Long.toString(version));
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.RESOURCE_CONDITIONAL_CREATE_VERSION, pid.getIdAsLong(), retVal); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.RESOURCE_CONDITIONAL_CREATE_VERSION, pid.getId(), retVal);
} }
} else { } else {
retVal = idWithVersion; retVal = idWithVersion;
@ -364,7 +365,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ResourceTable updatedEntity = updateEntity(theRequest, theResource, entity, null, thePerformIndexing, false, theTransactionDetails, false, thePerformIndexing); ResourceTable updatedEntity = updateEntity(theRequest, theResource, entity, null, thePerformIndexing, false, theTransactionDetails, false, thePerformIndexing);
// Store the resource forced ID if necessary // Store the resource forced ID if necessary
ResourcePersistentId persistentId = new ResourcePersistentId(updatedEntity.getResourceId()); JpaPid jpaPid = JpaPid.fromId(updatedEntity.getResourceId());
if (resourceHadIdBeforeStorage) { if (resourceHadIdBeforeStorage) {
if (resourceIdWasServerAssigned) { if (resourceIdWasServerAssigned) {
boolean createForPureNumericIds = true; boolean createForPureNumericIds = true;
@ -393,13 +394,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
theResource.setId(entity.getIdDt()); theResource.setId(entity.getIdDt());
// Pre-cache the resource ID // Pre-cache the resource ID
persistentId.setAssociatedResourceId(entity.getIdType(myFhirContext)); jpaPid.setAssociatedResourceId(entity.getIdType(myFhirContext));
myIdHelperService.addResolvedPidToForcedId(persistentId, theRequestPartitionId, getResourceName(), entity.getTransientForcedId(), null); myIdHelperService.addResolvedPidToForcedId(jpaPid, theRequestPartitionId, getResourceName(), entity.getTransientForcedId(), null);
theTransactionDetails.addResolvedResourceId(persistentId.getAssociatedResourceId(), persistentId); theTransactionDetails.addResolvedResourceId(jpaPid.getAssociatedResourceId(), jpaPid);
// Pre-cache the match URL // Pre-cache the match URL
if (theMatchUrl != null) { if (theMatchUrl != null) {
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, getResourceName(), theMatchUrl, persistentId); myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, getResourceName(), theMatchUrl, jpaPid);
} }
// Update the version/last updated in the resource so that interceptors get // Update the version/last updated in the resource so that interceptors get
@ -556,7 +557,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
DaoMethodOutcome outcome = createMethodOutcomeForResourceId(entity.getIdDt().getValue(), MESSAGE_KEY_DELETE_RESOURCE_ALREADY_DELETED, StorageResponseCodeEnum.SUCCESSFUL_DELETE_ALREADY_DELETED); DaoMethodOutcome outcome = createMethodOutcomeForResourceId(entity.getIdDt().getValue(), MESSAGE_KEY_DELETE_RESOURCE_ALREADY_DELETED, StorageResponseCodeEnum.SUCCESSFUL_DELETE_ALREADY_DELETED);
// used to exist, so we'll set the persistent id // used to exist, so we'll set the persistent id
outcome.setPersistentId(new ResourcePersistentId(entity.getResourceId())); outcome.setPersistentId(JpaPid.fromId(entity.getResourceId()));
outcome.setEntity(entity); outcome.setEntity(entity);
return outcome; return outcome;
@ -639,7 +640,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
SearchParameterMap paramMap = resourceSearch.getSearchParameterMap(); SearchParameterMap paramMap = resourceSearch.getSearchParameterMap();
paramMap.setLoadSynchronous(true); paramMap.setLoadSynchronous(true);
Set<ResourcePersistentId> resourceIds = myMatchResourceUrlService.search(paramMap, myResourceType, theRequest, null); Set<JpaPid> resourceIds = myMatchResourceUrlService.search(paramMap, myResourceType, theRequest, null);
if (resourceIds.size() > 1) { if (resourceIds.size() > 1) {
if (!getConfig().isAllowMultipleDelete()) { if (!getConfig().isAllowMultipleDelete()) {
@ -670,12 +671,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Nonnull @Nonnull
@Override @Override
public DeleteMethodOutcome deletePidList(String theUrl, Collection<ResourcePersistentId> theResourceIds, DeleteConflictList theDeleteConflicts, RequestDetails theRequest) { public <P extends IResourcePersistentId> DeleteMethodOutcome deletePidList(String theUrl, Collection<P> theResourceIds, DeleteConflictList theDeleteConflicts, RequestDetails theRequest) {
StopWatch w = new StopWatch(); StopWatch w = new StopWatch();
TransactionDetails transactionDetails = new TransactionDetails(); TransactionDetails transactionDetails = new TransactionDetails();
List<ResourceTable> deletedResources = new ArrayList<>(); List<ResourceTable> deletedResources = new ArrayList<>();
for (ResourcePersistentId pid : theResourceIds) { for (P pid : theResourceIds) {
ResourceTable entity = myEntityManager.find(ResourceTable.class, pid.getIdAsLong()); JpaPid jpaPid = (JpaPid)pid;
ResourceTable entity = myEntityManager.find(ResourceTable.class, jpaPid.getId());
deletedResources.add(entity); deletedResources.add(entity);
T resourceToDelete = myJpaStorageResourceParser.toResource(myResourceType, entity, null, false); T resourceToDelete = myJpaStorageResourceParser.toResource(myResourceType, entity, null, false);
@ -878,10 +880,10 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
throw new PreconditionFailedException(Msg.code(969) + "Can not perform version-specific expunge of resource " + theId.toUnqualified().getValue() + " as this is the current version"); throw new PreconditionFailedException(Msg.code(969) + "Can not perform version-specific expunge of resource " + theId.toUnqualified().getValue() + " as this is the current version");
} }
return myExpungeService.expunge(getResourceName(), new ResourcePersistentId(entity.getResourceId(), entity.getVersion()), theExpungeOptions, theRequest); return myExpungeService.expunge(getResourceName(), JpaPid.fromIdAndVersion(entity.getResourceId(), entity.getVersion()), theExpungeOptions, theRequest);
} }
return myExpungeService.expunge(getResourceName(), new ResourcePersistentId(entity.getResourceId()), theExpungeOptions, theRequest); return myExpungeService.expunge(getResourceName(), JpaPid.fromId(entity.getResourceId()), theExpungeOptions, theRequest);
} }
@Override @Override
@ -1132,18 +1134,19 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Override @Override
@Transactional @Transactional
public T readByPid(ResourcePersistentId thePid) { public T readByPid(IResourcePersistentId thePid) {
return readByPid(thePid, false); return readByPid(thePid, false);
} }
@Override @Override
@Transactional @Transactional
public T readByPid(ResourcePersistentId thePid, boolean theDeletedOk) { public T readByPid(IResourcePersistentId thePid, boolean theDeletedOk) {
StopWatch w = new StopWatch(); StopWatch w = new StopWatch();
JpaPid jpaPid = (JpaPid)thePid;
Optional<ResourceTable> entity = myResourceTableDao.findById(thePid.getIdAsLong()); Optional<ResourceTable> entity = myResourceTableDao.findById(jpaPid.getId());
if (!entity.isPresent()) { if (!entity.isPresent()) {
throw new ResourceNotFoundException(Msg.code(975) + "No resource found with PID " + thePid); throw new ResourceNotFoundException(Msg.code(975) + "No resource found with PID " + jpaPid);
} }
if (isDeleted(entity.get()) && !theDeletedOk) { if (isDeleted(entity.get()) && !theDeletedOk) {
throw createResourceGoneException(entity.get()); throw createResourceGoneException(entity.get());
@ -1151,7 +1154,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
T retVal = myJpaStorageResourceParser.toResource(myResourceType, entity.get(), null, false); T retVal = myJpaStorageResourceParser.toResource(myResourceType, entity.get(), null, false);
ourLog.debug("Processed read on {} in {}ms", thePid, w.getMillis()); ourLog.debug("Processed read on {} in {}ms", jpaPid, w.getMillis());
return retVal; return retVal;
} }
@ -1228,10 +1231,11 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void reindex(ResourcePersistentId theResourcePersistentId, RequestDetails theRequest, TransactionDetails theTransactionDetails) { public void reindex(IResourcePersistentId thePid, RequestDetails theRequest, TransactionDetails theTransactionDetails) {
Optional<ResourceTable> entityOpt = myResourceTableDao.findById(theResourcePersistentId.getIdAsLong()); JpaPid jpaPid = (JpaPid)thePid;
Optional<ResourceTable> entityOpt = myResourceTableDao.findById(jpaPid.getId());
if (!entityOpt.isPresent()) { if (!entityOpt.isPresent()) {
ourLog.warn("Unable to find entity with PID: {}", theResourcePersistentId.getId()); ourLog.warn("Unable to find entity with PID: {}", jpaPid.getId());
return; return;
} }
@ -1253,24 +1257,24 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForRead(theRequest, getResourceName(), theId); RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForRead(theRequest, getResourceName(), theId);
BaseHasResource entity; BaseHasResource entity;
ResourcePersistentId pid = myIdHelperService.resolveResourcePersistentIds(requestPartitionId, getResourceName(), theId.getIdPart()); JpaPid pid = myIdHelperService.resolveResourcePersistentIds(requestPartitionId, getResourceName(), theId.getIdPart());
Set<Integer> readPartitions = null; Set<Integer> readPartitions = null;
if (requestPartitionId.isAllPartitions()) { if (requestPartitionId.isAllPartitions()) {
entity = myEntityManager.find(ResourceTable.class, pid.getIdAsLong()); entity = myEntityManager.find(ResourceTable.class, pid.getId());
} else { } else {
readPartitions = myRequestPartitionHelperService.toReadPartitions(requestPartitionId); readPartitions = myRequestPartitionHelperService.toReadPartitions(requestPartitionId);
if (readPartitions.size() == 1) { if (readPartitions.size() == 1) {
if (readPartitions.contains(null)) { if (readPartitions.contains(null)) {
entity = myResourceTableDao.readByPartitionIdNull(pid.getIdAsLong()).orElse(null); entity = myResourceTableDao.readByPartitionIdNull(pid.getId()).orElse(null);
} else { } else {
entity = myResourceTableDao.readByPartitionId(readPartitions.iterator().next(), pid.getIdAsLong()).orElse(null); entity = myResourceTableDao.readByPartitionId(readPartitions.iterator().next(), pid.getId()).orElse(null);
} }
} else { } else {
if (readPartitions.contains(null)) { if (readPartitions.contains(null)) {
List<Integer> readPartitionsWithoutNull = readPartitions.stream().filter(t -> t != null).collect(Collectors.toList()); List<Integer> readPartitionsWithoutNull = readPartitions.stream().filter(t -> t != null).collect(Collectors.toList());
entity = myResourceTableDao.readByPartitionIdsOrNull(readPartitionsWithoutNull, pid.getIdAsLong()).orElse(null); entity = myResourceTableDao.readByPartitionIdsOrNull(readPartitionsWithoutNull, pid.getId()).orElse(null);
} else { } else {
entity = myResourceTableDao.readByPartitionIds(readPartitions, pid.getIdAsLong()).orElse(null); entity = myResourceTableDao.readByPartitionIds(readPartitions, pid.getId()).orElse(null);
} }
} }
} }
@ -1320,8 +1324,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} }
@Override @Override
protected IBasePersistedResource readEntityLatestVersion(ResourcePersistentId thePersistentId, RequestDetails theRequestDetails, TransactionDetails theTransactionDetails) { protected IBasePersistedResource readEntityLatestVersion(IResourcePersistentId thePersistentId, RequestDetails theRequestDetails, TransactionDetails theTransactionDetails) {
return myEntityManager.find(ResourceTable.class, thePersistentId.getIdAsLong()); JpaPid jpaPid = (JpaPid)thePersistentId;
return myEntityManager.find(ResourceTable.class, jpaPid.getId());
} }
@ -1336,13 +1341,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
private ResourceTable readEntityLatestVersion(IIdType theId, @Nonnull RequestPartitionId theRequestPartitionId, TransactionDetails theTransactionDetails) { private ResourceTable readEntityLatestVersion(IIdType theId, @Nonnull RequestPartitionId theRequestPartitionId, TransactionDetails theTransactionDetails) {
validateResourceTypeAndThrowInvalidRequestException(theId); validateResourceTypeAndThrowInvalidRequestException(theId);
ResourcePersistentId persistentId = null; JpaPid persistentId = null;
if (theTransactionDetails != null) { if (theTransactionDetails != null) {
if (theTransactionDetails.isResolvedResourceIdEmpty(theId.toUnqualifiedVersionless())) { if (theTransactionDetails.isResolvedResourceIdEmpty(theId.toUnqualifiedVersionless())) {
throw new ResourceNotFoundException(Msg.code(1997) + theId); throw new ResourceNotFoundException(Msg.code(1997) + theId);
} }
if (theTransactionDetails.hasResolvedResourceIds()) { if (theTransactionDetails.hasResolvedResourceIds()) {
persistentId = theTransactionDetails.getResolvedResourceId(theId); persistentId = (JpaPid)theTransactionDetails.getResolvedResourceId(theId);
} }
} }
@ -1517,7 +1522,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} }
@Override @Override
public List<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest, @Nullable IBaseResource theConditionalOperationTargetOrNull) { public List<JpaPid> searchForIds(SearchParameterMap theParams, RequestDetails theRequest, @Nullable IBaseResource theConditionalOperationTargetOrNull) {
TransactionDetails transactionDetails = new TransactionDetails(); TransactionDetails transactionDetails = new TransactionDetails();
return myTransactionService.execute(theRequest, transactionDetails, tx -> { return myTransactionService.execute(theRequest, transactionDetails, tx -> {
@ -1530,13 +1535,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ISearchBuilder builder = mySearchBuilderFactory.newSearchBuilder(this, getResourceName(), getResourceType()); ISearchBuilder builder = mySearchBuilderFactory.newSearchBuilder(this, getResourceName(), getResourceType());
List<ResourcePersistentId> ids = new ArrayList<>(); List<JpaPid> ids = new ArrayList<>();
String uuid = UUID.randomUUID().toString(); String uuid = UUID.randomUUID().toString();
RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForSearchType(theRequest, getResourceName(), theParams, theConditionalOperationTargetOrNull); RequestPartitionId requestPartitionId = myRequestPartitionHelperService.determineReadPartitionForRequestForSearchType(theRequest, getResourceName(), theParams, theConditionalOperationTargetOrNull);
SearchRuntimeDetails searchRuntimeDetails = new SearchRuntimeDetails(theRequest, uuid); SearchRuntimeDetails searchRuntimeDetails = new SearchRuntimeDetails(theRequest, uuid);
try (IResultIterator iter = builder.createQuery(theParams, searchRuntimeDetails, theRequest, requestPartitionId)) { try (IResultIterator<JpaPid> iter = builder.createQuery(theParams, searchRuntimeDetails, theRequest, requestPartitionId)) {
while (iter.hasNext()) { while (iter.hasNext()) {
ids.add(iter.next()); ids.add(iter.next());
} }
@ -1652,12 +1657,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
IIdType resourceId; IIdType resourceId;
RestOperationTypeEnum update = RestOperationTypeEnum.UPDATE; RestOperationTypeEnum update = RestOperationTypeEnum.UPDATE;
if (isNotBlank(theMatchUrl)) { if (isNotBlank(theMatchUrl)) {
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theTransactionDetails, theRequest, theResource); Set<JpaPid> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theTransactionDetails, theRequest, theResource);
if (match.size() > 1) { if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size()); String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size());
throw new PreconditionFailedException(Msg.code(988) + msg); throw new PreconditionFailedException(Msg.code(988) + msg);
} else if (match.size() == 1) { } else if (match.size() == 1) {
ResourcePersistentId pid = match.iterator().next(); JpaPid pid = match.iterator().next();
entity = myEntityManager.find(ResourceTable.class, pid.getId()); entity = myEntityManager.find(ResourceTable.class, pid.getId());
resourceId = entity.getIdDt(); resourceId = entity.getIdDt();
} else { } else {
@ -1666,7 +1671,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
// Pre-cache the match URL // Pre-cache the match URL
if (outcome.getPersistentId() != null) { if (outcome.getPersistentId() != null) {
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, getResourceName(), theMatchUrl, outcome.getPersistentId()); myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, getResourceName(), theMatchUrl, (JpaPid)outcome.getPersistentId());
} }
return outcome; return outcome;

View File

@ -7,11 +7,10 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.api.model.ExpungeOptions; import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
import ca.uhn.fhir.jpa.api.model.ExpungeOutcome; import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
import ca.uhn.fhir.jpa.dao.data.IResourceSearchViewDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao; import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
import ca.uhn.fhir.jpa.dao.expunge.ExpungeService; import ca.uhn.fhir.jpa.dao.expunge.ExpungeService;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory; import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory;
@ -20,12 +19,11 @@ import ca.uhn.fhir.jpa.util.QueryChunker;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.StopWatch;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
@ -165,10 +163,10 @@ public abstract class BaseHapiFhirSystemDao<T extends IBaseBundle, MT> extends B
@Override @Override
@Transactional(propagation = Propagation.MANDATORY) @Transactional(propagation = Propagation.MANDATORY)
public void preFetchResources(List<ResourcePersistentId> theResolvedIds) { public <P extends IResourcePersistentId> void preFetchResources(List<P> theResolvedIds) {
List<Long> pids = theResolvedIds List<Long> pids = theResolvedIds
.stream() .stream()
.map(t -> t.getIdAsLong()) .map(t -> ((JpaPid) t).getId())
.collect(Collectors.toList()); .collect(Collectors.toList());
new QueryChunker<Long>().chunk(pids, ids->{ new QueryChunker<Long>().chunk(pids, ids->{

View File

@ -30,6 +30,7 @@ import ca.uhn.fhir.jpa.dao.search.ExtendedHSearchResourceProjection;
import ca.uhn.fhir.jpa.dao.search.ExtendedHSearchSearchBuilder; import ca.uhn.fhir.jpa.dao.search.ExtendedHSearchSearchBuilder;
import ca.uhn.fhir.jpa.dao.search.IHSearchSortHelper; import ca.uhn.fhir.jpa.dao.search.IHSearchSortHelper;
import ca.uhn.fhir.jpa.dao.search.LastNOperation; import ca.uhn.fhir.jpa.dao.search.LastNOperation;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.search.ExtendedHSearchIndexData; import ca.uhn.fhir.jpa.model.search.ExtendedHSearchIndexData;
@ -43,7 +44,7 @@ import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.rest.server.util.ResourceSearchParams; import ca.uhn.fhir.rest.server.util.ResourceSearchParams;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
@ -156,7 +157,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
// keep this in sync with supportsSomeOf(); // keep this in sync with supportsSomeOf();
private ISearchQueryExecutor doSearch(String theResourceType, SearchParameterMap theParams, private ISearchQueryExecutor doSearch(String theResourceType, SearchParameterMap theParams,
ResourcePersistentId theReferencingPid, Integer theMaxResultsToFetch) { IResourcePersistentId theReferencingPid, Integer theMaxResultsToFetch) {
int offset = theParams.getOffset() == null ? 0 : theParams.getOffset(); int offset = theParams.getOffset() == null ? 0 : theParams.getOffset();
int count = getMaxFetchSize(theParams, theMaxResultsToFetch); int count = getMaxFetchSize(theParams, theMaxResultsToFetch);
@ -185,7 +186,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
private SearchQueryOptionsStep<?, Long, SearchLoadingOptionsStep, ?, ?> getSearchQueryOptionsStep( private SearchQueryOptionsStep<?, Long, SearchLoadingOptionsStep, ?, ?> getSearchQueryOptionsStep(
String theResourceType, SearchParameterMap theParams, ResourcePersistentId theReferencingPid) { String theResourceType, SearchParameterMap theParams, IResourcePersistentId theReferencingPid) {
dispatchEvent(IHSearchEventListener.HSearchEventType.SEARCH); dispatchEvent(IHSearchEventListener.HSearchEventType.SEARCH);
var query= getSearchSession().search(ResourceTable.class) var query= getSearchSession().search(ResourceTable.class)
@ -213,7 +214,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
private PredicateFinalStep buildWhereClause(SearchPredicateFactory f, String theResourceType, private PredicateFinalStep buildWhereClause(SearchPredicateFactory f, String theResourceType,
SearchParameterMap theParams, ResourcePersistentId theReferencingPid) { SearchParameterMap theParams, IResourcePersistentId theReferencingPid) {
return f.bool(b -> { return f.bool(b -> {
ExtendedHSearchClauseBuilder builder = new ExtendedHSearchClauseBuilder(myFhirContext, myModelConfig, b, f); ExtendedHSearchClauseBuilder builder = new ExtendedHSearchClauseBuilder(myFhirContext, myModelConfig, b, f);
@ -261,18 +262,18 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
return Search.session(myEntityManager); return Search.session(myEntityManager);
} }
private List<ResourcePersistentId> convertLongsToResourcePersistentIds(List<Long> theLongPids) { private List<IResourcePersistentId> convertLongsToResourcePersistentIds(List<Long> theLongPids) {
return theLongPids.stream() return theLongPids.stream()
.map(ResourcePersistentId::new) .map(JpaPid::fromId)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override @Override
public List<ResourcePersistentId> everything(String theResourceName, SearchParameterMap theParams, ResourcePersistentId theReferencingPid) { public List<IResourcePersistentId> everything(String theResourceName, SearchParameterMap theParams, IResourcePersistentId theReferencingPid) {
validateHibernateSearchIsEnabled(); validateHibernateSearchIsEnabled();
// todo mb what about max results here? // todo mb what about max results here?
List<ResourcePersistentId> retVal = toList(doSearch(null, theParams, theReferencingPid, 10_000), 10_000); List<IResourcePersistentId> retVal = toList(doSearch(null, theParams, theReferencingPid, 10_000), 10_000);
if (theReferencingPid != null) { if (theReferencingPid != null) {
retVal.add(theReferencingPid); retVal.add(theReferencingPid);
} }
@ -310,7 +311,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
@Transactional() @Transactional()
@Override @Override
public List<ResourcePersistentId> search(String theResourceName, SearchParameterMap theParams) { public List<IResourcePersistentId> search(String theResourceName, SearchParameterMap theParams) {
validateHibernateSearchIsEnabled(); validateHibernateSearchIsEnabled();
return toList(doSearch(theResourceName, theParams, null, DEFAULT_MAX_NON_PAGED_SIZE), DEFAULT_MAX_NON_PAGED_SIZE); return toList(doSearch(theResourceName, theParams, null, DEFAULT_MAX_NON_PAGED_SIZE), DEFAULT_MAX_NON_PAGED_SIZE);
} }
@ -318,9 +319,9 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
/** /**
* Adapt our async interface to the legacy concrete List * Adapt our async interface to the legacy concrete List
*/ */
private List<ResourcePersistentId> toList(ISearchQueryExecutor theSearchResultStream, long theMaxSize) { private List<IResourcePersistentId> toList(ISearchQueryExecutor theSearchResultStream, long theMaxSize) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(theSearchResultStream, 0), false) return StreamSupport.stream(Spliterators.spliteratorUnknownSize(theSearchResultStream, 0), false)
.map(ResourcePersistentId::new) .map(JpaPid::fromId)
.limit(theMaxSize) .limit(theMaxSize)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -356,7 +357,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
} }
@Override @Override
public List<ResourcePersistentId> lastN(SearchParameterMap theParams, Integer theMaximumResults) { public List<IResourcePersistentId> lastN(SearchParameterMap theParams, Integer theMaximumResults) {
ensureElastic(); ensureElastic();
dispatchEvent(IHSearchEventListener.HSearchEventType.SEARCH); dispatchEvent(IHSearchEventListener.HSearchEventType.SEARCH);
List<Long> pidList = new LastNOperation(getSearchSession(), myFhirContext, myModelConfig, mySearchParamRegistry) List<Long> pidList = new LastNOperation(getSearchSession(), myFhirContext, myModelConfig, mySearchParamRegistry)

View File

@ -27,8 +27,8 @@ import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.model.PersistentIdToForcedIdMap; import ca.uhn.fhir.jpa.api.model.PersistentIdToForcedIdMap;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.HistorySearchStyleEnum; import ca.uhn.fhir.rest.param.HistorySearchStyleEnum;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableListMultimap;
@ -128,7 +128,7 @@ public class HistoryBuilder {
List<ResourceHistoryTable> tables = query.getResultList(); List<ResourceHistoryTable> tables = query.getResultList();
if (tables.size() > 0) { if (tables.size() > 0) {
ImmutableListMultimap<Long, ResourceHistoryTable> resourceIdToHistoryEntries = Multimaps.index(tables, ResourceHistoryTable::getResourceId); ImmutableListMultimap<Long, ResourceHistoryTable> resourceIdToHistoryEntries = Multimaps.index(tables, ResourceHistoryTable::getResourceId);
Set<ResourcePersistentId> pids = resourceIdToHistoryEntries.keySet().stream().map(t-> new ResourcePersistentId(t)).collect(Collectors.toSet()); Set<JpaPid> pids = resourceIdToHistoryEntries.keySet().stream().map(JpaPid::fromId).collect(Collectors.toSet());
PersistentIdToForcedIdMap pidToForcedId = myIdHelperService.translatePidsToForcedIds(pids); PersistentIdToForcedIdMap pidToForcedId = myIdHelperService.translatePidsToForcedIds(pids);
ourLog.trace("Translated IDs: {}", pidToForcedId.getResourcePersistentIdOptionalMap()); ourLog.trace("Translated IDs: {}", pidToForcedId.getResourcePersistentIdOptionalMap());
@ -137,7 +137,7 @@ public class HistoryBuilder {
String resourceId; String resourceId;
Optional<String> forcedId = pidToForcedId.get(new ResourcePersistentId(nextResourceId)); Optional<String> forcedId = pidToForcedId.get(JpaPid.fromId(nextResourceId));
if (forcedId.isPresent()) { if (forcedId.isPresent()) {
resourceId = forcedId.get(); resourceId = forcedId.get();
} else { } else {

View File

@ -26,7 +26,7 @@ import ca.uhn.fhir.jpa.search.autocomplete.ValueSetAutocompleteOptions;
import ca.uhn.fhir.jpa.search.builder.ISearchQueryExecutor; import ca.uhn.fhir.jpa.search.builder.ISearchQueryExecutor;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams; import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.Collection; import java.util.Collection;
@ -43,7 +43,7 @@ public interface IFulltextSearchSvc {
* @param theParams the full query - modified to return only params unused by the index. * @param theParams the full query - modified to return only params unused by the index.
* @return the pid list for the matchign resources. * @return the pid list for the matchign resources.
*/ */
List<ResourcePersistentId> search(String theResourceName, SearchParameterMap theParams); <T extends IResourcePersistentId> List<T> search(String theResourceName, SearchParameterMap theParams);
/** /**
@ -63,7 +63,7 @@ public interface IFulltextSearchSvc {
*/ */
IBaseResource tokenAutocompleteValueSetSearch(ValueSetAutocompleteOptions theOptions); IBaseResource tokenAutocompleteValueSetSearch(ValueSetAutocompleteOptions theOptions);
List<ResourcePersistentId> everything(String theResourceName, SearchParameterMap theParams, ResourcePersistentId theReferencingPid); <T extends IResourcePersistentId> List<T> everything(String theResourceName, SearchParameterMap theParams, T theReferencingPid);
boolean isDisabled(); boolean isDisabled();
@ -81,7 +81,7 @@ public interface IFulltextSearchSvc {
*/ */
void reindex(ResourceTable theEntity); void reindex(ResourceTable theEntity);
List<ResourcePersistentId> lastN(SearchParameterMap theParams, Integer theMaximumResults); List<IResourcePersistentId> lastN(SearchParameterMap theParams, Integer theMaximumResults);
/** /**
* Returns inlined resource stored along with index mappings for matched identifiers * Returns inlined resource stored along with index mappings for matched identifiers

View File

@ -36,7 +36,7 @@ import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.util.LogicUtil; import ca.uhn.fhir.jpa.util.LogicUtil;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -88,9 +88,9 @@ public class JpaResourceDaoCodeSystem<T extends IBaseResource> extends BaseHapiF
@Override @Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) { public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
List<IIdType> valueSetIds; List<IIdType> valueSetIds;
List<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(org.hl7.fhir.r4.model.CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest); List<IResourcePersistentId> ids = searchForIds(new SearchParameterMap(org.hl7.fhir.r4.model.CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
valueSetIds = new ArrayList<>(); valueSetIds = new ArrayList<>();
for (ResourcePersistentId next : ids) { for (IResourcePersistentId next : ids) {
IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "CodeSystem", next); IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "CodeSystem", next);
valueSetIds.add(id); valueSetIds.add(id);
} }

View File

@ -31,7 +31,6 @@ import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Composition;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -34,7 +35,6 @@ import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.ReferenceOrListParam; import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
@ -152,8 +152,8 @@ public class JpaResourceDaoObservation<T extends IBaseResource> extends BaseHapi
for (IQueryParameterType nextOr : nextPatientList) { for (IQueryParameterType nextOr : nextPatientList) {
if (nextOr instanceof ReferenceParam) { if (nextOr instanceof ReferenceParam) {
ReferenceParam ref = (ReferenceParam) nextOr; ReferenceParam ref = (ReferenceParam) nextOr;
ResourcePersistentId pid = myIdHelperService.resolveResourcePersistentIds(requestPartitionId, ref.getResourceType(), ref.getIdPart()); JpaPid pid = myIdHelperService.resolveResourcePersistentIds(requestPartitionId, ref.getResourceType(), ref.getIdPart());
orderedSubjectReferenceMap.put(pid.getIdAsLong(), nextOr); orderedSubjectReferenceMap.put(pid.getId(), nextOr);
} else { } else {
throw new IllegalArgumentException(Msg.code(942) + "Invalid token type (expecting ReferenceParam): " + nextOr.getClass()); throw new IllegalArgumentException(Msg.code(942) + "Invalid token type (expecting ReferenceParam): " + nextOr.getClass());
} }

View File

@ -28,16 +28,14 @@ import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.config.HapiFhirHibernateJpaDialect; import ca.uhn.fhir.jpa.config.HapiFhirHibernateJpaDialect;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.StopWatch;
@ -90,7 +88,7 @@ public class TransactionProcessor extends BaseTransactionProcessor {
@Autowired(required = false) @Autowired(required = false)
private HapiFhirHibernateJpaDialect myHapiFhirHibernateJpaDialect; private HapiFhirHibernateJpaDialect myHapiFhirHibernateJpaDialect;
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<JpaPid> myIdHelperService;
@Autowired @Autowired
private PartitionSettings myPartitionSettings; private PartitionSettings myPartitionSettings;
@Autowired @Autowired
@ -98,7 +96,7 @@ public class TransactionProcessor extends BaseTransactionProcessor {
@Autowired @Autowired
private FhirContext myFhirContext; private FhirContext myFhirContext;
@Autowired @Autowired
private MatchResourceUrlService myMatchResourceUrlService; private MatchResourceUrlService<JpaPid> myMatchResourceUrlService;
@Autowired @Autowired
private MatchUrlService myMatchUrlService; private MatchUrlService myMatchUrlService;
@Autowired @Autowired
@ -166,12 +164,13 @@ public class TransactionProcessor extends BaseTransactionProcessor {
} }
} }
} }
List<ResourcePersistentId> outcome = myIdHelperService.resolveResourcePersistentIdsWithCache(requestPartitionId, idsToPreResolve); List<JpaPid> outcome = myIdHelperService.resolveResourcePersistentIdsWithCache(requestPartitionId, idsToPreResolve)
for (ResourcePersistentId next : outcome) { .stream().collect(Collectors.toList());
for (JpaPid next : outcome) {
foundIds.add(next.getAssociatedResourceId().toUnqualifiedVersionless().getValue()); foundIds.add(next.getAssociatedResourceId().toUnqualifiedVersionless().getValue());
theTransactionDetails.addResolvedResourceId(next.getAssociatedResourceId(), next); theTransactionDetails.addResolvedResourceId(next.getAssociatedResourceId(), next);
if (myDaoConfig.getResourceClientIdStrategy() != DaoConfig.ClientIdStrategyEnum.ANY || !next.getAssociatedResourceId().isIdPartValidLong()) { if (myDaoConfig.getResourceClientIdStrategy() != DaoConfig.ClientIdStrategyEnum.ANY || !next.getAssociatedResourceId().isIdPartValidLong()) {
idsToPreFetch.add(next.getIdAsLong()); idsToPreFetch.add(next.getId());
} }
} }
for (IIdType next : idsToPreResolve) { for (IIdType next : idsToPreResolve) {
@ -192,18 +191,18 @@ public class TransactionProcessor extends BaseTransactionProcessor {
String requestIfNoneExist = versionAdapter.getEntryIfNoneExist(nextEntry); String requestIfNoneExist = versionAdapter.getEntryIfNoneExist(nextEntry);
String resourceType = myFhirContext.getResourceType(resource); String resourceType = myFhirContext.getResourceType(resource);
if ("PUT".equals(verb) && requestUrl != null && requestUrl.contains("?")) { if ("PUT".equals(verb) && requestUrl != null && requestUrl.contains("?")) {
ResourcePersistentId cachedId = myMatchResourceUrlService.processMatchUrlUsingCacheOnly(resourceType, requestUrl); JpaPid cachedId = myMatchResourceUrlService.processMatchUrlUsingCacheOnly(resourceType, requestUrl);
if (cachedId != null) { if (cachedId != null) {
idsToPreFetch.add(cachedId.getIdAsLong()); idsToPreFetch.add(cachedId.getId());
} else if (SINGLE_PARAMETER_MATCH_URL_PATTERN.matcher(requestUrl).matches()) { } else if (SINGLE_PARAMETER_MATCH_URL_PATTERN.matcher(requestUrl).matches()) {
RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(resource); RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(resource);
SearchParameterMap matchUrlSearchMap = myMatchUrlService.translateMatchUrl(requestUrl, resourceDefinition); SearchParameterMap matchUrlSearchMap = myMatchUrlService.translateMatchUrl(requestUrl, resourceDefinition);
searchParameterMapsToResolve.add(new MatchUrlToResolve(requestUrl, matchUrlSearchMap, resourceDefinition)); searchParameterMapsToResolve.add(new MatchUrlToResolve(requestUrl, matchUrlSearchMap, resourceDefinition));
} }
} else if ("POST".equals(verb) && requestIfNoneExist != null && requestIfNoneExist.contains("?")) { } else if ("POST".equals(verb) && requestIfNoneExist != null && requestIfNoneExist.contains("?")) {
ResourcePersistentId cachedId = myMatchResourceUrlService.processMatchUrlUsingCacheOnly(resourceType, requestIfNoneExist); JpaPid cachedId = myMatchResourceUrlService.processMatchUrlUsingCacheOnly(resourceType, requestIfNoneExist);
if (cachedId != null) { if (cachedId != null) {
idsToPreFetch.add(cachedId.getIdAsLong()); idsToPreFetch.add(cachedId.getId());
} else if (SINGLE_PARAMETER_MATCH_URL_PATTERN.matcher(requestIfNoneExist).matches()) { } else if (SINGLE_PARAMETER_MATCH_URL_PATTERN.matcher(requestIfNoneExist).matches()) {
RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(resource); RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(resource);
SearchParameterMap matchUrlSearchMap = myMatchUrlService.translateMatchUrl(requestIfNoneExist, resourceDefinition); SearchParameterMap matchUrlSearchMap = myMatchUrlService.translateMatchUrl(requestIfNoneExist, resourceDefinition);
@ -277,7 +276,7 @@ public class TransactionProcessor extends BaseTransactionProcessor {
} }
IFhirSystemDao<?,?> systemDao = myApplicationContext.getBean(IFhirSystemDao.class); IFhirSystemDao<?,?> systemDao = myApplicationContext.getBean(IFhirSystemDao.class);
systemDao.preFetchResources(ResourcePersistentId.fromLongList(idsToPreFetch)); systemDao.preFetchResources(JpaPid.fromLongList(idsToPreFetch));
} }
@ -322,8 +321,8 @@ public class TransactionProcessor extends BaseTransactionProcessor {
private void setSearchToResolvedAndPrefetchFoundResourcePid(TransactionDetails theTransactionDetails, List<Long> idsToPreFetch, ResourceIndexedSearchParamToken nextResult, MatchUrlToResolve nextSearchParameterMap) { private void setSearchToResolvedAndPrefetchFoundResourcePid(TransactionDetails theTransactionDetails, List<Long> idsToPreFetch, ResourceIndexedSearchParamToken nextResult, MatchUrlToResolve nextSearchParameterMap) {
ourLog.debug("Matched url {} from database", nextSearchParameterMap.myRequestUrl); ourLog.debug("Matched url {} from database", nextSearchParameterMap.myRequestUrl);
idsToPreFetch.add(nextResult.getResourcePid()); idsToPreFetch.add(nextResult.getResourcePid());
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid())); myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, JpaPid.fromId(nextResult.getResourcePid()));
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid())); theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, JpaPid.fromId(nextResult.getResourcePid()));
nextSearchParameterMap.setResolved(true); nextSearchParameterMap.setResolved(true);
} }

View File

@ -45,13 +45,13 @@ import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao; import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao; import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ForcedId; import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster; import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
@ -74,8 +74,8 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@Service @Service
public class ResourceExpungeService implements IResourceExpungeService { public class JpaResourceExpungeService implements IResourceExpungeService<JpaPid> {
private static final Logger ourLog = LoggerFactory.getLogger(ResourceExpungeService.class); private static final Logger ourLog = LoggerFactory.getLogger(JpaResourceExpungeService.class);
@Autowired @Autowired
private IForcedIdDao myForcedIdDao; private IForcedIdDao myForcedIdDao;
@ -128,7 +128,7 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override @Override
@Transactional @Transactional
public List<ResourcePersistentId> findHistoricalVersionsOfNonDeletedResources(String theResourceName, ResourcePersistentId theResourceId, int theRemainingCount) { public List<JpaPid> findHistoricalVersionsOfNonDeletedResources(String theResourceName, JpaPid theJpaPid, int theRemainingCount) {
if (isEmptyQuery(theRemainingCount)) { if (isEmptyQuery(theRemainingCount)) {
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
} }
@ -136,11 +136,11 @@ public class ResourceExpungeService implements IResourceExpungeService {
Pageable page = PageRequest.of(0, theRemainingCount); Pageable page = PageRequest.of(0, theRemainingCount);
Slice<Long> ids; Slice<Long> ids;
if (theResourceId != null && theResourceId.getId() != null) { if (theJpaPid != null && theJpaPid.getId() != null) {
if (theResourceId.getVersion() != null) { if (theJpaPid.getVersion() != null) {
ids = toSlice(myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(theResourceId.getIdAsLong(), theResourceId.getVersion())); ids = toSlice(myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(theJpaPid.getId(), theJpaPid.getVersion()));
} else { } else {
ids = myResourceHistoryTableDao.findIdsOfPreviousVersionsOfResourceId(page, theResourceId.getIdAsLong()); ids = myResourceHistoryTableDao.findIdsOfPreviousVersionsOfResourceId(page, theJpaPid.getId());
} }
} else { } else {
if (theResourceName != null) { if (theResourceName != null) {
@ -150,12 +150,12 @@ public class ResourceExpungeService implements IResourceExpungeService {
} }
} }
return ResourcePersistentId.fromLongList(ids.getContent()); return JpaPid.fromLongList(ids.getContent());
} }
@Override @Override
@Transactional @Transactional
public List<ResourcePersistentId> findHistoricalVersionsOfDeletedResources(String theResourceName, ResourcePersistentId theResourceId, int theRemainingCount) { public List<JpaPid> findHistoricalVersionsOfDeletedResources(String theResourceName, JpaPid theResourceId, int theRemainingCount) {
if (isEmptyQuery(theRemainingCount)) { if (isEmptyQuery(theRemainingCount)) {
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
} }
@ -163,7 +163,7 @@ public class ResourceExpungeService implements IResourceExpungeService {
Pageable page = PageRequest.of(0, theRemainingCount); Pageable page = PageRequest.of(0, theRemainingCount);
Slice<Long> ids; Slice<Long> ids;
if (theResourceId != null) { if (theResourceId != null) {
ids = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId.getIdAsLong(), theResourceName); ids = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId.getId(), theResourceName);
ourLog.info("Expunging {} deleted resources of type[{}] and ID[{}]", ids.getNumberOfElements(), theResourceName, theResourceId); ourLog.info("Expunging {} deleted resources of type[{}] and ID[{}]", ids.getNumberOfElements(), theResourceName, theResourceId);
} else { } else {
if (theResourceName != null) { if (theResourceName != null) {
@ -174,14 +174,14 @@ public class ResourceExpungeService implements IResourceExpungeService {
ourLog.info("Expunging {} deleted resources (all types)", ids.getNumberOfElements()); ourLog.info("Expunging {} deleted resources (all types)", ids.getNumberOfElements());
} }
} }
return ResourcePersistentId.fromLongList(ids.getContent()); return JpaPid.fromLongList(ids.getContent());
} }
@Override @Override
@Transactional @Transactional
public void expungeCurrentVersionOfResources(RequestDetails theRequestDetails, List<ResourcePersistentId> theResourceIds, AtomicInteger theRemainingCount) { public void expungeCurrentVersionOfResources(RequestDetails theRequestDetails, List<JpaPid> theResourceIds, AtomicInteger theRemainingCount) {
for (ResourcePersistentId next : theResourceIds) { for (JpaPid next : theResourceIds) {
expungeCurrentVersionOfResource(theRequestDetails, next.getIdAsLong(), theRemainingCount); expungeCurrentVersionOfResource(theRequestDetails,(next).getId(), theRemainingCount);
if (expungeLimitReached(theRemainingCount)) { if (expungeLimitReached(theRemainingCount)) {
return; return;
} }
@ -236,9 +236,9 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override @Override
@Transactional @Transactional
public void expungeHistoricalVersionsOfIds(RequestDetails theRequestDetails, List<ResourcePersistentId> theResourceIds, AtomicInteger theRemainingCount) { public void expungeHistoricalVersionsOfIds(RequestDetails theRequestDetails, List<JpaPid> theResourceIds, AtomicInteger theRemainingCount) {
for (ResourcePersistentId next : theResourceIds) { for (JpaPid next : theResourceIds) {
expungeHistoricalVersionsOfId(theRequestDetails, next.getIdAsLong(), theRemainingCount); expungeHistoricalVersionsOfId(theRequestDetails, (next).getId(), theRemainingCount);
if (expungeLimitReached(theRemainingCount)) { if (expungeLimitReached(theRemainingCount)) {
return; return;
} }
@ -247,9 +247,9 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override @Override
@Transactional @Transactional
public void expungeHistoricalVersions(RequestDetails theRequestDetails, List<ResourcePersistentId> theHistoricalIds, AtomicInteger theRemainingCount) { public void expungeHistoricalVersions(RequestDetails theRequestDetails, List<JpaPid> theHistoricalIds, AtomicInteger theRemainingCount) {
for (ResourcePersistentId next : theHistoricalIds) { for (JpaPid next : theHistoricalIds) {
expungeHistoricalVersion(theRequestDetails, next.getIdAsLong(), theRemainingCount); expungeHistoricalVersion(theRequestDetails, (next).getId(), theRemainingCount);
if (expungeLimitReached(theRemainingCount)) { if (expungeLimitReached(theRemainingCount)) {
return; return;
} }
@ -266,7 +266,7 @@ public class ResourceExpungeService implements IResourceExpungeService {
ourLog.info("Expunging current version of resource {}", resource.getIdDt().getValue()); ourLog.info("Expunging current version of resource {}", resource.getIdDt().getValue());
deleteAllSearchParams(new ResourcePersistentId(resource.getResourceId())); deleteAllSearchParams(JpaPid.fromId(resource.getResourceId()));
myResourceTagDao.deleteByResourceId(resource.getId()); myResourceTagDao.deleteByResourceId(resource.getId());
@ -282,44 +282,45 @@ public class ResourceExpungeService implements IResourceExpungeService {
@Override @Override
@Transactional @Transactional
public void deleteAllSearchParams(ResourcePersistentId theResourceId) { public void deleteAllSearchParams(JpaPid theResourceId) {
ResourceTable resource = myResourceTableDao.findById(theResourceId.getIdAsLong()).orElse(null); Long theResourceLongId = theResourceId.getId();
ResourceTable resource = myResourceTableDao.findById(theResourceLongId).orElse(null);
if (resource == null || resource.isParamsUriPopulated()) { if (resource == null || resource.isParamsUriPopulated()) {
myResourceIndexedSearchParamUriDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamUriDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsCoordsPopulated()) { if (resource == null || resource.isParamsCoordsPopulated()) {
myResourceIndexedSearchParamCoordsDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamCoordsDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsDatePopulated()) { if (resource == null || resource.isParamsDatePopulated()) {
myResourceIndexedSearchParamDateDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamDateDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsNumberPopulated()) { if (resource == null || resource.isParamsNumberPopulated()) {
myResourceIndexedSearchParamNumberDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamNumberDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsQuantityPopulated()) { if (resource == null || resource.isParamsQuantityPopulated()) {
myResourceIndexedSearchParamQuantityDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamQuantityDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsQuantityNormalizedPopulated()) { if (resource == null || resource.isParamsQuantityNormalizedPopulated()) {
myResourceIndexedSearchParamQuantityNormalizedDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamQuantityNormalizedDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsStringPopulated()) { if (resource == null || resource.isParamsStringPopulated()) {
myResourceIndexedSearchParamStringDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamStringDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsTokenPopulated()) { if (resource == null || resource.isParamsTokenPopulated()) {
myResourceIndexedSearchParamTokenDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedSearchParamTokenDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsComboStringUniquePresent()) { if (resource == null || resource.isParamsComboStringUniquePresent()) {
myResourceIndexedCompositeStringUniqueDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedCompositeStringUniqueDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isParamsComboTokensNonUniquePresent()) { if (resource == null || resource.isParamsComboTokensNonUniquePresent()) {
myResourceIndexedComboTokensNonUniqueDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceIndexedComboTokensNonUniqueDao.deleteByResourceId(theResourceLongId);
} }
if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.ENABLED) { if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.ENABLED) {
mySearchParamPresentDao.deleteByResourceId(theResourceId.getIdAsLong()); mySearchParamPresentDao.deleteByResourceId(theResourceLongId);
} }
if (resource == null || resource.isHasLinks()) { if (resource == null || resource.isHasLinks()) {
myResourceLinkDao.deleteByResourceId(theResourceId.getIdAsLong()); myResourceLinkDao.deleteByResourceId(theResourceLongId);
} }
} }

View File

@ -1,97 +0,0 @@
package ca.uhn.fhir.jpa.dao.index;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;
/**
* This class is an analog to {@link IIdHelperService} but with additional JPA server methods
* added.
*
* JA 2022-02-17 - I moved these methods out of IdHelperService because I want to reuse
* IdHelperService in storage-engine-neutral batch tasks such as bulk import. These methods
* are all just being used by MDM, so they're JPA specific. I believe it should be possible
* though to just replace all of these calls with equivalents from IdHelperService,
* at which point this interface and its implementation could just go away.
*
* All of the methods here aren't partition aware, so it's not great to use them
* anyhow. The equivalents in {@link IIdHelperService} are probably a bit more
* clunky because you have to convert between {@link Long} and
* {@link ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId} to use them,
* but they also have caching and partition awareness so the tradeoff for that
* extra effort is that they are better.
*/
public interface IJpaIdHelperService extends IIdHelperService {
/**
* @deprecated This method doesn't take a partition ID as input, so it is unsafe. It
* should be reworked to include the partition ID before any new use is incorporated
*/
@Deprecated
@Nonnull
List<Long> getPidsOrThrowException(List<IIdType> theIds);
/**
* @deprecated This method doesn't take a partition ID as input, so it is unsafe. It
* should be reworked to include the partition ID before any new use is incorporated
*/
@Deprecated
@Nullable
Long getPidOrNull(IBaseResource theResource);
/**
* @deprecated This method doesn't take a partition ID as input, so it is unsafe. It
* should be reworked to include the partition ID before any new use is incorporated
*/
@Deprecated
@Nonnull
Long getPidOrThrowException(IIdType theId);
@Nonnull
ResourcePersistentId getPidOrThrowException(@Nonnull IAnyResource theResource);
IIdType resourceIdFromPidOrThrowException(Long thePid);
/**
* Given a set of PIDs, return a set of public FHIR Resource IDs.
* This function will resolve a forced ID if it resolves, and if it fails to resolve to a forced it, will just return the pid
* Example:
* Let's say we have Patient/1(pid == 1), Patient/pat1 (pid == 2), Patient/3 (pid == 3), their pids would resolve as follows:
* <p>
* [1,2,3] -> ["1","pat1","3"]
*
* @param thePids The Set of pids you would like to resolve to external FHIR Resource IDs.
* @return A Set of strings representing the FHIR IDs of the pids.
*/
Set<String> translatePidsToFhirResourceIds(Set<ResourcePersistentId> thePids);
}

View File

@ -30,14 +30,16 @@ import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.cross.IResourceLookup; import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
import ca.uhn.fhir.jpa.model.cross.ResourceLookup; import ca.uhn.fhir.jpa.model.cross.JpaResourceLookup;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ForcedId; import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.search.builder.SearchBuilder; import ca.uhn.fhir.jpa.search.builder.SearchBuilder;
import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.util.QueryChunker; import ca.uhn.fhir.jpa.util.QueryChunker;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.BaseResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -92,13 +94,13 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* <p> * <p>
* This service is highly optimized in order to minimize the number of DB calls as much as possible, * This service is highly optimized in order to minimize the number of DB calls as much as possible,
* since ID resolution is fundamental to many basic operations. This service returns either * since ID resolution is fundamental to many basic operations. This service returns either
* {@link IResourceLookup} or {@link ResourcePersistentId} depending on the method being called. * {@link IResourceLookup} or {@link BaseResourcePersistentId} depending on the method being called.
* The former involves an extra database join that the latter does not require, so selecting the * The former involves an extra database join that the latter does not require, so selecting the
* right method here is important. * right method here is important.
* </p> * </p>
*/ */
@Service @Service
public class IdHelperService implements IIdHelperService { public class IdHelperService implements IIdHelperService<JpaPid> {
public static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[0]; public static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[0];
public static final String RESOURCE_PID = "RESOURCE_PID"; public static final String RESOURCE_PID = "RESOURCE_PID";
@Autowired @Autowired
@ -130,7 +132,7 @@ public class IdHelperService implements IIdHelperService {
*/ */
@Override @Override
@Nonnull @Nonnull
public IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException { public IResourceLookup<JpaPid> resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException {
return resolveResourceIdentity(theRequestPartitionId, theResourceType, theResourceId, false); return resolveResourceIdentity(theRequestPartitionId, theResourceType, theResourceId, false);
} }
@ -143,12 +145,12 @@ public class IdHelperService implements IIdHelperService {
*/ */
@Override @Override
@Nonnull @Nonnull
public IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId, boolean theExcludeDeleted) throws ResourceNotFoundException { public IResourceLookup<JpaPid> resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId, boolean theExcludeDeleted) throws ResourceNotFoundException {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
assert theRequestPartitionId != null; assert theRequestPartitionId != null;
IdDt id = new IdDt(theResourceType, theResourceId); IdDt id = new IdDt(theResourceType, theResourceId);
Map<String, List<IResourceLookup>> matches = translateForcedIdToPids(theRequestPartitionId, Map<String, List<IResourceLookup<JpaPid>>> matches = translateForcedIdToPids(theRequestPartitionId,
Collections.singletonList(id), Collections.singletonList(id),
theExcludeDeleted); theExcludeDeleted);
@ -171,25 +173,25 @@ public class IdHelperService implements IIdHelperService {
} }
/** /**
* Returns a mapping of Id -> ResourcePersistentId. * Returns a mapping of Id -> IResourcePersistentId.
* If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned) * If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned)
*/ */
@Override @Override
@Nonnull @Nonnull
public Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, public Map<String, JpaPid> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId,
String theResourceType, String theResourceType,
List<String> theIds) { List<String> theIds) {
return resolveResourcePersistentIds(theRequestPartitionId, theResourceType, theIds, false); return resolveResourcePersistentIds(theRequestPartitionId, theResourceType, theIds, false);
} }
/** /**
* Returns a mapping of Id -> ResourcePersistentId. * Returns a mapping of Id -> IResourcePersistentId.
* If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned) * If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned)
* Optionally filters out deleted resources. * Optionally filters out deleted resources.
*/ */
@Override @Override
@Nonnull @Nonnull
public Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, public Map<String, JpaPid> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId,
String theResourceType, String theResourceType,
List<String> theIds, List<String> theIds,
boolean theExcludeDeleted) { boolean theExcludeDeleted) {
@ -197,13 +199,13 @@ public class IdHelperService implements IIdHelperService {
Validate.notNull(theIds, "theIds cannot be null"); Validate.notNull(theIds, "theIds cannot be null");
Validate.isTrue(!theIds.isEmpty(), "theIds must not be empty"); Validate.isTrue(!theIds.isEmpty(), "theIds must not be empty");
Map<String, ResourcePersistentId> retVals = new HashMap<>(); Map<String, JpaPid> retVals = new HashMap<>();
for (String id : theIds) { for (String id : theIds) {
ResourcePersistentId retVal; JpaPid retVal;
if (!idRequiresForcedId(id)) { if (!idRequiresForcedId(id)) {
// is already a PID // is already a PID
retVal = new ResourcePersistentId(Long.parseLong(id)); retVal = JpaPid.fromId(Long.parseLong(id));
retVals.put(id, retVal); retVals.put(id, retVal);
} else { } else {
// is a forced id // is a forced id
@ -217,7 +219,7 @@ public class IdHelperService implements IIdHelperService {
retVal = myMemoryCacheService.getThenPutAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, t -> { retVal = myMemoryCacheService.getThenPutAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, t -> {
List<IIdType> ids = Collections.singletonList(new IdType(theResourceType, id)); List<IIdType> ids = Collections.singletonList(new IdType(theResourceType, id));
// fetches from cache using a function that checks cache first... // fetches from cache using a function that checks cache first...
List<ResourcePersistentId> resolvedIds = resolveResourcePersistentIdsWithCache(theRequestPartitionId, ids); List<JpaPid> resolvedIds = resolveResourcePersistentIdsWithCache(theRequestPartitionId, ids);
if (resolvedIds.isEmpty()) { if (resolvedIds.isEmpty()) {
throw new ResourceNotFoundException(Msg.code(1100) + ids.get(0)); throw new ResourceNotFoundException(Msg.code(1100) + ids.get(0));
} }
@ -238,7 +240,7 @@ public class IdHelperService implements IIdHelperService {
*/ */
@Override @Override
@Nonnull @Nonnull
public ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId) { public JpaPid resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId) {
return resolveResourcePersistentIds(theRequestPartitionId, theResourceType, theId, false); return resolveResourcePersistentIds(theRequestPartitionId, theResourceType, theId, false);
} }
@ -249,10 +251,10 @@ public class IdHelperService implements IIdHelperService {
* @throws ResourceNotFoundException If the ID can not be found * @throws ResourceNotFoundException If the ID can not be found
*/ */
@Override @Override
public ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId, boolean theExcludeDeleted){ public JpaPid resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId, boolean theExcludeDeleted){
Validate.notNull(theId, "theId must not be null"); Validate.notNull(theId, "theId must not be null");
Map<String, ResourcePersistentId> retVal = resolveResourcePersistentIds(theRequestPartitionId, Map<String, JpaPid> retVal = resolveResourcePersistentIds(theRequestPartitionId,
theResourceType, theResourceType,
Collections.singletonList(theId), Collections.singletonList(theId),
theExcludeDeleted); theExcludeDeleted);
@ -284,7 +286,7 @@ public class IdHelperService implements IIdHelperService {
*/ */
@Override @Override
@Nonnull @Nonnull
public List<ResourcePersistentId> resolveResourcePersistentIdsWithCache(RequestPartitionId theRequestPartitionId, List<IIdType> theIds) { public List<JpaPid> resolveResourcePersistentIdsWithCache(RequestPartitionId theRequestPartitionId, List<IIdType> theIds) {
boolean onlyForcedIds = false; boolean onlyForcedIds = false;
return resolveResourcePersistentIdsWithCache(theRequestPartitionId, theIds, onlyForcedIds); return resolveResourcePersistentIdsWithCache(theRequestPartitionId, theIds, onlyForcedIds);
} }
@ -299,10 +301,10 @@ public class IdHelperService implements IIdHelperService {
*/ */
@Override @Override
@Nonnull @Nonnull
public List<ResourcePersistentId> resolveResourcePersistentIdsWithCache(RequestPartitionId theRequestPartitionId, List<IIdType> theIds, boolean theOnlyForcedIds) { public List<JpaPid> resolveResourcePersistentIdsWithCache(RequestPartitionId theRequestPartitionId, List<IIdType> theIds, boolean theOnlyForcedIds) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
List<ResourcePersistentId> retVal = new ArrayList<>(theIds.size()); List<JpaPid> retVal = new ArrayList<>(theIds.size());
for (IIdType id : theIds) { for (IIdType id : theIds) {
if (!id.hasIdPart()) { if (!id.hasIdPart()) {
@ -316,14 +318,16 @@ public class IdHelperService implements IIdHelperService {
if (myDaoConfig.getResourceClientIdStrategy() != DaoConfig.ClientIdStrategyEnum.ANY) { if (myDaoConfig.getResourceClientIdStrategy() != DaoConfig.ClientIdStrategyEnum.ANY) {
if (nextId.isIdPartValidLong()) { if (nextId.isIdPartValidLong()) {
if (!theOnlyForcedIds) { if (!theOnlyForcedIds) {
retVal.add(new ResourcePersistentId(nextId.getIdPartAsLong()).setAssociatedResourceId(nextId)); JpaPid jpaPid = JpaPid.fromId(nextId.getIdPartAsLong());
jpaPid.setAssociatedResourceId(nextId);
retVal.add(jpaPid);
} }
continue; continue;
} }
} }
String key = toForcedIdToPidKey(theRequestPartitionId, nextId.getResourceType(), nextId.getIdPart()); String key = toForcedIdToPidKey(theRequestPartitionId, nextId.getResourceType(), nextId.getIdPart());
ResourcePersistentId cachedId = myMemoryCacheService.getIfPresent(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key); JpaPid cachedId = myMemoryCacheService.getIfPresent(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key);
if (cachedId != null) { if (cachedId != null) {
retVal.add(cachedId); retVal.add(cachedId);
continue; continue;
@ -337,7 +341,7 @@ public class IdHelperService implements IIdHelperService {
return retVal; return retVal;
} }
private void doResolvePersistentIds(RequestPartitionId theRequestPartitionId, List<IIdType> theIds, List<ResourcePersistentId> theOutputListToPopulate) { private void doResolvePersistentIds(RequestPartitionId theRequestPartitionId, List<IIdType> theIds, List<JpaPid> theOutputListToPopulate) {
CriteriaBuilder cb = myEntityManager.getCriteriaBuilder(); CriteriaBuilder cb = myEntityManager.getCriteriaBuilder();
CriteriaQuery<ForcedId> criteriaQuery = cb.createQuery(ForcedId.class); CriteriaQuery<ForcedId> criteriaQuery = cb.createQuery(ForcedId.class);
Root<ForcedId> from = criteriaQuery.from(ForcedId.class); Root<ForcedId> from = criteriaQuery.from(ForcedId.class);
@ -365,12 +369,12 @@ public class IdHelperService implements IIdHelperService {
for (ForcedId nextId : results) { for (ForcedId nextId : results) {
// Check if the nextId has a resource ID. It may have a null resource ID if a commit is still pending. // Check if the nextId has a resource ID. It may have a null resource ID if a commit is still pending.
if (nextId.getResourceId() != null) { if (nextId.getResourceId() != null) {
ResourcePersistentId persistentId = new ResourcePersistentId(nextId.getResourceId()); JpaPid jpaPid = JpaPid.fromId(nextId.getResourceId());
populateAssociatedResourceId(nextId.getResourceType(), nextId.getForcedId(), persistentId); populateAssociatedResourceId(nextId.getResourceType(), nextId.getForcedId(), jpaPid);
theOutputListToPopulate.add(persistentId); theOutputListToPopulate.add(jpaPid);
String key = toForcedIdToPidKey(theRequestPartitionId, nextId.getResourceType(), nextId.getForcedId()); String key = toForcedIdToPidKey(theRequestPartitionId, nextId.getResourceType(), nextId.getForcedId());
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, persistentId); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, jpaPid);
} }
} }
} }
@ -401,10 +405,10 @@ public class IdHelperService implements IIdHelperService {
return Optional.empty(); return Optional.empty();
} }
private void populateAssociatedResourceId(String nextResourceType, String forcedId, ResourcePersistentId persistentId) { private void populateAssociatedResourceId(String nextResourceType, String forcedId, JpaPid jpaPid) {
IIdType resourceId = myFhirCtx.getVersion().newIdType(); IIdType resourceId = myFhirCtx.getVersion().newIdType();
resourceId.setValue(nextResourceType + "/" + forcedId); resourceId.setValue(nextResourceType + "/" + forcedId);
persistentId.setAssociatedResourceId(resourceId); jpaPid.setAssociatedResourceId(resourceId);
} }
/** /**
@ -412,7 +416,7 @@ public class IdHelperService implements IIdHelperService {
*/ */
@Nonnull @Nonnull
@Override @Override
public IIdType translatePidIdToForcedId(FhirContext theCtx, String theResourceType, ResourcePersistentId theId) { public IIdType translatePidIdToForcedId(FhirContext theCtx, String theResourceType, JpaPid theId) {
if (theId.getAssociatedResourceId() != null) { if (theId.getAssociatedResourceId() != null) {
return theId.getAssociatedResourceId(); return theId.getAssociatedResourceId();
} }
@ -430,8 +434,8 @@ public class IdHelperService implements IIdHelperService {
} }
@Override @Override
public Optional<String> translatePidIdToForcedIdWithCache(ResourcePersistentId theId) { public Optional<String> translatePidIdToForcedIdWithCache(JpaPid theId) {
return myMemoryCacheService.get(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, theId.getIdAsLong(), pid -> myForcedIdDao.findByResourcePid(pid).map(ForcedId::asTypedFhirResourceId)); return myMemoryCacheService.get(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, theId.getId(), pid -> myForcedIdDao.findByResourcePid(pid).map(ForcedId::asTypedFhirResourceId));
} }
private ListMultimap<String, String> organizeIdsByResourceType(Collection<IIdType> theIds) { private ListMultimap<String, String> organizeIdsByResourceType(Collection<IIdType> theIds) {
@ -448,7 +452,7 @@ public class IdHelperService implements IIdHelperService {
return typeToIds; return typeToIds;
} }
private Map<String, List<IResourceLookup>> translateForcedIdToPids(@Nonnull RequestPartitionId theRequestPartitionId, Collection<IIdType> theId, boolean theExcludeDeleted) { private Map<String, List<IResourceLookup<JpaPid>>> translateForcedIdToPids(@Nonnull RequestPartitionId theRequestPartitionId, Collection<IIdType> theId, boolean theExcludeDeleted) {
assert theRequestPartitionId != null; assert theRequestPartitionId != null;
theId.forEach(id -> Validate.isTrue(id.hasIdPart())); theId.forEach(id -> Validate.isTrue(id.hasIdPart()));
@ -457,7 +461,7 @@ public class IdHelperService implements IIdHelperService {
return new HashMap<>(); return new HashMap<>();
} }
Map<String, List<IResourceLookup>> retVal = new HashMap<>(); Map<String, List<IResourceLookup<JpaPid>>> retVal = new HashMap<>();
RequestPartitionId requestPartitionId = replaceDefault(theRequestPartitionId); RequestPartitionId requestPartitionId = replaceDefault(theRequestPartitionId);
if (myDaoConfig.getResourceClientIdStrategy() != DaoConfig.ClientIdStrategyEnum.ANY) { if (myDaoConfig.getResourceClientIdStrategy() != DaoConfig.ClientIdStrategyEnum.ANY) {
@ -514,7 +518,7 @@ public class IdHelperService implements IIdHelperService {
String forcedId = (String) next[2]; String forcedId = (String) next[2];
Date deletedAt = (Date) next[3]; Date deletedAt = (Date) next[3];
ResourceLookup lookup = new ResourceLookup(resourceType, resourcePid, deletedAt); JpaResourceLookup lookup = new JpaResourceLookup(resourceType, resourcePid, deletedAt);
if (!retVal.containsKey(forcedId)) { if (!retVal.containsKey(forcedId)) {
retVal.put(forcedId, new ArrayList<>()); retVal.put(forcedId, new ArrayList<>());
} }
@ -546,7 +550,7 @@ public class IdHelperService implements IIdHelperService {
return theRequestPartitionId; return theRequestPartitionId;
} }
private void resolvePids(@Nonnull RequestPartitionId theRequestPartitionId, List<Long> thePidsToResolve, Map<String, List<IResourceLookup>> theTargets) { private void resolvePids(@Nonnull RequestPartitionId theRequestPartitionId, List<Long> thePidsToResolve, Map<String, List<IResourceLookup<JpaPid>>> theTargets) {
if (!myDaoConfig.isDeleteEnabled()) { if (!myDaoConfig.isDeleteEnabled()) {
for (Iterator<Long> forcedIdIterator = thePidsToResolve.iterator(); forcedIdIterator.hasNext(); ) { for (Iterator<Long> forcedIdIterator = thePidsToResolve.iterator(); forcedIdIterator.hasNext(); ) {
Long nextPid = forcedIdIterator.next(); Long nextPid = forcedIdIterator.next();
@ -577,7 +581,7 @@ public class IdHelperService implements IIdHelperService {
} }
lookup lookup
.stream() .stream()
.map(t -> new ResourceLookup((String) t[0], (Long) t[1], (Date) t[2])) .map(t -> new JpaResourceLookup((String) t[0], (Long) t[1], (Date) t[2]))
.forEach(t -> { .forEach(t -> {
String id = t.getPersistentId().toString(); String id = t.getPersistentId().toString();
if (!theTargets.containsKey(id)) { if (!theTargets.containsKey(id)) {
@ -594,9 +598,9 @@ public class IdHelperService implements IIdHelperService {
} }
@Override @Override
public PersistentIdToForcedIdMap translatePidsToForcedIds(Set<ResourcePersistentId> theResourceIds) { public PersistentIdToForcedIdMap translatePidsToForcedIds(Set<JpaPid> theResourceIds) {
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive(); assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
Set<Long> thePids = theResourceIds.stream().map(t -> t.getIdAsLong()).collect(Collectors.toSet()); Set<Long> thePids = theResourceIds.stream().map(JpaPid::getId).collect(Collectors.toSet());
Map<Long, Optional<String>> retVal = new HashMap<>(myMemoryCacheService.getAllPresent(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, thePids)); Map<Long, Optional<String>> retVal = new HashMap<>(myMemoryCacheService.getAllPresent(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, thePids));
List<Long> remainingPids = thePids List<Long> remainingPids = thePids
@ -623,10 +627,10 @@ public class IdHelperService implements IIdHelperService {
retVal.put(nextResourcePid, Optional.empty()); retVal.put(nextResourcePid, Optional.empty());
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, nextResourcePid, Optional.empty()); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, nextResourcePid, Optional.empty());
} }
Map<ResourcePersistentId, Optional<String>> convertRetVal = new HashMap<>(); Map<IResourcePersistentId, Optional<String>> convertRetVal = new HashMap<>();
retVal.forEach( retVal.forEach(
(k, v) -> { (k, v) -> {
convertRetVal.put(new ResourcePersistentId(k), v); convertRetVal.put(JpaPid.fromId(k), v);
} }
); );
return new PersistentIdToForcedIdMap(convertRetVal); return new PersistentIdToForcedIdMap(convertRetVal);
@ -636,22 +640,22 @@ public class IdHelperService implements IIdHelperService {
* Pre-cache a PID-to-Resource-ID mapping for later retrieval by {@link #translatePidsToForcedIds(Set)} and related methods * Pre-cache a PID-to-Resource-ID mapping for later retrieval by {@link #translatePidsToForcedIds(Set)} and related methods
*/ */
@Override @Override
public void addResolvedPidToForcedId(ResourcePersistentId theResourcePersistentId, @Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, @Nullable String theForcedId, @Nullable Date theDeletedAt) { public void addResolvedPidToForcedId(JpaPid theJpaPid, @Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, @Nullable String theForcedId, @Nullable Date theDeletedAt) {
if (theForcedId != null) { if (theForcedId != null) {
if (theResourcePersistentId.getAssociatedResourceId() == null) { if (theJpaPid.getAssociatedResourceId() == null) {
populateAssociatedResourceId(theResourceType, theForcedId, theResourcePersistentId); populateAssociatedResourceId(theResourceType, theForcedId, theJpaPid);
} }
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, theResourcePersistentId.getIdAsLong(), Optional.of(theResourceType + "/" + theForcedId)); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, theJpaPid.getId(), Optional.of(theResourceType + "/" + theForcedId));
String key = toForcedIdToPidKey(theRequestPartitionId, theResourceType, theForcedId); String key = toForcedIdToPidKey(theRequestPartitionId, theResourceType, theForcedId);
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, theResourcePersistentId); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.FORCED_ID_TO_PID, key, theJpaPid);
} else { } else {
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, theResourcePersistentId.getIdAsLong(), Optional.empty()); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID, theJpaPid.getId(), Optional.empty());
} }
if (!myDaoConfig.isDeleteEnabled()) { if (!myDaoConfig.isDeleteEnabled()) {
ResourceLookup lookup = new ResourceLookup(theResourceType, theResourcePersistentId.getIdAsLong(), theDeletedAt); JpaResourceLookup lookup = new JpaResourceLookup(theResourceType, theJpaPid.getId(), theDeletedAt);
String nextKey = theResourcePersistentId.toString(); String nextKey = theJpaPid.toString();
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.RESOURCE_LOOKUP, nextKey, lookup); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.RESOURCE_LOOKUP, nextKey, lookup);
} }
@ -677,47 +681,50 @@ public class IdHelperService implements IIdHelperService {
@Override @Override
@Nonnull @Nonnull
public List<ResourcePersistentId> getPidsOrThrowException(@Nonnull RequestPartitionId theRequestPartitionId, List<IIdType> theIds) { public List<JpaPid> getPidsOrThrowException(@Nonnull RequestPartitionId theRequestPartitionId, List<IIdType> theIds) {
List<ResourcePersistentId> resourcePersistentIds = resolveResourcePersistentIdsWithCache(theRequestPartitionId, theIds); List<JpaPid> resourcePersistentIds = resolveResourcePersistentIdsWithCache(theRequestPartitionId, theIds);
return resourcePersistentIds; return resourcePersistentIds;
} }
@Override @Override
@Nullable @Nullable
public ResourcePersistentId getPidOrNull(@Nonnull RequestPartitionId theRequestPartitionId, IBaseResource theResource) { public JpaPid getPidOrNull(@Nonnull RequestPartitionId theRequestPartitionId, IBaseResource theResource) {
ResourcePersistentId retVal = new ResourcePersistentId(theResource.getUserData(RESOURCE_PID)); Object resourceId = theResource.getUserData(RESOURCE_PID);
if (retVal.getId() == null) { JpaPid retVal;
if (resourceId == null) {
IIdType id = theResource.getIdElement(); IIdType id = theResource.getIdElement();
try { try {
retVal = resolveResourcePersistentIds(theRequestPartitionId, id.getResourceType(), id.getIdPart()); retVal = resolveResourcePersistentIds(theRequestPartitionId, id.getResourceType(), id.getIdPart());
} catch (ResourceNotFoundException e) { } catch (ResourceNotFoundException e) {
return null; retVal = null;
} }
} else {
retVal = JpaPid.fromId(Long.parseLong(resourceId.toString()));
} }
return retVal; return retVal;
} }
@Override @Override
@Nonnull @Nonnull
public ResourcePersistentId getPidOrThrowException(@Nonnull RequestPartitionId theRequestPartitionId, IIdType theId) { public JpaPid getPidOrThrowException(@Nonnull RequestPartitionId theRequestPartitionId, IIdType theId) {
List<IIdType> ids = Collections.singletonList(theId); List<IIdType> ids = Collections.singletonList(theId);
List<ResourcePersistentId> resourcePersistentIds = resolveResourcePersistentIdsWithCache(theRequestPartitionId, ids); List<JpaPid> resourcePersistentIds = resolveResourcePersistentIdsWithCache(theRequestPartitionId, ids);
return resourcePersistentIds.get(0); return resourcePersistentIds.get(0);
} }
@Override @Override
@Nonnull @Nonnull
public ResourcePersistentId getPidOrThrowException(@Nonnull IAnyResource theResource) { public JpaPid getPidOrThrowException(@Nonnull IAnyResource theResource) {
Object theResourcePID = theResource.getUserData(RESOURCE_PID); Long theResourcePID = (Long) theResource.getUserData(RESOURCE_PID);
if (theResourcePID == null) { if (theResourcePID == null) {
throw new IllegalStateException(Msg.code(2108) + String.format("Unable to find %s in the user data for %s with ID %s", RESOURCE_PID, theResource, theResource.getId())); throw new IllegalStateException(Msg.code(2108) + String.format("Unable to find %s in the user data for %s with ID %s", RESOURCE_PID, theResource, theResource.getId()));
} }
return new ResourcePersistentId(theResourcePID); return JpaPid.fromId(theResourcePID);
} }
@Override @Override
public IIdType resourceIdFromPidOrThrowException(ResourcePersistentId thePid, String theResourceType) { public IIdType resourceIdFromPidOrThrowException(JpaPid thePid, String theResourceType) {
Optional<ResourceTable> optionalResource = myResourceTableDao.findById(thePid.getIdAsLong()); Optional<ResourceTable> optionalResource = myResourceTableDao.findById(thePid.getId());
if (!optionalResource.isPresent()) { if (!optionalResource.isPresent()) {
throw new ResourceNotFoundException(Msg.code(2124) + "Requested resource not found"); throw new ResourceNotFoundException(Msg.code(2124) + "Requested resource not found");
} }
@ -736,11 +743,21 @@ public class IdHelperService implements IIdHelperService {
* @return A Set of strings representing the FHIR IDs of the pids. * @return A Set of strings representing the FHIR IDs of the pids.
*/ */
@Override @Override
public Set<String> translatePidsToFhirResourceIds(Set<ResourcePersistentId> thePids) { public Set<String> translatePidsToFhirResourceIds(Set<JpaPid> thePids) {
assert TransactionSynchronizationManager.isSynchronizationActive(); assert TransactionSynchronizationManager.isSynchronizationActive();
PersistentIdToForcedIdMap pidToForcedIdMap = translatePidsToForcedIds(thePids); PersistentIdToForcedIdMap pidToForcedIdMap = translatePidsToForcedIds(thePids);
return pidToForcedIdMap.getResolvedResourceIds(); return pidToForcedIdMap.getResolvedResourceIds();
} }
@Override
public JpaPid newPid(Object thePid) {
return JpaPid.fromId((Long) thePid);
}
@Override
public JpaPid newPidFromStringIdAndResourceName(String thePid, String theResourceName) {
return JpaPid.fromIdAndResourceType(Long.parseLong(thePid), theResourceName);
}
} }

View File

@ -1,143 +0,0 @@
package ca.uhn.fhir.jpa.dao.index;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.model.PersistentIdToForcedIdMap;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
/**
* See {@link IJpaIdHelperService} for an explanation of this class.
*/
public class JpaIdHelperService extends IdHelperService implements IJpaIdHelperService, IIdHelperService {
@Autowired
protected IResourceTableDao myResourceTableDao;
/**
* @deprecated This method doesn't take a partition ID as input, so it is unsafe. It
* should be reworked to include the partition ID before any new use is incorporated
*/
@Override
@Deprecated
@Nonnull
public List<Long> getPidsOrThrowException(List<IIdType> theIds) {
List<ResourcePersistentId> resourcePersistentIds = super.resolveResourcePersistentIdsWithCache(RequestPartitionId.allPartitions(), theIds);
return resourcePersistentIds.stream().map(ResourcePersistentId::getIdAsLong).collect(Collectors.toList());
}
/**
* @deprecated This method doesn't take a partition ID as input, so it is unsafe. It
* should be reworked to include the partition ID before any new use is incorporated
*/
@Override
@Deprecated
@Nullable
public Long getPidOrNull(IBaseResource theResource) {
IAnyResource anyResource = (IAnyResource) theResource;
Long retVal = (Long) anyResource.getUserData(RESOURCE_PID);
if (retVal == null) {
IIdType id = theResource.getIdElement();
try {
retVal = super.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), id.getResourceType(), id.getIdPart()).getIdAsLong();
} catch (ResourceNotFoundException e) {
return null;
}
}
return retVal;
}
/**
* @deprecated This method doesn't take a partition ID as input, so it is unsafe. It
* should be reworked to include the partition ID before any new use is incorporated
*/
@Override
@Deprecated
@Nonnull
public Long getPidOrThrowException(IIdType theId) {
assert TransactionSynchronizationManager.isSynchronizationActive();
List<IIdType> ids = Collections.singletonList(theId);
List<ResourcePersistentId> resourcePersistentIds = super.resolveResourcePersistentIdsWithCache(RequestPartitionId.allPartitions(), ids);
return resourcePersistentIds.get(0).getIdAsLong();
}
@Override
@Nonnull
public ResourcePersistentId getPidOrThrowException(@Nonnull IAnyResource theResource) {
Long retVal = (Long) theResource.getUserData(RESOURCE_PID);
if (retVal == null) {
throw new IllegalStateException(Msg.code(1102) + String.format("Unable to find %s in the user data for %s with ID %s", RESOURCE_PID, theResource, theResource.getId())
);
}
return new ResourcePersistentId(retVal);
}
@Override
public IIdType resourceIdFromPidOrThrowException(Long thePid) {
Optional<ResourceTable> optionalResource = myResourceTableDao.findById(thePid);
if (!optionalResource.isPresent()) {
throw new ResourceNotFoundException(Msg.code(1103) + "Requested resource not found");
}
return optionalResource.get().getIdDt().toVersionless();
}
/**
* Given a set of PIDs, return a set of public FHIR Resource IDs.
* This function will resolve a forced ID if it resolves, and if it fails to resolve to a forced it, will just return the pid
* Example:
* Let's say we have Patient/1(pid == 1), Patient/pat1 (pid == 2), Patient/3 (pid == 3), their pids would resolve as follows:
* <p>
* [1,2,3] -> ["1","pat1","3"]
*
* @param thePids The Set of pids you would like to resolve to external FHIR Resource IDs.
* @return A Set of strings representing the FHIR IDs of the pids.
*/
@Override
public Set<String> translatePidsToFhirResourceIds(Set<ResourcePersistentId> thePids) {
assert TransactionSynchronizationManager.isSynchronizationActive();
PersistentIdToForcedIdMap pidToForcedIdMap = super.translatePidsToForcedIds(thePids);
return pidToForcedIdMap.getResolvedResourceIds();
}
}

View File

@ -34,6 +34,7 @@ import ca.uhn.fhir.jpa.dao.MatchResourceUrlService;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboStringUniqueDao; import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboStringUniqueDao;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam; import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboStringUnique; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboStringUnique;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboTokenNonUnique; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboTokenNonUnique;
@ -46,7 +47,6 @@ import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
@ -88,19 +88,19 @@ public class SearchParamWithInlineReferencesExtractor {
@PersistenceContext(type = PersistenceContextType.TRANSACTION) @PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager; protected EntityManager myEntityManager;
@Autowired @Autowired
private MatchResourceUrlService myMatchResourceUrlService; private MatchResourceUrlService<JpaPid> myMatchResourceUrlService;
@Autowired @Autowired
private DaoConfig myDaoConfig; private DaoConfig myDaoConfig;
@Autowired @Autowired
private FhirContext myContext; private FhirContext myContext;
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<JpaPid> myIdHelperService;
@Autowired @Autowired
private ISearchParamRegistry mySearchParamRegistry; private ISearchParamRegistry mySearchParamRegistry;
@Autowired @Autowired
private SearchParamExtractorService mySearchParamExtractorService; private SearchParamExtractorService mySearchParamExtractorService;
@Autowired @Autowired
private DaoResourceLinkResolver myDaoResourceLinkResolver; private DaoResourceLinkResolver<JpaPid> myDaoResourceLinkResolver;
@Autowired @Autowired
private DaoSearchParamSynchronizer myDaoSearchParamSynchronizer; private DaoSearchParamSynchronizer myDaoSearchParamSynchronizer;
@Autowired @Autowired
@ -350,14 +350,14 @@ public class SearchParamWithInlineReferencesExtractor {
Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass(); Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass();
//Attempt to find the target reference before creating a placeholder //Attempt to find the target reference before creating a placeholder
Set<ResourcePersistentId> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType, theTransactionDetails, theRequest); Set<JpaPid> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType, theTransactionDetails, theRequest);
ResourcePersistentId match; JpaPid match;
if (matches.isEmpty()) { if (matches.isEmpty()) {
Optional<IBasePersistedResource> placeholderOpt = myDaoResourceLinkResolver.createPlaceholderTargetIfConfiguredToDoSo(matchResourceType, nextRef, null, theRequest, theTransactionDetails); Optional<IBasePersistedResource> placeholderOpt = myDaoResourceLinkResolver.createPlaceholderTargetIfConfiguredToDoSo(matchResourceType, nextRef, null, theRequest, theTransactionDetails);
if (placeholderOpt.isPresent()) { if (placeholderOpt.isPresent()) {
match = placeholderOpt.get().getPersistentId(); match = (JpaPid) placeholderOpt.get().getPersistentId();
match.setAssociatedResourceId(placeholderOpt.get().getIdDt()); match.setAssociatedResourceId(placeholderOpt.get().getIdDt());
theTransactionDetails.addResolvedMatchUrl(nextIdText, match); theTransactionDetails.addResolvedMatchUrl(nextIdText, match);
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.MATCH_URL, nextIdText, match); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.MATCH_URL, nextIdText, match);

View File

@ -25,13 +25,13 @@ import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.data.IMdmLinkJpaRepository; import ca.uhn.fhir.jpa.dao.data.IMdmLinkJpaRepository;
import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLink;
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest; import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.dao.IMdmLinkDao;
import ca.uhn.fhir.mdm.model.MdmPidTuple; import ca.uhn.fhir.mdm.model.MdmPidTuple;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.ListUtils;
@ -56,81 +56,80 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MdmLinkDaoJpaImpl implements IMdmLinkDao<MdmLink> { public class MdmLinkDaoJpaImpl implements IMdmLinkDao<JpaPid, MdmLink> {
@Autowired @Autowired
IMdmLinkJpaRepository myMdmLinkDao; IMdmLinkJpaRepository myMdmLinkDao;
@Autowired @Autowired
protected EntityManager myEntityManager; protected EntityManager myEntityManager;
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<JpaPid> myIdHelperService;
@Override @Override
public int deleteWithAnyReferenceToPid(ResourcePersistentId thePid) { public int deleteWithAnyReferenceToPid(JpaPid thePid) {
return myMdmLinkDao.deleteWithAnyReferenceToPid(thePid.getIdAsLong()); return myMdmLinkDao.deleteWithAnyReferenceToPid(thePid.getId());
} }
@Override @Override
public int deleteWithAnyReferenceToPidAndMatchResultNot(ResourcePersistentId thePid, MdmMatchResultEnum theMatchResult) { public int deleteWithAnyReferenceToPidAndMatchResultNot(JpaPid thePid, MdmMatchResultEnum theMatchResult) {
return myMdmLinkDao.deleteWithAnyReferenceToPidAndMatchResultNot(thePid.getIdAsLong(), theMatchResult); return myMdmLinkDao.deleteWithAnyReferenceToPidAndMatchResultNot(thePid.getId(), theMatchResult);
} }
@Override @Override
public List<MdmPidTuple> expandPidsFromGroupPidGivenMatchResult(ResourcePersistentId theGroupPid, MdmMatchResultEnum theMdmMatchResultEnum) { public List<MdmPidTuple<JpaPid>> expandPidsFromGroupPidGivenMatchResult(JpaPid theGroupPid, MdmMatchResultEnum theMdmMatchResultEnum) {
return myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(theGroupPid.getIdAsLong(), theMdmMatchResultEnum) return myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult((theGroupPid).getId(), theMdmMatchResultEnum)
.stream() .stream()
.map( theMdmPidTuple -> new MdmPidTuple() .map(this::daoTupleToMdmTuple)
.setSourcePid(new ResourcePersistentId(theMdmPidTuple.getSourcePid())) .collect(Collectors.toList());
.setGoldenPid(new ResourcePersistentId(theMdmPidTuple.getGoldenPid()))) }
private MdmPidTuple<JpaPid> daoTupleToMdmTuple(IMdmLinkJpaRepository.MdmPidTuple theMdmPidTuple) {
return MdmPidTuple.fromGoldenAndSource(JpaPid.fromId(theMdmPidTuple.getGoldenPid()), JpaPid.fromId(theMdmPidTuple.getSourcePid()));
}
@Override
public List<MdmPidTuple<JpaPid>> expandPidsBySourcePidAndMatchResult(JpaPid theSourcePid, MdmMatchResultEnum theMdmMatchResultEnum) {
return myMdmLinkDao.expandPidsBySourcePidAndMatchResult((theSourcePid).getId(), theMdmMatchResultEnum)
.stream()
.map(this::daoTupleToMdmTuple)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override @Override
public List<MdmPidTuple> expandPidsBySourcePidAndMatchResult(ResourcePersistentId theSourcePid, MdmMatchResultEnum theMdmMatchResultEnum) { public List<MdmPidTuple<JpaPid>> expandPidsByGoldenResourcePidAndMatchResult(JpaPid theSourcePid, MdmMatchResultEnum theMdmMatchResultEnum) {
return myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourcePid.getIdAsLong(), theMdmMatchResultEnum) return myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult((theSourcePid).getId(), theMdmMatchResultEnum)
.stream() .stream()
.map( theMdmPidTuple -> new MdmPidTuple() .map(this::daoTupleToMdmTuple)
.setSourcePid(new ResourcePersistentId(theMdmPidTuple.getSourcePid()))
.setGoldenPid(new ResourcePersistentId(theMdmPidTuple.getGoldenPid())))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override @Override
public List<MdmPidTuple> expandPidsByGoldenResourcePidAndMatchResult(ResourcePersistentId theSourcePid, MdmMatchResultEnum theMdmMatchResultEnum) { public List<JpaPid> findPidByResourceNameAndThreshold(String theResourceName, Date theHighThreshold, Pageable thePageable) {
return myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult(theSourcePid.getIdAsLong(), theMdmMatchResultEnum)
.stream()
.map( theMdmPidTuple -> new MdmPidTuple()
.setSourcePid(new ResourcePersistentId(theMdmPidTuple.getSourcePid()))
.setGoldenPid(new ResourcePersistentId(theMdmPidTuple.getGoldenPid())))
.collect(Collectors.toList());
}
@Override
public List<ResourcePersistentId> findPidByResourceNameAndThreshold(String theResourceName, Date theHighThreshold, Pageable thePageable) {
return myMdmLinkDao.findPidByResourceNameAndThreshold(theResourceName,theHighThreshold, thePageable) return myMdmLinkDao.findPidByResourceNameAndThreshold(theResourceName,theHighThreshold, thePageable)
.stream() .stream()
.map( theResourcePids -> new ResourcePersistentId(theResourcePids)) .map( theResourcePids -> JpaPid.fromId(theResourcePids))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override @Override
public List<ResourcePersistentId> findPidByResourceNameAndThresholdAndPartitionId(String theResourceName, Date theHighThreshold, List<Integer> thePartitionIds, Pageable thePageable) { public List<JpaPid> findPidByResourceNameAndThresholdAndPartitionId(String theResourceName, Date theHighThreshold, List<Integer> thePartitionIds, Pageable thePageable) {
return myMdmLinkDao.findPidByResourceNameAndThresholdAndPartitionId(theResourceName,theHighThreshold, thePartitionIds, thePageable) return myMdmLinkDao.findPidByResourceNameAndThresholdAndPartitionId(theResourceName,theHighThreshold, thePartitionIds, thePageable)
.stream() .stream()
.map( theResourcePids -> new ResourcePersistentId(theResourcePids)) .map( theResourcePids -> JpaPid.fromId(theResourcePids))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@Override @Override
public List<MdmLink> findAllById(List<ResourcePersistentId> thePids) { public List<MdmLink> findAllById(List<JpaPid> thePids) {
List<Long> theLongPids = thePids.stream().map(theResourcePersistentId -> theResourcePersistentId.getIdAsLong()).collect(Collectors.toList()); List<Long> theLongPids = thePids.stream().map(JpaPid::getId).collect(Collectors.toList());
return myMdmLinkDao.findAllById(theLongPids); return myMdmLinkDao.findAllById(theLongPids);
} }
@Override @Override
public Optional<MdmLink> findById(ResourcePersistentId thePid) { public Optional<MdmLink> findById(JpaPid thePid) {
return myMdmLinkDao.findById(thePid.getIdAsLong()); return myMdmLinkDao.findById(thePid.getId());
} }
@Override
public void deleteAll(List<MdmLink> theLinks) { public void deleteAll(List<MdmLink> theLinks) {
myMdmLinkDao.deleteAll(theLinks); myMdmLinkDao.deleteAll(theLinks);
} }
@ -190,11 +189,11 @@ public class MdmLinkDaoJpaImpl implements IMdmLinkDao<MdmLink> {
List<Predicate> andPredicates = new ArrayList<>(); List<Predicate> andPredicates = new ArrayList<>();
if (theGoldenResourceId != null) { if (theGoldenResourceId != null) {
Predicate goldenResourcePredicate = criteriaBuilder.equal(from.get("myGoldenResourcePid").as(Long.class), myIdHelperService.getPidOrThrowException(RequestPartitionId.allPartitions(), theGoldenResourceId).getIdAsLong()); Predicate goldenResourcePredicate = criteriaBuilder.equal(from.get("myGoldenResourcePid").as(Long.class), (myIdHelperService.getPidOrThrowException(RequestPartitionId.allPartitions(), theGoldenResourceId)).getId());
andPredicates.add(goldenResourcePredicate); andPredicates.add(goldenResourcePredicate);
} }
if (theSourceId != null) { if (theSourceId != null) {
Predicate sourceIdPredicate = criteriaBuilder.equal(from.get("mySourcePid").as(Long.class), myIdHelperService.getPidOrThrowException(RequestPartitionId.allPartitions(), theSourceId).getIdAsLong()); Predicate sourceIdPredicate = criteriaBuilder.equal(from.get("mySourcePid").as(Long.class), (myIdHelperService.getPidOrThrowException(RequestPartitionId.allPartitions(), theSourceId)).getId());
andPredicates.add(sourceIdPredicate); andPredicates.add(sourceIdPredicate);
} }
if (theMatchResult != null) { if (theMatchResult != null) {
@ -226,13 +225,13 @@ public class MdmLinkDaoJpaImpl implements IMdmLinkDao<MdmLink> {
} }
@Override @Override
public Optional<? extends IMdmLink> findBySourcePidAndMatchResult(ResourcePersistentId theSourcePid, MdmMatchResultEnum theMatch) { public Optional<MdmLink> findBySourcePidAndMatchResult(JpaPid theSourcePid, MdmMatchResultEnum theMatch) {
return myMdmLinkDao.findBySourcePidAndMatchResult(theSourcePid.getIdAsLong(), theMatch); return myMdmLinkDao.findBySourcePidAndMatchResult((theSourcePid).getId(), theMatch);
} }
@Override @Override
public void deleteLinksWithAnyReferenceToPids(List<ResourcePersistentId> theResourcePersistentIds) { public void deleteLinksWithAnyReferenceToPids(List<JpaPid> theResourcePersistentIds) {
List<Long> goldenResourcePids = theResourcePersistentIds.stream().map(ResourcePersistentId::getIdAsLong).collect(Collectors.toList()); List<Long> goldenResourcePids = theResourcePersistentIds.stream().map(JpaPid::getId).collect(Collectors.toList());
// Split into chunks of 500 so older versions of Oracle don't run into issues (500 = 1000 / 2 since the dao // Split into chunks of 500 so older versions of Oracle don't run into issues (500 = 1000 / 2 since the dao
// method uses the list twice in the sql predicate) // method uses the list twice in the sql predicate)
List<List<Long>> chunks = ListUtils.partition(goldenResourcePids, 500); List<List<Long>> chunks = ListUtils.partition(goldenResourcePids, 500);

View File

@ -26,9 +26,8 @@ import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao; import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
import ca.uhn.fhir.jpa.dao.expunge.ResourceForeignKey; import ca.uhn.fhir.jpa.dao.expunge.ResourceForeignKey;
import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider; import ca.uhn.fhir.jpa.dao.expunge.ResourceTableFKProvider;
import ca.uhn.fhir.jpa.dao.index.IJpaIdHelperService; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceLink; import ca.uhn.fhir.jpa.model.entity.ResourceLink;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -58,8 +57,8 @@ public class DeleteExpungeSqlBuilder {
@Nonnull @Nonnull
List<String> convertPidsToDeleteExpungeSql(List<ResourcePersistentId> thePersistentIds) { List<String> convertPidsToDeleteExpungeSql(List<JpaPid> theJpaPids) {
List<Long> pids = ResourcePersistentId.toLongList(thePersistentIds); List<Long> pids = JpaPid.toLongList(theJpaPids);
validateOkToDeleteAndExpunge(pids); validateOkToDeleteAndExpunge(pids);
@ -84,7 +83,7 @@ public class DeleteExpungeSqlBuilder {
return; return;
} }
List<ResourcePersistentId> targetPidsAsResourceIds = ResourcePersistentId.fromLongList(thePids); List<JpaPid> targetPidsAsResourceIds = JpaPid.fromLongList(thePids);
List<ResourceLink> conflictResourceLinks = Collections.synchronizedList(new ArrayList<>()); List<ResourceLink> conflictResourceLinks = Collections.synchronizedList(new ArrayList<>());
findResourceLinksWithTargetPidIn(targetPidsAsResourceIds, targetPidsAsResourceIds, conflictResourceLinks); findResourceLinksWithTargetPidIn(targetPidsAsResourceIds, targetPidsAsResourceIds, conflictResourceLinks);
@ -97,16 +96,16 @@ public class DeleteExpungeSqlBuilder {
//NB-GGG: We previously instantiated these ID values from firstConflict.getSourceResource().getIdDt(), but in a situation where we //NB-GGG: We previously instantiated these ID values from firstConflict.getSourceResource().getIdDt(), but in a situation where we
//actually had to run delete conflict checks in multiple partitions, the executor service starts its own sessions on a per thread basis, and by the time //actually had to run delete conflict checks in multiple partitions, the executor service starts its own sessions on a per thread basis, and by the time
//we arrive here, those sessions are closed. So instead, we resolve them from PIDs, which are eagerly loaded. //we arrive here, those sessions are closed. So instead, we resolve them from PIDs, which are eagerly loaded.
String sourceResourceId = myIdHelper.resourceIdFromPidOrThrowException(new ResourcePersistentId(firstConflict.getSourceResourcePid()), firstConflict.getSourceResourceType()).toVersionless().getValue(); String sourceResourceId = myIdHelper.resourceIdFromPidOrThrowException(JpaPid.fromId(firstConflict.getSourceResourcePid()), firstConflict.getSourceResourceType()).toVersionless().getValue();
String targetResourceId = myIdHelper.resourceIdFromPidOrThrowException(new ResourcePersistentId(firstConflict.getTargetResourcePid()), firstConflict.getTargetResourceType()).toVersionless().getValue(); String targetResourceId = myIdHelper.resourceIdFromPidOrThrowException(JpaPid.fromId(firstConflict.getTargetResourcePid()), firstConflict.getTargetResourceType()).toVersionless().getValue();
throw new InvalidRequestException(Msg.code(822) + "DELETE with _expunge=true failed. Unable to delete " + throw new InvalidRequestException(Msg.code(822) + "DELETE with _expunge=true failed. Unable to delete " +
targetResourceId + " because " + sourceResourceId + " refers to it via the path " + firstConflict.getSourcePath()); targetResourceId + " because " + sourceResourceId + " refers to it via the path " + firstConflict.getSourcePath());
} }
public void findResourceLinksWithTargetPidIn(List<ResourcePersistentId> theAllTargetPids, List<ResourcePersistentId> theSomeTargetPids, List<ResourceLink> theConflictResourceLinks) { public void findResourceLinksWithTargetPidIn(List<JpaPid> theAllTargetPids, List<JpaPid> theSomeTargetPids, List<ResourceLink> theConflictResourceLinks) {
List<Long> allTargetPidsAsLongs = ResourcePersistentId.toLongList(theAllTargetPids); List<Long> allTargetPidsAsLongs = JpaPid.toLongList(theAllTargetPids);
List<Long> someTargetPidsAsLongs = ResourcePersistentId.toLongList(theSomeTargetPids); List<Long> someTargetPidsAsLongs = JpaPid.toLongList(theSomeTargetPids);
// We only need to find one conflict, so if we found one already in an earlier partition run, we can skip the rest of the searches // We only need to find one conflict, so if we found one already in an earlier partition run, we can skip the rest of the searches
if (theConflictResourceLinks.isEmpty()) { if (theConflictResourceLinks.isEmpty()) {
List<ResourceLink> conflictResourceLinks = myResourceLinkDao.findWithTargetPidIn(someTargetPidsAsLongs).stream() List<ResourceLink> conflictResourceLinks = myResourceLinkDao.findWithTargetPidIn(someTargetPidsAsLongs).stream()

View File

@ -22,8 +22,8 @@ package ca.uhn.fhir.jpa.delete.batch2;
import ca.uhn.fhir.jpa.api.svc.IDeleteExpungeSvc; import ca.uhn.fhir.jpa.api.svc.IDeleteExpungeSvc;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -49,8 +49,8 @@ public class DeleteExpungeSvcImpl implements IDeleteExpungeSvc {
} }
@Override @Override
public void deleteExpunge(List<ResourcePersistentId> thePersistentIds) { public void deleteExpunge(List<JpaPid> theJpaPids) {
List<String> sqlList = myDeleteExpungeSqlBuilder.convertPidsToDeleteExpungeSql(thePersistentIds); List<String> sqlList = myDeleteExpungeSqlBuilder.convertPidsToDeleteExpungeSql(theJpaPids);
ourLog.debug("Executing {} delete expunge sql commands", sqlList.size()); ourLog.debug("Executing {} delete expunge sql commands", sqlList.size());
long totalDeleted = 0; long totalDeleted = 0;
@ -60,7 +60,7 @@ public class DeleteExpungeSvcImpl implements IDeleteExpungeSvc {
} }
ourLog.info("{} records deleted", totalDeleted); ourLog.info("{} records deleted", totalDeleted);
clearHibernateSearchIndex(thePersistentIds); clearHibernateSearchIndex(theJpaPids);
// TODO KHS instead of logging progress, produce result chunks that get aggregated into a delete expunge report // TODO KHS instead of logging progress, produce result chunks that get aggregated into a delete expunge report
} }
@ -69,9 +69,9 @@ public class DeleteExpungeSvcImpl implements IDeleteExpungeSvc {
* If we are running with HS enabled, the expunge operation will cause dangling documents because Hibernate Search is not aware of custom SQL queries that delete resources. * If we are running with HS enabled, the expunge operation will cause dangling documents because Hibernate Search is not aware of custom SQL queries that delete resources.
* This method clears the Hibernate Search index for the given resources. * This method clears the Hibernate Search index for the given resources.
*/ */
private void clearHibernateSearchIndex(List<ResourcePersistentId> thePersistentIds) { private void clearHibernateSearchIndex(List<JpaPid> thePersistentIds) {
if (myFullTextSearchSvc != null) { if (myFullTextSearchSvc != null) {
List<Object> objectIds = thePersistentIds.stream().map(ResourcePersistentId::getIdAsLong).collect(Collectors.toList()); List<Object> objectIds = thePersistentIds.stream().map(JpaPid::getId).collect(Collectors.toList());
myFullTextSearchSvc.deleteIndexedDocumentsByTypeAndId(ResourceTable.class, objectIds); myFullTextSearchSvc.deleteIndexedDocumentsByTypeAndId(ResourceTable.class, objectIds);
ourLog.info("Cleared Hibernate Search indexes."); ourLog.info("Cleared Hibernate Search indexes.");
} }

View File

@ -20,12 +20,12 @@ package ca.uhn.fhir.jpa.entity;
* #L% * #L%
*/ */
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.BasePartitionable; import ca.uhn.fhir.jpa.model.entity.BasePartitionable;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLink;
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import javax.persistence.Column; import javax.persistence.Column;
@ -57,7 +57,7 @@ import java.util.Date;
}, indexes = { }, indexes = {
@Index(name = "IDX_EMPI_MATCH_TGT_VER", columnList = "MATCH_RESULT, TARGET_PID, VERSION") @Index(name = "IDX_EMPI_MATCH_TGT_VER", columnList = "MATCH_RESULT, TARGET_PID, VERSION")
}) })
public class MdmLink extends BasePartitionable implements IMdmLink { public class MdmLink extends BasePartitionable implements IMdmLink<JpaPid> {
public static final int VERSION_LENGTH = 16; public static final int VERSION_LENGTH = 16;
private static final int MATCH_RESULT_LENGTH = 16; private static final int MATCH_RESULT_LENGTH = 16;
private static final int LINK_SOURCE_LENGTH = 16; private static final int LINK_SOURCE_LENGTH = 16;
@ -139,37 +139,38 @@ public class MdmLink extends BasePartitionable implements IMdmLink {
private String myMdmSourceType; private String myMdmSourceType;
@Override @Override
public ResourcePersistentId getId() { public JpaPid getId() {
return new ResourcePersistentId(myId); return JpaPid.fromId(myId);
} }
@Override @Override
public MdmLink setId(ResourcePersistentId theId) { public MdmLink setId(JpaPid theId) {
myId = theId.getIdAsLong(); myId = theId.getId();
return this; return this;
} }
@Override @Override
public ResourcePersistentId getGoldenResourcePersistenceId() { public JpaPid getGoldenResourcePersistenceId() {
return new ResourcePersistentId(myGoldenResourcePid); return JpaPid.fromId(myGoldenResourcePid);
} }
@Override @Override
public IMdmLink setGoldenResourcePersistenceId(ResourcePersistentId theGoldenResourcePid) { public IMdmLink setGoldenResourcePersistenceId(JpaPid theGoldenResourcePid) {
setPersonPid(theGoldenResourcePid.getIdAsLong()); Long longPid = theGoldenResourcePid.getId();
setPersonPid(longPid);
myGoldenResourcePid = theGoldenResourcePid.getIdAsLong(); myGoldenResourcePid = longPid;
return this; return this;
} }
@Override @Override
public ResourcePersistentId getSourcePersistenceId() { public JpaPid getSourcePersistenceId() {
return new ResourcePersistentId(mySourcePid); return JpaPid.fromId(mySourcePid);
} }
@Override @Override
public IMdmLink setSourcePersistenceId(ResourcePersistentId theSourcePid) { public IMdmLink setSourcePersistenceId(JpaPid theSourcePid) {
mySourcePid = theSourcePid.getIdAsLong(); mySourcePid = theSourcePid.getId();
return this; return this;
} }
@ -202,7 +203,7 @@ public class MdmLink extends BasePartitionable implements IMdmLink {
} }
/** /**
* @deprecated Use {@link #setGoldenResourcePersistenceId(ResourcePersistentId)} instead * @deprecated Use {@link #setGoldenResourcePersistenceId(JpaPid)} instead
*/ */
@Deprecated @Deprecated
public MdmLink setGoldenResourcePid(Long theGoldenResourcePid) { public MdmLink setGoldenResourcePid(Long theGoldenResourcePid) {
@ -228,7 +229,7 @@ public class MdmLink extends BasePartitionable implements IMdmLink {
} }
/** /**
* @deprecated Use {@link #setSourcePersistenceId(ResourcePersistentId)} instead * @deprecated Use {@link #setSourcePersistenceId(JpaPid)} instead
*/ */
@Deprecated @Deprecated
public MdmLink setSourcePid(Long theSourcePid) { public MdmLink setSourcePid(Long theSourcePid) {

View File

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

View File

@ -20,16 +20,16 @@ package ca.uhn.fhir.jpa.model.cross;
* #L% * #L%
*/ */
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import java.util.Date; import java.util.Date;
public class ResourceLookup implements IResourceLookup { public class JpaResourceLookup implements IResourceLookup {
private final String myResourceType; private final String myResourceType;
private final Long myResourcePid; private final Long myResourcePid;
private final Date myDeletedAt; private final Date myDeletedAt;
public ResourceLookup(String theResourceType, Long theResourcePid, Date theDeletedAt) { public JpaResourceLookup(String theResourceType, Long theResourcePid, Date theDeletedAt) {
myResourceType = theResourceType; myResourceType = theResourceType;
myResourcePid = theResourcePid; myResourcePid = theResourcePid;
myDeletedAt = theDeletedAt; myDeletedAt = theDeletedAt;
@ -46,7 +46,7 @@ public class ResourceLookup implements IResourceLookup {
} }
@Override @Override
public ResourcePersistentId getPersistentId() { public JpaPid getPersistentId() {
return new ResourcePersistentId(myResourcePid); return JpaPid.fromId(myResourcePid);
} }
} }

View File

@ -34,6 +34,7 @@ import ca.uhn.fhir.jpa.dao.data.INpmPackageDao;
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao; import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao;
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionResourceDao; import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionResourceDao;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.NpmPackageEntity; import ca.uhn.fhir.jpa.model.entity.NpmPackageEntity;
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity; import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity; import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity;
@ -42,7 +43,6 @@ import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -72,6 +72,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -85,7 +86,6 @@ import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType; import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -182,7 +182,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
private IHapiPackageCacheManager.PackageContents loadPackageContents(NpmPackageVersionEntity thePackageVersion) { private IHapiPackageCacheManager.PackageContents loadPackageContents(NpmPackageVersionEntity thePackageVersion) {
IFhirResourceDao<? extends IBaseBinary> binaryDao = getBinaryDao(); IFhirResourceDao<? extends IBaseBinary> binaryDao = getBinaryDao();
IBaseBinary binary = binaryDao.readByPid(new ResourcePersistentId(thePackageVersion.getPackageBinary().getId())); IBaseBinary binary = binaryDao.readByPid(JpaPid.fromId(thePackageVersion.getPackageBinary().getId()));
try { try {
byte[] content = fetchBlobFromBinary(binary); byte[] content = fetchBlobFromBinary(binary);
PackageContents retVal = new PackageContents() PackageContents retVal = new PackageContents()
@ -529,7 +529,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
private IBaseResource loadPackageEntity(NpmPackageVersionResourceEntity contents) { private IBaseResource loadPackageEntity(NpmPackageVersionResourceEntity contents) {
try { try {
ResourcePersistentId binaryPid = new ResourcePersistentId(contents.getResourceBinary().getId()); JpaPid binaryPid = JpaPid.fromId(contents.getResourceBinary().getId());
IBaseBinary binary = getBinaryDao().readByPid(binaryPid); IBaseBinary binary = getBinaryDao().readByPid(binaryPid);
byte[] resourceContentsBytes= fetchBlobFromBinary(binary); byte[] resourceContentsBytes= fetchBlobFromBinary(binary);
String resourceContents = new String(resourceContentsBytes, StandardCharsets.UTF_8); String resourceContents = new String(resourceContentsBytes, StandardCharsets.UTF_8);

View File

@ -31,13 +31,14 @@ import ca.uhn.fhir.jpa.api.pid.IResourcePidList;
import ca.uhn.fhir.jpa.api.pid.MixedResourcePidList; import ca.uhn.fhir.jpa.api.pid.MixedResourcePidList;
import ca.uhn.fhir.jpa.api.svc.IBatch2DaoSvc; import ca.uhn.fhir.jpa.api.svc.IBatch2DaoSvc;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortOrderEnum; import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.util.DateRangeUtil; import ca.uhn.fhir.util.DateRangeUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -95,7 +96,7 @@ public class Batch2DaoSvcImpl implements IBatch2DaoSvc {
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(resourceType); IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(resourceType);
SystemRequestDetails request = new SystemRequestDetails(); SystemRequestDetails request = new SystemRequestDetails();
request.setRequestPartitionId(theRequestPartitionId); request.setRequestPartitionId(theRequestPartitionId);
List<ResourcePersistentId> ids = dao.searchForIds(searchParamMap, request); List<IResourcePersistentId> ids = dao.searchForIds(searchParamMap, request);
Date lastDate = null; Date lastDate = null;
if (ids.size() > 0) { if (ids.size() > 0) {
@ -122,9 +123,9 @@ public class Batch2DaoSvcImpl implements IBatch2DaoSvc {
return new EmptyResourcePidList(); return new EmptyResourcePidList();
} }
List<ResourcePersistentId> ids = content List<IResourcePersistentId> ids = content
.stream() .stream()
.map(t -> new ResourcePersistentId(t[0])) .map(t -> JpaPid.fromId((Long) t[0]))
.collect(Collectors.toList()); .collect(Collectors.toList());
List<String> types = content List<String> types = content

View File

@ -33,10 +33,10 @@ import ca.uhn.fhir.jpa.dao.HistoryBuilder;
import ca.uhn.fhir.jpa.dao.HistoryBuilderFactory; import ca.uhn.fhir.jpa.dao.HistoryBuilderFactory;
import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser; import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.JpaStorageResourceParser;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum; import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource; import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
import ca.uhn.fhir.jpa.partition.RequestPartitionHelperSvc; import ca.uhn.fhir.jpa.partition.RequestPartitionHelperSvc;
@ -51,7 +51,6 @@ import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.interceptor.ServerInterceptorUtil; import ca.uhn.fhir.rest.server.interceptor.ServerInterceptorUtil;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster; import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
@ -91,7 +90,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
@Autowired @Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster; private IInterceptorBroadcaster myInterceptorBroadcaster;
@Autowired @Autowired
private SearchBuilderFactory mySearchBuilderFactory; private SearchBuilderFactory<JpaPid> mySearchBuilderFactory;
@Autowired @Autowired
private HistoryBuilderFactory myHistoryBuilderFactory; private HistoryBuilderFactory myHistoryBuilderFactory;
@Autowired @Autowired
@ -99,7 +98,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
@Autowired @Autowired
private FhirContext myContext; private FhirContext myContext;
@Autowired @Autowired
private ISearchCoordinatorSvc mySearchCoordinatorSvc; private ISearchCoordinatorSvc<JpaPid> mySearchCoordinatorSvc;
@Autowired @Autowired
private ISearchCacheSvc mySearchCacheSvc; private ISearchCacheSvc mySearchCacheSvc;
@Autowired @Autowired
@ -136,18 +135,6 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
mySearchEntity = theSearch; mySearchEntity = theSearch;
} }
/**
* When HAPI FHIR server is running "for real", a new
* instance of the bundle provider is created to serve
* every HTTP request, so it's ok for us to keep
* state in here and expect that it will go away. But
* in unit tests we keep this object around for longer
* sometimes.
*/
public void clearCachedDataForUnitTest() {
mySearchEntity = null;
}
/** /**
* Perform a history search * Perform a history search
*/ */
@ -225,7 +212,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
final ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(dao, resourceName, resourceType); final ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(dao, resourceName, resourceType);
final List<ResourcePersistentId> pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex, myRequest); final List<JpaPid> pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex, myRequest);
TransactionTemplate template = new TransactionTemplate(myTxManager); TransactionTemplate template = new TransactionTemplate(myTxManager);
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@ -413,14 +400,14 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
// Note: Leave as protected, HSPC depends on this // Note: Leave as protected, HSPC depends on this
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected List<IBaseResource> toResourceList(ISearchBuilder theSearchBuilder, List<ResourcePersistentId> thePids) { protected List<IBaseResource> toResourceList(ISearchBuilder theSearchBuilder, List<JpaPid> thePids) {
List<ResourcePersistentId> includedPidList = new ArrayList<>(); List<JpaPid> includedPidList = new ArrayList<>();
if (mySearchEntity.getSearchType() == SearchTypeEnum.SEARCH) { if (mySearchEntity.getSearchType() == SearchTypeEnum.SEARCH) {
Integer maxIncludes = myDaoConfig.getMaximumIncludesToLoadPerPage(); Integer maxIncludes = myDaoConfig.getMaximumIncludesToLoadPerPage();
// Load _revincludes // Load _revincludes
Set<ResourcePersistentId> includedPids = theSearchBuilder.loadIncludes(myContext, myEntityManager, thePids, mySearchEntity.toRevIncludesList(), true, mySearchEntity.getLastUpdated(), myUuid, myRequest, maxIncludes); Set<JpaPid> includedPids = theSearchBuilder.loadIncludes(myContext, myEntityManager, thePids, mySearchEntity.toRevIncludesList(), true, mySearchEntity.getLastUpdated(), myUuid, myRequest, maxIncludes);
if (maxIncludes != null) { if (maxIncludes != null) {
maxIncludes -= includedPids.size(); maxIncludes -= includedPids.size();
} }
@ -428,7 +415,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
includedPidList.addAll(includedPids); includedPidList.addAll(includedPids);
// Load _includes // Load _includes
Set<ResourcePersistentId> revIncludedPids = theSearchBuilder.loadIncludes(myContext, myEntityManager, thePids, mySearchEntity.toIncludesList(), false, mySearchEntity.getLastUpdated(), myUuid, myRequest, maxIncludes); Set<JpaPid> revIncludedPids = theSearchBuilder.loadIncludes(myContext, myEntityManager, thePids, mySearchEntity.toIncludesList(), false, mySearchEntity.getLastUpdated(), myUuid, myRequest, maxIncludes);
thePids.addAll(revIncludedPids); thePids.addAll(revIncludedPids);
includedPidList.addAll(revIncludedPids); includedPidList.addAll(revIncludedPids);

View File

@ -22,10 +22,10 @@ package ca.uhn.fhir.jpa.search;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.util.QueryParameterUtils; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.builder.tasks.SearchTask; import ca.uhn.fhir.jpa.search.builder.tasks.SearchTask;
import ca.uhn.fhir.jpa.util.QueryParameterUtils;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
@ -67,7 +67,7 @@ public class PersistedJpaSearchFirstPageBundleProvider extends PersistedJpaBundl
mySearchTask.awaitInitialSync(); mySearchTask.awaitInitialSync();
ourLog.trace("Fetching search resource PIDs from task: {}", mySearchTask.getClass()); ourLog.trace("Fetching search resource PIDs from task: {}", mySearchTask.getClass());
final List<ResourcePersistentId> pids = mySearchTask.getResourcePids(theFromIndex, theToIndex); final List<JpaPid> pids = mySearchTask.getResourcePids(theFromIndex, theToIndex);
ourLog.trace("Done fetching search resource PIDs"); ourLog.trace("Done fetching search resource PIDs");
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager); TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);

View File

@ -37,6 +37,7 @@ import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.dao.search.ResourceNotFoundInIndexException; import ca.uhn.fhir.jpa.dao.search.ResourceNotFoundInIndexException;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.search.builder.StorageInterceptorHooksFacade; import ca.uhn.fhir.jpa.search.builder.StorageInterceptorHooksFacade;
@ -55,7 +56,6 @@ import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.SearchTotalModeEnum; import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
@ -96,7 +96,7 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
@Component("mySearchCoordinatorSvc") @Component("mySearchCoordinatorSvc")
public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc<JpaPid> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchCoordinatorSvcImpl.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchCoordinatorSvcImpl.class);
@ -107,7 +107,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private final ISearchCacheSvc mySearchCacheSvc; private final ISearchCacheSvc mySearchCacheSvc;
private final ISearchResultCacheSvc mySearchResultCacheSvc; private final ISearchResultCacheSvc mySearchResultCacheSvc;
private final DaoRegistry myDaoRegistry; private final DaoRegistry myDaoRegistry;
private final SearchBuilderFactory mySearchBuilderFactory; private final SearchBuilderFactory<JpaPid> mySearchBuilderFactory;
private final ISynchronousSearchSvc mySynchronousSearchSvc; private final ISynchronousSearchSvc mySynchronousSearchSvc;
private final PersistedJpaBundleProviderFactory myPersistedJpaBundleProviderFactory; private final PersistedJpaBundleProviderFactory myPersistedJpaBundleProviderFactory;
private final IRequestPartitionHelperSvc myRequestPartitionHelperService; private final IRequestPartitionHelperSvc myRequestPartitionHelperService;
@ -124,9 +124,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private final ConcurrentHashMap<String, SearchTask> myIdToSearchTask = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, SearchTask> myIdToSearchTask = new ConcurrentHashMap<>();
private final Consumer<String> myOnRemoveSearchTask = (theId) -> { private final Consumer<String> myOnRemoveSearchTask = (theId) -> myIdToSearchTask.remove(theId);
myIdToSearchTask.remove(theId);
};
private final StorageInterceptorHooksFacade myStorageInterceptorHooks; private final StorageInterceptorHooksFacade myStorageInterceptorHooks;
@ -141,7 +139,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
ISearchCacheSvc theSearchCacheSvc, ISearchCacheSvc theSearchCacheSvc,
ISearchResultCacheSvc theSearchResultCacheSvc, ISearchResultCacheSvc theSearchResultCacheSvc,
DaoRegistry theDaoRegistry, DaoRegistry theDaoRegistry,
SearchBuilderFactory theSearchBuilderFactory, SearchBuilderFactory<JpaPid> theSearchBuilderFactory,
ISynchronousSearchSvc theSynchronousSearchSvc, ISynchronousSearchSvc theSynchronousSearchSvc,
PersistedJpaBundleProviderFactory thePersistedJpaBundleProviderFactory, PersistedJpaBundleProviderFactory thePersistedJpaBundleProviderFactory,
IRequestPartitionHelperSvc theRequestPartitionHelperService, IRequestPartitionHelperSvc theRequestPartitionHelperService,
@ -211,7 +209,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
*/ */
@Override @Override
@Transactional(propagation = Propagation.NEVER) @Transactional(propagation = Propagation.NEVER)
public List<ResourcePersistentId> getResources(final String theUuid, int theFrom, int theTo, @Nullable RequestDetails theRequestDetails) { public List<JpaPid> getResources(final String theUuid, int theFrom, int theTo, @Nullable RequestDetails theRequestDetails) {
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager); TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@ -231,7 +229,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
if (myNeverUseLocalSearchForUnitTests == false) { if (myNeverUseLocalSearchForUnitTests == false) {
if (searchTask != null) { if (searchTask != null) {
ourLog.trace("Local search found"); ourLog.trace("Local search found");
List<ResourcePersistentId> resourcePids = searchTask.getResourcePids(theFrom, theTo); List<JpaPid> resourcePids = searchTask.getResourcePids(theFrom, theTo);
ourLog.trace("Local search returned {} pids, wanted {}-{} - Search: {}", resourcePids.size(), theFrom, theTo, searchTask.getSearch()); ourLog.trace("Local search returned {} pids, wanted {}-{} - Search: {}", resourcePids.size(), theFrom, theTo, searchTask.getSearch());
/* /*
@ -301,7 +299,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
ourLog.trace("Finished looping"); ourLog.trace("Finished looping");
List<ResourcePersistentId> pids = mySearchResultCacheSvc.fetchResultPids(search, theFrom, theTo); List<JpaPid> pids = mySearchResultCacheSvc.fetchResultPids(search, theFrom, theTo);
if (pids == null) { if (pids == null) {
throw myExceptionSvc.newUnknownSearchException(theUuid); throw myExceptionSvc.newUnknownSearchException(theUuid);
} }
@ -326,7 +324,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
validateSearch(theParams); validateSearch(theParams);
Class<? extends IBaseResource> resourceTypeClass = myContext.getResourceDefinition(theResourceType).getImplementingClass(); Class<? extends IBaseResource> resourceTypeClass = myContext.getResourceDefinition(theResourceType).getImplementingClass();
final ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(theCallingDao, theResourceType, resourceTypeClass); final ISearchBuilder<JpaPid> sb = mySearchBuilderFactory.newSearchBuilder(theCallingDao, theResourceType, resourceTypeClass);
sb.setFetchSize(mySyncSize); sb.setFetchSize(mySyncSize);
final Integer loadSynchronousUpTo = getLoadSynchronousUpToOrNull(theCacheControlDirective); final Integer loadSynchronousUpTo = getLoadSynchronousUpToOrNull(theCacheControlDirective);
@ -359,7 +357,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
* instead * instead
*/ */
SearchCacheStatusEnum cacheStatus = SearchCacheStatusEnum.MISS; SearchCacheStatusEnum cacheStatus = SearchCacheStatusEnum.MISS;
if (theCacheControlDirective != null && theCacheControlDirective.isNoCache() == true) { if (theCacheControlDirective != null && theCacheControlDirective.isNoCache()) {
cacheStatus = SearchCacheStatusEnum.NOT_TRIED; cacheStatus = SearchCacheStatusEnum.NOT_TRIED;
} }
@ -375,7 +373,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
} }
} }
PersistedJpaSearchFirstPageBundleProvider retVal = submitSearch(theCallingDao, theParams, theResourceType, theRequestDetails, searchUuid, sb, queryString, theRequestPartitionId, search); PersistedJpaSearchFirstPageBundleProvider retVal = submitSearch(theCallingDao, theParams, theResourceType, theRequestDetails, sb, theRequestPartitionId, search);
retVal.setCacheStatus(cacheStatus); retVal.setCacheStatus(cacheStatus);
return retVal; return retVal;
} }
@ -463,7 +461,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
} }
@Nonnull @Nonnull
private PersistedJpaSearchFirstPageBundleProvider submitSearch(IDao theCallingDao, SearchParameterMap theParams, String theResourceType, RequestDetails theRequestDetails, String theSearchUuid, ISearchBuilder theSb, String theQueryString, RequestPartitionId theRequestPartitionId, Search theSearch) { private PersistedJpaSearchFirstPageBundleProvider submitSearch(IDao theCallingDao, SearchParameterMap theParams, String theResourceType, RequestDetails theRequestDetails, ISearchBuilder<JpaPid> theSb, RequestPartitionId theRequestPartitionId, Search theSearch) {
StopWatch w = new StopWatch(); StopWatch w = new StopWatch();
SearchTaskParameters stp = new SearchTaskParameters( SearchTaskParameters stp = new SearchTaskParameters(

View File

@ -33,6 +33,7 @@ import ca.uhn.fhir.jpa.dao.IResultIterator;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails; import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
@ -40,7 +41,6 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.SimpleBundleProvider; import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.ServerInterceptorUtil; import ca.uhn.fhir.rest.server.interceptor.ServerInterceptorUtil;
@ -104,7 +104,7 @@ public class SynchronousSearchSvcImpl implements ISynchronousSearchSvc {
return txTemplate.execute(t -> { return txTemplate.execute(t -> {
// Load the results synchronously // Load the results synchronously
final List<ResourcePersistentId> pids = new ArrayList<>(); final List<JpaPid> pids = new ArrayList<>();
Long count = 0L; Long count = 0L;
if (wantCount) { if (wantCount) {
@ -130,7 +130,7 @@ public class SynchronousSearchSvcImpl implements ISynchronousSearchSvc {
return bundleProvider; return bundleProvider;
} }
try (IResultIterator resultIter = theSb.createQuery(theParams, searchRuntimeDetails, theRequestDetails, theRequestPartitionId)) { try (IResultIterator<JpaPid> resultIter = theSb.createQuery(theParams, searchRuntimeDetails, theRequestDetails, theRequestPartitionId)) {
while (resultIter.hasNext()) { while (resultIter.hasNext()) {
pids.add(resultIter.next()); pids.add(resultIter.next());
if (theLoadSynchronousUpTo != null && pids.size() >= theLoadSynchronousUpTo) { if (theLoadSynchronousUpTo != null && pids.size() >= theLoadSynchronousUpTo) {
@ -170,16 +170,16 @@ public class SynchronousSearchSvcImpl implements ISynchronousSearchSvc {
// _includes // _includes
Integer maxIncludes = myDaoConfig.getMaximumIncludesToLoadPerPage(); Integer maxIncludes = myDaoConfig.getMaximumIncludesToLoadPerPage();
final Set<ResourcePersistentId> includedPids = theSb.loadIncludes(myContext, myEntityManager, pids, theParams.getRevIncludes(), true, theParams.getLastUpdated(), "(synchronous)", theRequestDetails, maxIncludes); final Set<JpaPid> includedPids = theSb.loadIncludes(myContext, myEntityManager, pids, theParams.getRevIncludes(), true, theParams.getLastUpdated(), "(synchronous)", theRequestDetails, maxIncludes);
if (maxIncludes != null) { if (maxIncludes != null) {
maxIncludes -= includedPids.size(); maxIncludes -= includedPids.size();
} }
pids.addAll(includedPids); pids.addAll(includedPids);
List<ResourcePersistentId> includedPidsList = new ArrayList<>(includedPids); List<JpaPid> includedPidsList = new ArrayList<>(includedPids);
// _revincludes // _revincludes
if (theParams.getEverythingMode() == null && (maxIncludes == null || maxIncludes > 0)) { if (theParams.getEverythingMode() == null && (maxIncludes == null || maxIncludes > 0)) {
Set<ResourcePersistentId> revIncludedPids = theSb.loadIncludes(myContext, myEntityManager, pids, theParams.getIncludes(), false, theParams.getLastUpdated(), "(synchronous)", theRequestDetails, maxIncludes); Set<JpaPid> revIncludedPids = theSb.loadIncludes(myContext, myEntityManager, pids, theParams.getIncludes(), false, theParams.getLastUpdated(), "(synchronous)", theRequestDetails, maxIncludes);
includedPids.addAll(revIncludedPids); includedPids.addAll(revIncludedPids);
pids.addAll(revIncludedPids); pids.addAll(revIncludedPids);
includedPidsList.addAll(revIncludedPids); includedPidsList.addAll(revIncludedPids);

View File

@ -48,6 +48,7 @@ import ca.uhn.fhir.jpa.dao.search.ResourceNotFoundInIndexException;
import ca.uhn.fhir.jpa.entity.ResourceSearchView; import ca.uhn.fhir.jpa.entity.ResourceSearchView;
import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails; import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.IBaseResourceEntity; import ca.uhn.fhir.jpa.model.entity.IBaseResourceEntity;
import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.ResourceTag; import ca.uhn.fhir.jpa.model.entity.ResourceTag;
@ -80,7 +81,6 @@ import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.StringParam;
@ -135,7 +135,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* The SearchBuilder is responsible for actually forming the SQL query that handles * The SearchBuilder is responsible for actually forming the SQL query that handles
* searches for resources * searches for resources
*/ */
public class SearchBuilder implements ISearchBuilder { public class SearchBuilder implements ISearchBuilder<JpaPid> {
/** /**
* See loadResourcesByPid * See loadResourcesByPid
@ -148,7 +148,7 @@ public class SearchBuilder implements ISearchBuilder {
public static final String RESOURCE_ID_ALIAS = "resource_id"; public static final String RESOURCE_ID_ALIAS = "resource_id";
public static final String RESOURCE_VERSION_ALIAS = "resource_version"; public static final String RESOURCE_VERSION_ALIAS = "resource_version";
private static final Logger ourLog = LoggerFactory.getLogger(SearchBuilder.class); private static final Logger ourLog = LoggerFactory.getLogger(SearchBuilder.class);
private static final ResourcePersistentId NO_MORE = new ResourcePersistentId(-1L); private static final JpaPid NO_MORE = JpaPid.fromId(-1L);
private static final String MY_TARGET_RESOURCE_PID = "myTargetResourcePid"; private static final String MY_TARGET_RESOURCE_PID = "myTargetResourcePid";
private static final String MY_SOURCE_RESOURCE_PID = "mySourceResourcePid"; private static final String MY_SOURCE_RESOURCE_PID = "mySourceResourcePid";
private static final String MY_TARGET_RESOURCE_TYPE = "myTargetResourceType"; private static final String MY_TARGET_RESOURCE_TYPE = "myTargetResourceType";
@ -168,18 +168,18 @@ public class SearchBuilder implements ISearchBuilder {
private final DaoRegistry myDaoRegistry; private final DaoRegistry myDaoRegistry;
private final IResourceSearchViewDao myResourceSearchViewDao; private final IResourceSearchViewDao myResourceSearchViewDao;
private final FhirContext myContext; private final FhirContext myContext;
private final IIdHelperService myIdHelperService; private final IIdHelperService<JpaPid> myIdHelperService;
private final DaoConfig myDaoConfig; private final DaoConfig myDaoConfig;
private final IDao myCallingDao; private final IDao myCallingDao;
@PersistenceContext(type = PersistenceContextType.TRANSACTION) @PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager; protected EntityManager myEntityManager;
private List<ResourcePersistentId> myAlsoIncludePids; private List<JpaPid> myAlsoIncludePids;
private CriteriaBuilder myCriteriaBuilder; private CriteriaBuilder myCriteriaBuilder;
private SearchParameterMap myParams; private SearchParameterMap myParams;
private String mySearchUuid; private String mySearchUuid;
private int myFetchSize; private int myFetchSize;
private Integer myMaxResultsToFetch; private Integer myMaxResultsToFetch;
private Set<ResourcePersistentId> myPidSet; private Set<JpaPid> myPidSet;
private boolean myHasNextIteratorQuery = false; private boolean myHasNextIteratorQuery = false;
private RequestPartitionId myRequestPartitionId; private RequestPartitionId myRequestPartitionId;
@Autowired(required = false) @Autowired(required = false)
@ -313,7 +313,7 @@ public class SearchBuilder implements ISearchBuilder {
* @param thePidSet May be null * @param thePidSet May be null
*/ */
@Override @Override
public void setPreviouslyAddedResourcePids(@Nonnull List<ResourcePersistentId> thePidSet) { public void setPreviouslyAddedResourcePids(@Nonnull List<JpaPid> thePidSet) {
myPidSet = new HashSet<>(thePidSet); myPidSet = new HashSet<>(thePidSet);
} }
@ -351,7 +351,7 @@ public class SearchBuilder implements ISearchBuilder {
// Ugh - we have two different return types for now // Ugh - we have two different return types for now
ISearchQueryExecutor fulltextExecutor = null; ISearchQueryExecutor fulltextExecutor = null;
List<ResourcePersistentId> fulltextMatchIds = null; List<JpaPid> fulltextMatchIds = null;
int resultCount = 0; int resultCount = 0;
if (myParams.isLastN()) { if (myParams.isLastN()) {
fulltextMatchIds = executeLastNAgainstIndex(theMaximumResults); fulltextMatchIds = executeLastNAgainstIndex(theMaximumResults);
@ -441,7 +441,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
} }
private List<ResourcePersistentId> executeLastNAgainstIndex(Integer theMaximumResults) { private List<JpaPid> executeLastNAgainstIndex(Integer theMaximumResults) {
// Can we use our hibernate search generated index on resource to support lastN?: // Can we use our hibernate search generated index on resource to support lastN?:
if (myDaoConfig.isAdvancedHSearchIndexing()) { if (myDaoConfig.isAdvancedHSearchIndexing()) {
if (myFulltextSearchSvc == null) { if (myFulltextSearchSvc == null) {
@ -461,8 +461,8 @@ public class SearchBuilder implements ISearchBuilder {
} }
} }
private List<ResourcePersistentId> queryHibernateSearchForEverythingPids() { private List<JpaPid> queryHibernateSearchForEverythingPids() {
ResourcePersistentId pid = null; JpaPid pid = null;
if (myParams.get(IAnyResource.SP_RES_ID) != null) { if (myParams.get(IAnyResource.SP_RES_ID) != null) {
String idParamValue; String idParamValue;
IQueryParameterType idParam = myParams.get(IAnyResource.SP_RES_ID).get(0).get(0); IQueryParameterType idParam = myParams.get(IAnyResource.SP_RES_ID).get(0).get(0);
@ -476,7 +476,7 @@ public class SearchBuilder implements ISearchBuilder {
pid = myIdHelperService.resolveResourcePersistentIds(myRequestPartitionId, myResourceName, idParamValue); pid = myIdHelperService.resolveResourcePersistentIds(myRequestPartitionId, myResourceName, idParamValue);
} }
List<ResourcePersistentId> pids = myFulltextSearchSvc.everything(myResourceName, myParams, pid); List<JpaPid> pids = myFulltextSearchSvc.everything(myResourceName, myParams, pid);
return pids; return pids;
} }
@ -514,7 +514,7 @@ public class SearchBuilder implements ISearchBuilder {
// fetch our target Pids // fetch our target Pids
// this will throw if an id is not found // this will throw if an id is not found
Map<String, ResourcePersistentId> idToPid = myIdHelperService.resolveResourcePersistentIds(myRequestPartitionId, Map<String, JpaPid> idToPid = myIdHelperService.resolveResourcePersistentIds(myRequestPartitionId,
myResourceName, myResourceName,
new ArrayList<>(ids)); new ArrayList<>(ids));
if (myAlsoIncludePids == null) { if (myAlsoIncludePids == null) {
@ -522,9 +522,9 @@ public class SearchBuilder implements ISearchBuilder {
} }
// add the pids to targetPids // add the pids to targetPids
for (ResourcePersistentId pid : idToPid.values()) { for (JpaPid pid : idToPid.values()) {
myAlsoIncludePids.add(pid); myAlsoIncludePids.add(pid);
theTargetPids.add(pid.getIdAsLong()); theTargetPids.add(pid.getId());
} }
} }
@ -563,7 +563,7 @@ public class SearchBuilder implements ISearchBuilder {
if (myAlsoIncludePids == null) { if (myAlsoIncludePids == null) {
myAlsoIncludePids = new ArrayList<>(output.size()); myAlsoIncludePids = new ArrayList<>(output.size());
} }
myAlsoIncludePids.addAll(ResourcePersistentId.fromLongList(output)); myAlsoIncludePids.addAll(JpaPid.fromLongList(output));
} }
@ -795,8 +795,8 @@ public class SearchBuilder implements ISearchBuilder {
RuntimeSearchParam left = compositeList.get(0); RuntimeSearchParam left = compositeList.get(0);
RuntimeSearchParam right = compositeList.get(1); RuntimeSearchParam right = compositeList.get(1);
createCompositeSort(theQueryStack, myResourceName, left.getParamType(), left.getName(), ascending); createCompositeSort(theQueryStack, left.getParamType(), left.getName(), ascending);
createCompositeSort(theQueryStack, myResourceName, right.getParamType(), right.getName(), ascending); createCompositeSort(theQueryStack, right.getParamType(), right.getName(), ascending);
break; break;
case SPECIAL: case SPECIAL:
@ -812,7 +812,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
private void createCompositeSort(QueryStack theQueryStack, String theResourceName, RestSearchParameterTypeEnum theParamType, String theParamName, boolean theAscending) { private void createCompositeSort(QueryStack theQueryStack, RestSearchParameterTypeEnum theParamType, String theParamName, boolean theAscending) {
switch (theParamType) { switch (theParamType) {
case STRING: case STRING:
@ -839,20 +839,20 @@ public class SearchBuilder implements ISearchBuilder {
} }
private void doLoadPids(Collection<ResourcePersistentId> thePids, Collection<ResourcePersistentId> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation, private void doLoadPids(Collection<JpaPid> thePids, Collection<JpaPid> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation,
Map<ResourcePersistentId, Integer> thePosition) { Map<JpaPid, Integer> thePosition) {
Map<Long, Long> resourcePidToVersion = null; Map<Long, Long> resourcePidToVersion = null;
for (ResourcePersistentId next : thePids) { for (JpaPid next : thePids) {
if (next.getVersion() != null && myModelConfig.isRespectVersionsForSearchIncludes()) { if (next.getVersion() != null && myModelConfig.isRespectVersionsForSearchIncludes()) {
if (resourcePidToVersion == null) { if (resourcePidToVersion == null) {
resourcePidToVersion = new HashMap<>(); resourcePidToVersion = new HashMap<>();
} }
resourcePidToVersion.put(next.getIdAsLong(), next.getVersion()); resourcePidToVersion.put((next).getId(), next.getVersion());
} }
} }
List<Long> versionlessPids = ResourcePersistentId.toLongList(thePids); List<Long> versionlessPids = JpaPid.toLongList(thePids);
if (versionlessPids.size() < getMaximumPageSize()) { if (versionlessPids.size() < getMaximumPageSize()) {
versionlessPids = normalizeIdListForLastNInClause(versionlessPids); versionlessPids = normalizeIdListForLastNInClause(versionlessPids);
} }
@ -870,7 +870,7 @@ public class SearchBuilder implements ISearchBuilder {
Class<? extends IBaseResource> resourceType = myContext.getResourceDefinition(next.getResourceType()).getImplementingClass(); Class<? extends IBaseResource> resourceType = myContext.getResourceDefinition(next.getResourceType()).getImplementingClass();
ResourcePersistentId resourceId = new ResourcePersistentId(next.getResourceId()); JpaPid resourceId = JpaPid.fromId(next.getResourceId());
/* /*
* If a specific version is requested via an include, we'll replace the current version * If a specific version is requested via an include, we'll replace the current version
@ -946,16 +946,16 @@ public class SearchBuilder implements ISearchBuilder {
Collection<ResourceTag> tagList = myResourceTagDao.findByResourceIds(thePidList); Collection<ResourceTag> tagList = myResourceTagDao.findByResourceIds(thePidList);
//-- build the map, key = resourceId, value = list of ResourceTag //-- build the map, key = resourceId, value = list of ResourceTag
ResourcePersistentId resourceId; JpaPid resourceId;
Collection<ResourceTag> tagCol; Collection<ResourceTag> tagCol;
for (ResourceTag tag : tagList) { for (ResourceTag tag : tagList) {
resourceId = new ResourcePersistentId(tag.getResourceId()); resourceId = JpaPid.fromId(tag.getResourceId());
tagCol = tagMap.get(resourceId.getIdAsLong()); tagCol = tagMap.get(resourceId.getId());
if (tagCol == null) { if (tagCol == null) {
tagCol = new ArrayList<>(); tagCol = new ArrayList<>();
tagCol.add(tag); tagCol.add(tag);
tagMap.put(resourceId.getIdAsLong(), tagCol); tagMap.put(resourceId.getId(), tagCol);
} else { } else {
tagCol.add(tag); tagCol.add(tag);
} }
@ -965,7 +965,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
@Override @Override
public void loadResourcesByPid(Collection<ResourcePersistentId> thePids, Collection<ResourcePersistentId> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation, RequestDetails theDetails) { public void loadResourcesByPid(Collection<JpaPid> thePids, Collection<JpaPid> theIncludedPids, List<IBaseResource> theResourceListToPopulate, boolean theForHistoryOperation, RequestDetails theDetails) {
if (thePids.isEmpty()) { if (thePids.isEmpty()) {
ourLog.debug("The include pids are empty"); ourLog.debug("The include pids are empty");
// return; // return;
@ -975,8 +975,8 @@ public class SearchBuilder implements ISearchBuilder {
// when running asserts // when running asserts
assert new HashSet<>(thePids).size() == thePids.size() : "PID list contains duplicates: " + thePids; assert new HashSet<>(thePids).size() == thePids.size() : "PID list contains duplicates: " + thePids;
Map<ResourcePersistentId, Integer> position = new HashMap<>(); Map<JpaPid, Integer> position = new HashMap<>();
for (ResourcePersistentId next : thePids) { for (JpaPid next : thePids) {
position.put(next, theResourceListToPopulate.size()); position.put(next, theResourceListToPopulate.size());
theResourceListToPopulate.add(null); theResourceListToPopulate.add(null);
} }
@ -994,7 +994,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
// We only chunk because some jdbc drivers can't handle long param lists. // We only chunk because some jdbc drivers can't handle long param lists.
new QueryChunker<ResourcePersistentId>().chunk(thePids, t -> doLoadPids(t, theIncludedPids, theResourceListToPopulate, theForHistoryOperation, position)); new QueryChunker<JpaPid>().chunk(thePids, t -> doLoadPids(t, theIncludedPids, theResourceListToPopulate, theForHistoryOperation, position));
} }
/** /**
@ -1006,7 +1006,7 @@ public class SearchBuilder implements ISearchBuilder {
* @param thePids the pids to check for versioned references * @param thePids the pids to check for versioned references
* @return can we fetch from Hibernate Search? * @return can we fetch from Hibernate Search?
*/ */
private boolean isLoadingFromElasticSearchSupported(Collection<ResourcePersistentId> thePids) { private boolean isLoadingFromElasticSearchSupported(Collection<JpaPid> thePids) {
// is storage enabled? // is storage enabled?
return myDaoConfig.isStoreResourceInHSearchIndex() && return myDaoConfig.isStoreResourceInHSearchIndex() &&
myDaoConfig.isAdvancedHSearchIndexing() && myDaoConfig.isAdvancedHSearchIndexing() &&
@ -1016,11 +1016,11 @@ public class SearchBuilder implements ISearchBuilder {
myContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3); myContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3);
} }
private List<IBaseResource> loadResourcesFromElasticSearch(Collection<ResourcePersistentId> thePids) { private List<IBaseResource> loadResourcesFromElasticSearch(Collection<JpaPid> thePids) {
// Do we use the fulltextsvc via hibernate-search to load resources or be backwards compatible with older ES only impl // Do we use the fulltextsvc via hibernate-search to load resources or be backwards compatible with older ES only impl
// to handle lastN? // to handle lastN?
if (myDaoConfig.isAdvancedHSearchIndexing() && myDaoConfig.isStoreResourceInHSearchIndex()) { if (myDaoConfig.isAdvancedHSearchIndexing() && myDaoConfig.isStoreResourceInHSearchIndex()) {
List<Long> pidList = thePids.stream().map(ResourcePersistentId::getIdAsLong).collect(Collectors.toList()); List<Long> pidList = thePids.stream().map(pid -> (pid).getId()).collect(Collectors.toList());
List<IBaseResource> resources = myFulltextSearchSvc.getResources(pidList); List<IBaseResource> resources = myFulltextSearchSvc.getResources(pidList);
return resources; return resources;
@ -1035,10 +1035,10 @@ public class SearchBuilder implements ISearchBuilder {
/** /**
* THIS SHOULD RETURN HASHSET and not just Set because we add to it later * THIS SHOULD RETURN HASHSET and not just Set because we add to it later
* so it can't be Collections.emptySet() or some such thing. * so it can't be Collections.emptySet() or some such thing.
* The ResourcePersistentId returned will have resource type populated. * The JpaPid returned will have resource type populated.
*/ */
@Override @Override
public Set<ResourcePersistentId> loadIncludes(FhirContext theContext, EntityManager theEntityManager, Collection<ResourcePersistentId> theMatches, Collection<Include> theIncludes, public Set<JpaPid> loadIncludes(FhirContext theContext, EntityManager theEntityManager, Collection<JpaPid> theMatches, Collection<Include> theIncludes,
boolean theReverseMode, DateRangeParam theLastUpdated, String theSearchIdOrDescription, RequestDetails theRequest, Integer theMaxCount) { boolean theReverseMode, DateRangeParam theLastUpdated, String theSearchIdOrDescription, RequestDetails theRequest, Integer theMaxCount) {
if (theMatches.size() == 0) { if (theMatches.size() == 0) {
return new HashSet<>(); return new HashSet<>();
@ -1054,9 +1054,9 @@ public class SearchBuilder implements ISearchBuilder {
findVersionFieldName = MY_TARGET_RESOURCE_VERSION; findVersionFieldName = MY_TARGET_RESOURCE_VERSION;
} }
List<ResourcePersistentId> nextRoundMatches = new ArrayList<>(theMatches); List<JpaPid> nextRoundMatches = new ArrayList<>(theMatches);
HashSet<ResourcePersistentId> allAdded = new HashSet<>(); HashSet<JpaPid> allAdded = new HashSet<>();
HashSet<ResourcePersistentId> original = new HashSet<>(theMatches); HashSet<JpaPid> original = new HashSet<>(theMatches);
ArrayList<Include> includes = new ArrayList<>(theIncludes); ArrayList<Include> includes = new ArrayList<>(theIncludes);
int roundCounts = 0; int roundCounts = 0;
@ -1066,7 +1066,7 @@ public class SearchBuilder implements ISearchBuilder {
do { do {
roundCounts++; roundCounts++;
HashSet<ResourcePersistentId> pidsToInclude = new HashSet<>(); HashSet<JpaPid> pidsToInclude = new HashSet<>();
for (Iterator<Include> iter = includes.iterator(); iter.hasNext(); ) { for (Iterator<Include> iter = includes.iterator(); iter.hasNext(); ) {
Include nextInclude = iter.next(); Include nextInclude = iter.next();
@ -1112,10 +1112,10 @@ public class SearchBuilder implements ISearchBuilder {
} }
String sql = sqlBuilder.toString(); String sql = sqlBuilder.toString();
List<Collection<ResourcePersistentId>> partitions = partition(nextRoundMatches, getMaximumPageSize()); List<Collection<JpaPid>> partitions = partition(nextRoundMatches, getMaximumPageSize());
for (Collection<ResourcePersistentId> nextPartition : partitions) { for (Collection<JpaPid> nextPartition : partitions) {
TypedQuery<?> q = theEntityManager.createQuery(sql, Object[].class); TypedQuery<?> q = theEntityManager.createQuery(sql, Object[].class);
q.setParameter("target_pids", ResourcePersistentId.toLongList(nextPartition)); q.setParameter("target_pids", JpaPid.toLongList(nextPartition));
if (wantResourceType != null) { if (wantResourceType != null) {
q.setParameter("want_resource_type", wantResourceType); q.setParameter("want_resource_type", wantResourceType);
} }
@ -1138,8 +1138,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
if (resourceLink != null) { if (resourceLink != null) {
ResourcePersistentId pid = new ResourcePersistentId(resourceLink, version); JpaPid pid = JpaPid.fromIdAndVersionAndResourceType(resourceLink, version, resourceType);
pid.setResourceType(resourceType);
pidsToInclude.add(pid); pidsToInclude.add(pid);
} }
} }
@ -1231,11 +1230,11 @@ public class SearchBuilder implements ISearchBuilder {
String sql = resourceIdBasedQuery + " UNION " + resourceUrlBasedQuery; String sql = resourceIdBasedQuery + " UNION " + resourceUrlBasedQuery;
List<Collection<ResourcePersistentId>> partitions = partition(nextRoundMatches, getMaximumPageSize()); List<Collection<JpaPid>> partitions = partition(nextRoundMatches, getMaximumPageSize());
for (Collection<ResourcePersistentId> nextPartition : partitions) { for (Collection<JpaPid> nextPartition : partitions) {
Query q = theEntityManager.createNativeQuery(sql, Tuple.class); Query q = theEntityManager.createNativeQuery(sql, Tuple.class);
q.setParameter("src_path", nextPath); q.setParameter("src_path", nextPath);
q.setParameter("target_pids", ResourcePersistentId.toLongList(nextPartition)); q.setParameter("target_pids", JpaPid.toLongList(nextPartition));
if (targetResourceType != null) { if (targetResourceType != null) {
q.setParameter("target_resource_type", targetResourceType); q.setParameter("target_resource_type", targetResourceType);
} else if (haveTargetTypesDefinedByParam) { } else if (haveTargetTypesDefinedByParam) {
@ -1253,7 +1252,7 @@ public class SearchBuilder implements ISearchBuilder {
if (findVersionFieldName != null && result.get(RESOURCE_VERSION_ALIAS) != null) { if (findVersionFieldName != null && result.get(RESOURCE_VERSION_ALIAS) != null) {
resourceVersion = NumberUtils.createLong(String.valueOf(result.get(RESOURCE_VERSION_ALIAS))); resourceVersion = NumberUtils.createLong(String.valueOf(result.get(RESOURCE_VERSION_ALIAS)));
} }
pidsToInclude.add(new ResourcePersistentId(resourceId, resourceVersion)); pidsToInclude.add(JpaPid.fromIdAndVersion(resourceId, resourceVersion));
} }
} }
} }
@ -1268,7 +1267,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
nextRoundMatches.clear(); nextRoundMatches.clear();
for (ResourcePersistentId next : pidsToInclude) { for (JpaPid next : pidsToInclude) {
if (original.contains(next) == false && allAdded.contains(next) == false) { if (original.contains(next) == false && allAdded.contains(next) == false) {
nextRoundMatches.add(next); nextRoundMatches.add(next);
} }
@ -1292,7 +1291,7 @@ public class SearchBuilder implements ISearchBuilder {
if (allAdded.size() > 0) { if (allAdded.size() > 0) {
if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_PREACCESS_RESOURCES, myInterceptorBroadcaster, theRequest)) { if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_PREACCESS_RESOURCES, myInterceptorBroadcaster, theRequest)) {
List<ResourcePersistentId> includedPidList = new ArrayList<>(allAdded); List<JpaPid> includedPidList = new ArrayList<>(allAdded);
JpaPreResourceAccessDetails accessDetails = new JpaPreResourceAccessDetails(includedPidList, () -> this); JpaPreResourceAccessDetails accessDetails = new JpaPreResourceAccessDetails(includedPidList, () -> this);
HookParams params = new HookParams() HookParams params = new HookParams()
.add(IPreResourceAccessDetails.class, accessDetails) .add(IPreResourceAccessDetails.class, accessDetails)
@ -1302,7 +1301,7 @@ public class SearchBuilder implements ISearchBuilder {
for (int i = includedPidList.size() - 1; i >= 0; i--) { for (int i = includedPidList.size() - 1; i >= 0; i--) {
if (accessDetails.isDontReturnResourceAtIndex(i)) { if (accessDetails.isDontReturnResourceAtIndex(i)) {
ResourcePersistentId value = includedPidList.remove(i); JpaPid value = includedPidList.remove(i);
if (value != null) { if (value != null) {
allAdded.remove(value); allAdded.remove(value);
} }
@ -1314,14 +1313,14 @@ public class SearchBuilder implements ISearchBuilder {
return allAdded; return allAdded;
} }
private List<Collection<ResourcePersistentId>> partition(Collection<ResourcePersistentId> theNextRoundMatches, int theMaxLoad) { private List<Collection<JpaPid>> partition(Collection<JpaPid> theNextRoundMatches, int theMaxLoad) {
if (theNextRoundMatches.size() <= theMaxLoad) { if (theNextRoundMatches.size() <= theMaxLoad) {
return Collections.singletonList(theNextRoundMatches); return Collections.singletonList(theNextRoundMatches);
} else { } else {
List<Collection<ResourcePersistentId>> retVal = new ArrayList<>(); List<Collection<JpaPid>> retVal = new ArrayList<>();
Collection<ResourcePersistentId> current = null; Collection<JpaPid> current = null;
for (ResourcePersistentId next : theNextRoundMatches) { for (JpaPid next : theNextRoundMatches) {
if (current == null) { if (current == null) {
current = new ArrayList<>(theMaxLoad); current = new ArrayList<>(theMaxLoad);
retVal.add(current); retVal.add(current);
@ -1482,14 +1481,14 @@ public class SearchBuilder implements ISearchBuilder {
return myResourceName; return myResourceName;
} }
public class IncludesIterator extends BaseIterator<ResourcePersistentId> implements Iterator<ResourcePersistentId> { public class IncludesIterator extends BaseIterator<JpaPid> implements Iterator<JpaPid> {
private final RequestDetails myRequest; private final RequestDetails myRequest;
private final Set<ResourcePersistentId> myCurrentPids; private final Set<JpaPid> myCurrentPids;
private Iterator<ResourcePersistentId> myCurrentIterator; private Iterator<JpaPid> myCurrentIterator;
private ResourcePersistentId myNext; private JpaPid myNext;
IncludesIterator(Set<ResourcePersistentId> thePidSet, RequestDetails theRequest) { IncludesIterator(Set<JpaPid> thePidSet, RequestDetails theRequest) {
myCurrentPids = new HashSet<>(thePidSet); myCurrentPids = new HashSet<>(thePidSet);
myCurrentIterator = null; myCurrentIterator = null;
myRequest = theRequest; myRequest = theRequest;
@ -1500,7 +1499,7 @@ public class SearchBuilder implements ISearchBuilder {
if (myCurrentIterator == null) { if (myCurrentIterator == null) {
Set<Include> includes = Collections.singleton(new Include("*", true)); Set<Include> includes = Collections.singleton(new Include("*", true));
Set<ResourcePersistentId> newPids = loadIncludes(myContext, myEntityManager, myCurrentPids, includes, false, getParams().getLastUpdated(), mySearchUuid, myRequest, null); Set<JpaPid> newPids = loadIncludes(myContext, myEntityManager, myCurrentPids, includes, false, getParams().getLastUpdated(), mySearchUuid, myRequest, null);
myCurrentIterator = newPids.iterator(); myCurrentIterator = newPids.iterator();
} }
@ -1520,16 +1519,16 @@ public class SearchBuilder implements ISearchBuilder {
} }
@Override @Override
public ResourcePersistentId next() { public JpaPid next() {
fetchNext(); fetchNext();
ResourcePersistentId retVal = myNext; JpaPid retVal = myNext;
myNext = null; myNext = null;
return retVal; return retVal;
} }
} }
private final class QueryIterator extends BaseIterator<ResourcePersistentId> implements IResultIterator { private final class QueryIterator extends BaseIterator<JpaPid> implements IResultIterator<JpaPid> {
private final SearchRuntimeDetails mySearchRuntimeDetails; private final SearchRuntimeDetails mySearchRuntimeDetails;
private final RequestDetails myRequest; private final RequestDetails myRequest;
@ -1539,7 +1538,7 @@ public class SearchBuilder implements ISearchBuilder {
private final Integer myOffset; private final Integer myOffset;
private boolean myFirst = true; private boolean myFirst = true;
private IncludesIterator myIncludesIterator; private IncludesIterator myIncludesIterator;
private ResourcePersistentId myNext; private JpaPid myNext;
private ISearchQueryExecutor myResultsIterator; private ISearchQueryExecutor myResultsIterator;
private boolean myFetchIncludesForEverythingOperation; private boolean myFetchIncludesForEverythingOperation;
private int mySkipCount = 0; private int mySkipCount = 0;
@ -1591,8 +1590,8 @@ public class SearchBuilder implements ISearchBuilder {
if (myNext == null) { if (myNext == null) {
for (Iterator<ResourcePersistentId> myPreResultsIterator = myAlsoIncludePids.iterator(); myPreResultsIterator.hasNext(); ) { for (Iterator<JpaPid> myPreResultsIterator = myAlsoIncludePids.iterator(); myPreResultsIterator.hasNext(); ) {
ResourcePersistentId next = myPreResultsIterator.next(); JpaPid next = myPreResultsIterator.next();
if (next != null) if (next != null)
if (myPidSet.add(next)) { if (myPidSet.add(next)) {
myNext = next; myNext = next;
@ -1616,7 +1615,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
if (nextLong != null) { if (nextLong != null) {
ResourcePersistentId next = new ResourcePersistentId(nextLong); JpaPid next = JpaPid.fromId(nextLong);
if (myPidSet.add(next)) { if (myPidSet.add(next)) {
myNext = next; myNext = next;
myNonSkipCount++; myNonSkipCount++;
@ -1655,7 +1654,7 @@ public class SearchBuilder implements ISearchBuilder {
} }
if (myIncludesIterator != null) { if (myIncludesIterator != null) {
while (myIncludesIterator.hasNext()) { while (myIncludesIterator.hasNext()) {
ResourcePersistentId next = myIncludesIterator.next(); JpaPid next = myIncludesIterator.next();
if (next != null) if (next != null)
if (myPidSet.add(next)) { if (myPidSet.add(next)) {
myNext = next; myNext = next;
@ -1740,9 +1739,9 @@ public class SearchBuilder implements ISearchBuilder {
} }
@Override @Override
public ResourcePersistentId next() { public JpaPid next() {
fetchNext(); fetchNext();
ResourcePersistentId retVal = myNext; JpaPid retVal = myNext;
myNext = null; myNext = null;
Validate.isTrue(!NO_MORE.equals(retVal), "No more elements"); Validate.isTrue(!NO_MORE.equals(retVal), "No more elements");
return retVal; return retVal;
@ -1759,8 +1758,8 @@ public class SearchBuilder implements ISearchBuilder {
} }
@Override @Override
public Collection<ResourcePersistentId> getNextResultBatch(long theBatchSize) { public Collection<JpaPid> getNextResultBatch(long theBatchSize) {
Collection<ResourcePersistentId> batch = new ArrayList<>(); Collection<JpaPid> batch = new ArrayList<>();
while (this.hasNext() && batch.size() < theBatchSize) { while (this.hasNext() && batch.size() < theBatchSize) {
batch.add(this.next()); batch.add(this.next());
} }

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.jpa.search.builder;
* #L% * #L%
*/ */
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -93,18 +93,18 @@ public class SearchQueryExecutors {
} }
} }
static public ISearchQueryExecutor from(Iterator<ResourcePersistentId> theIterator) { static public ISearchQueryExecutor from(Iterator<JpaPid> theIterator) {
return new ResourcePersistentIdQueryAdaptor(theIterator); return new JpaPidQueryAdaptor(theIterator);
} }
static public ISearchQueryExecutor from(Iterable<ResourcePersistentId> theIterable) { static public ISearchQueryExecutor from(Iterable<JpaPid> theIterable) {
return new ResourcePersistentIdQueryAdaptor(theIterable.iterator()); return new JpaPidQueryAdaptor(theIterable.iterator());
} }
static class ResourcePersistentIdQueryAdaptor implements ISearchQueryExecutor { static class JpaPidQueryAdaptor implements ISearchQueryExecutor {
final Iterator<ResourcePersistentId> myIterator; final Iterator<JpaPid> myIterator;
ResourcePersistentIdQueryAdaptor(Iterator<ResourcePersistentId> theIterator) { JpaPidQueryAdaptor(Iterator<JpaPid> theIterator) {
myIterator = theIterator; myIterator = theIterator;
} }
@ -119,8 +119,8 @@ public class SearchQueryExecutors {
@Override @Override
public Long next() { public Long next() {
ResourcePersistentId next = myIterator.next(); JpaPid next = myIterator.next();
return next==null?null:next.getIdAsLong(); return next == null ? null : next.getId();
} }
} }

View File

@ -23,10 +23,10 @@ package ca.uhn.fhir.jpa.search.builder.predicate;
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser; import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
import ca.uhn.fhir.jpa.util.QueryParameterUtils; import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder; import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
import ca.uhn.fhir.jpa.util.QueryParameterUtils;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.param.TokenParamModifier; import ca.uhn.fhir.rest.param.TokenParamModifier;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -49,7 +49,7 @@ public class ResourceIdPredicateBuilder extends BasePredicateBuilder {
private static final Logger ourLog = LoggerFactory.getLogger(ResourceIdPredicateBuilder.class); private static final Logger ourLog = LoggerFactory.getLogger(ResourceIdPredicateBuilder.class);
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<JpaPid> myIdHelperService;
/** /**
* Constructor * Constructor
@ -62,12 +62,12 @@ public class ResourceIdPredicateBuilder extends BasePredicateBuilder {
@Nullable @Nullable
public Condition createPredicateResourceId(@Nullable DbColumn theSourceJoinColumn, String theResourceName, List<List<IQueryParameterType>> theValues, SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { public Condition createPredicateResourceId(@Nullable DbColumn theSourceJoinColumn, String theResourceName, List<List<IQueryParameterType>> theValues, SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) {
Set<ResourcePersistentId> allOrPids = null; Set<JpaPid> allOrPids = null;
SearchFilterParser.CompareOperation defaultOperation = SearchFilterParser.CompareOperation.eq; SearchFilterParser.CompareOperation defaultOperation = SearchFilterParser.CompareOperation.eq;
boolean allIdsAreForcedIds = true; boolean allIdsAreForcedIds = true;
for (List<? extends IQueryParameterType> nextValue : theValues) { for (List<? extends IQueryParameterType> nextValue : theValues) {
Set<ResourcePersistentId> orPids = new HashSet<>(); Set<JpaPid> orPids = new HashSet<>();
boolean haveValue = false; boolean haveValue = false;
for (IQueryParameterType next : nextValue) { for (IQueryParameterType next : nextValue) {
String value = next.getValueAsQueryToken(getFhirContext()); String value = next.getValueAsQueryToken(getFhirContext());
@ -83,7 +83,7 @@ public class ResourceIdPredicateBuilder extends BasePredicateBuilder {
haveValue = true; haveValue = true;
try { try {
boolean excludeDeleted = true; boolean excludeDeleted = true;
ResourcePersistentId pid = myIdHelperService.resolveResourcePersistentIds(theRequestPartitionId, theResourceName, valueAsId.getIdPart(), excludeDeleted); JpaPid pid = myIdHelperService.resolveResourcePersistentIds(theRequestPartitionId, theResourceName, valueAsId.getIdPart(), excludeDeleted);
orPids.add(pid); orPids.add(pid);
} catch (ResourceNotFoundException e) { } catch (ResourceNotFoundException e) {
// This is not an error in a search, it just results in no matches // This is not an error in a search, it just results in no matches
@ -117,7 +117,7 @@ public class ResourceIdPredicateBuilder extends BasePredicateBuilder {
SearchFilterParser.CompareOperation operation = defaultIfNull(theOperation, defaultOperation); SearchFilterParser.CompareOperation operation = defaultIfNull(theOperation, defaultOperation);
assert operation == SearchFilterParser.CompareOperation.eq || operation == SearchFilterParser.CompareOperation.ne; assert operation == SearchFilterParser.CompareOperation.eq || operation == SearchFilterParser.CompareOperation.ne;
List<Long> resourceIds = ResourcePersistentId.toLongList(allOrPids); List<Long> resourceIds = JpaPid.toLongList(allOrPids);
if (theSourceJoinColumn == null) { if (theSourceJoinColumn == null) {
BaseJoiningPredicateBuilder queryRootTable = super.getOrCreateQueryRootTable(!allIdsAreForcedIds); BaseJoiningPredicateBuilder queryRootTable = super.getOrCreateQueryRootTable(!allIdsAreForcedIds);
Condition predicate; Condition predicate;

View File

@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.search.builder.predicate;
* #L% * #L%
*/ */
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
@ -28,6 +27,7 @@ import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
import ca.uhn.fhir.context.RuntimeChildResourceDefinition; import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.interceptor.api.Pointcut;
@ -38,15 +38,16 @@ import ca.uhn.fhir.jpa.api.dao.IDao;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.BaseStorageDao; import ca.uhn.fhir.jpa.dao.BaseStorageDao;
import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser; import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.jpa.util.QueryParameterUtils;
import ca.uhn.fhir.jpa.search.builder.QueryStack; import ca.uhn.fhir.jpa.search.builder.QueryStack;
import ca.uhn.fhir.jpa.search.builder.models.MissingQueryParameterPredicateParams; import ca.uhn.fhir.jpa.search.builder.models.MissingQueryParameterPredicateParams;
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder; import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams; import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams;
import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil;
import ca.uhn.fhir.jpa.util.QueryParameterUtils;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
@ -54,7 +55,6 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.SearchContainedModeEnum; import ca.uhn.fhir.rest.api.SearchContainedModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.CompositeParam; import ca.uhn.fhir.rest.param.CompositeParam;
import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.NumberParam; import ca.uhn.fhir.rest.param.NumberParam;
@ -96,9 +96,6 @@ import java.util.ListIterator;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.util.QueryParameterUtils.toAndPredicate;
import static ca.uhn.fhir.jpa.util.QueryParameterUtils.toEqualToOrInPredicate;
import static ca.uhn.fhir.jpa.util.QueryParameterUtils.toOrPredicate;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.trim; import static org.apache.commons.lang3.StringUtils.trim;
@ -238,8 +235,8 @@ public class ResourceLinkPredicateBuilder
inverse = true; inverse = true;
} }
List<ResourcePersistentId> targetPids = myIdHelperService.resolveResourcePersistentIdsWithCache(theRequestPartitionId, targetIds); List<JpaPid> targetPids = myIdHelperService.resolveResourcePersistentIdsWithCache(theRequestPartitionId, targetIds);
List<Long> targetPidList = ResourcePersistentId.toLongList(targetPids); List<Long> targetPidList = JpaPid.toLongList(targetPids);
if (targetPidList.isEmpty() && targetQualifiedUrls.isEmpty()) { if (targetPidList.isEmpty() && targetQualifiedUrls.isEmpty()) {
setMatchNothing(); setMatchNothing();

View File

@ -25,6 +25,7 @@ import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.config.HibernatePropertiesProvider; import ca.uhn.fhir.jpa.config.HibernatePropertiesProvider;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.search.builder.QueryStack; import ca.uhn.fhir.jpa.search.builder.QueryStack;
import ca.uhn.fhir.jpa.search.builder.predicate.BaseJoiningPredicateBuilder; import ca.uhn.fhir.jpa.search.builder.predicate.BaseJoiningPredicateBuilder;
@ -45,7 +46,6 @@ import ca.uhn.fhir.jpa.search.builder.predicate.StringPredicateBuilder;
import ca.uhn.fhir.jpa.search.builder.predicate.TagPredicateBuilder; import ca.uhn.fhir.jpa.search.builder.predicate.TagPredicateBuilder;
import ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder; import ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder;
import ca.uhn.fhir.jpa.search.builder.predicate.UriPredicateBuilder; import ca.uhn.fhir.jpa.search.builder.predicate.UriPredicateBuilder;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum;
@ -680,14 +680,14 @@ public class SearchQueryBuilder {
addPredicate(predicate); addPredicate(predicate);
} }
public void excludeResourceIdsPredicate(Set<ResourcePersistentId> theExsitinghPidSetToExclude) { public void excludeResourceIdsPredicate(Set<JpaPid> theExistingPidSetToExclude) {
// Do nothing if it's empty // Do nothing if it's empty
if (theExsitinghPidSetToExclude == null || theExsitinghPidSetToExclude.isEmpty()) if (theExistingPidSetToExclude == null || theExistingPidSetToExclude.isEmpty())
return; return;
List<Long> excludePids = ResourcePersistentId.toLongList(theExsitinghPidSetToExclude); List<Long> excludePids = JpaPid.toLongList(theExistingPidSetToExclude);
ourLog.trace("excludePids = " + excludePids); ourLog.trace("excludePids = " + excludePids);
DbColumn resourceIdColumn = getOrCreateFirstPredicateBuilder().getResourceIdColumn(); DbColumn resourceIdColumn = getOrCreateFirstPredicateBuilder().getResourceIdColumn();

View File

@ -24,12 +24,11 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.ExceptionService; import ca.uhn.fhir.jpa.search.ExceptionService;
import ca.uhn.fhir.jpa.search.SearchStrategyFactory;
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.IPagingProvider; import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
@ -47,7 +46,6 @@ public class SearchContinuationTask extends SearchTask {
SearchTaskParameters theCreationParams, SearchTaskParameters theCreationParams,
PlatformTransactionManager theManagedTxManager, PlatformTransactionManager theManagedTxManager,
FhirContext theContext, FhirContext theContext,
SearchStrategyFactory theSearchStrategyFactory,
IInterceptorBroadcaster theInterceptorBroadcaster, IInterceptorBroadcaster theInterceptorBroadcaster,
SearchBuilderFactory theSearchBuilderFactory, SearchBuilderFactory theSearchBuilderFactory,
ISearchResultCacheSvc theSearchResultCacheSvc, ISearchResultCacheSvc theSearchResultCacheSvc,
@ -60,7 +58,6 @@ public class SearchContinuationTask extends SearchTask {
theCreationParams, theCreationParams,
theManagedTxManager, theManagedTxManager,
theContext, theContext,
theSearchStrategyFactory,
theInterceptorBroadcaster, theInterceptorBroadcaster,
theSearchBuilderFactory, theSearchBuilderFactory,
theSearchResultCacheSvc, theSearchResultCacheSvc,
@ -78,7 +75,7 @@ public class SearchContinuationTask extends SearchTask {
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager); TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.afterPropertiesSet(); txTemplate.afterPropertiesSet();
txTemplate.execute(t -> { txTemplate.execute(t -> {
List<ResourcePersistentId> previouslyAddedResourcePids = mySearchResultCacheSvc.fetchAllResultPids(getSearch()); List<JpaPid> previouslyAddedResourcePids = mySearchResultCacheSvc.fetchAllResultPids(getSearch());
if (previouslyAddedResourcePids == null) { if (previouslyAddedResourcePids == null) {
throw myExceptionSvc.newUnknownSearchException(getSearch().getUuid()); throw myExceptionSvc.newUnknownSearchException(getSearch().getUuid());
} }

View File

@ -33,9 +33,9 @@ import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails; import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.SearchStrategyFactory;
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -43,7 +43,6 @@ import ca.uhn.fhir.jpa.util.QueryParameterUtils;
import ca.uhn.fhir.jpa.util.SearchParameterMapCalculator; import ca.uhn.fhir.jpa.util.SearchParameterMapCalculator;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.IPagingProvider; import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -102,10 +101,10 @@ public class SearchTask implements Callable<Void> {
private final SearchParameterMap myParams; private final SearchParameterMap myParams;
private final IDao myCallingDao; private final IDao myCallingDao;
private final String myResourceType; private final String myResourceType;
private final ArrayList<ResourcePersistentId> mySyncedPids = new ArrayList<>(); private final ArrayList<JpaPid> mySyncedPids = new ArrayList<>();
private final CountDownLatch myInitialCollectionLatch = new CountDownLatch(1); private final CountDownLatch myInitialCollectionLatch = new CountDownLatch(1);
private final CountDownLatch myCompletionLatch; private final CountDownLatch myCompletionLatch;
private final ArrayList<ResourcePersistentId> myUnsyncedPids = new ArrayList<>(); private final ArrayList<JpaPid> myUnsyncedPids = new ArrayList<>();
private final RequestDetails myRequest; private final RequestDetails myRequest;
private final RequestPartitionId myRequestPartitionId; private final RequestPartitionId myRequestPartitionId;
private final SearchRuntimeDetails mySearchRuntimeDetails; private final SearchRuntimeDetails mySearchRuntimeDetails;
@ -116,7 +115,7 @@ public class SearchTask implements Callable<Void> {
private int myCountSavedThisPass = 0; private int myCountSavedThisPass = 0;
private int myCountBlockedThisPass = 0; private int myCountBlockedThisPass = 0;
private boolean myAdditionalPrefetchThresholdsRemaining; private boolean myAdditionalPrefetchThresholdsRemaining;
private List<ResourcePersistentId> myPreviouslyAddedResourcePids; private List<JpaPid> myPreviouslyAddedResourcePids;
private Integer myMaxResultsToFetch; private Integer myMaxResultsToFetch;
private final Consumer<String> myOnRemove; private final Consumer<String> myOnRemove;
@ -130,7 +129,7 @@ public class SearchTask implements Callable<Void> {
protected final PlatformTransactionManager myManagedTxManager; protected final PlatformTransactionManager myManagedTxManager;
protected final FhirContext myContext; protected final FhirContext myContext;
private final IInterceptorBroadcaster myInterceptorBroadcaster; private final IInterceptorBroadcaster myInterceptorBroadcaster;
private final SearchBuilderFactory mySearchBuilderFactory; private final SearchBuilderFactory<JpaPid> mySearchBuilderFactory;
protected final ISearchResultCacheSvc mySearchResultCacheSvc; protected final ISearchResultCacheSvc mySearchResultCacheSvc;
private final DaoConfig myDaoConfig; private final DaoConfig myDaoConfig;
private final ISearchCacheSvc mySearchCacheSvc; private final ISearchCacheSvc mySearchCacheSvc;
@ -143,7 +142,6 @@ public class SearchTask implements Callable<Void> {
SearchTaskParameters theCreationParams, SearchTaskParameters theCreationParams,
PlatformTransactionManager theManagedTxManager, PlatformTransactionManager theManagedTxManager,
FhirContext theContext, FhirContext theContext,
SearchStrategyFactory theSearchStrategyFactory,
IInterceptorBroadcaster theInterceptorBroadcaster, IInterceptorBroadcaster theInterceptorBroadcaster,
SearchBuilderFactory theSearchBuilderFactory, SearchBuilderFactory theSearchBuilderFactory,
ISearchResultCacheSvc theSearchResultCacheSvc, ISearchResultCacheSvc theSearchResultCacheSvc,
@ -215,7 +213,7 @@ public class SearchTask implements Callable<Void> {
return myInitialCollectionLatch; return myInitialCollectionLatch;
} }
public void setPreviouslyAddedResourcePids(List<ResourcePersistentId> thePreviouslyAddedResourcePids) { public void setPreviouslyAddedResourcePids(List<JpaPid> thePreviouslyAddedResourcePids) {
myPreviouslyAddedResourcePids = thePreviouslyAddedResourcePids; myPreviouslyAddedResourcePids = thePreviouslyAddedResourcePids;
myCountSavedTotal = myPreviouslyAddedResourcePids.size(); myCountSavedTotal = myPreviouslyAddedResourcePids.size();
} }
@ -226,7 +224,7 @@ public class SearchTask implements Callable<Void> {
} }
@Nonnull @Nonnull
public List<ResourcePersistentId> getResourcePids(int theFromIndex, int theToIndex) { public List<JpaPid> getResourcePids(int theFromIndex, int theToIndex) {
ourLog.debug("Requesting search PIDs from {}-{}", theFromIndex, theToIndex); ourLog.debug("Requesting search PIDs from {}-{}", theFromIndex, theToIndex);
boolean keepWaiting; boolean keepWaiting;
@ -268,7 +266,7 @@ public class SearchTask implements Callable<Void> {
ourLog.debug("Proceeding, as we have {} results", mySyncedPids.size()); ourLog.debug("Proceeding, as we have {} results", mySyncedPids.size());
ArrayList<ResourcePersistentId> retVal = new ArrayList<>(); ArrayList<JpaPid> retVal = new ArrayList<>();
synchronized (mySyncedPids) { synchronized (mySyncedPids) {
QueryParameterUtils.verifySearchHasntFailedOrThrowInternalErrorException(mySearch); QueryParameterUtils.verifySearchHasntFailedOrThrowInternalErrorException(mySearch);
@ -308,7 +306,7 @@ public class SearchTask implements Callable<Void> {
doSaveSearch(); doSaveSearch();
} }
ArrayList<ResourcePersistentId> unsyncedPids = myUnsyncedPids; ArrayList<JpaPid> unsyncedPids = myUnsyncedPids;
int countBlocked = 0; int countBlocked = 0;
// Interceptor call: STORAGE_PREACCESS_RESOURCES // Interceptor call: STORAGE_PREACCESS_RESOURCES
@ -634,7 +632,7 @@ public class SearchTask implements Callable<Void> {
* This is an odd implementation behaviour, but the change * This is an odd implementation behaviour, but the change
* for this will require a lot more handling at higher levels * for this will require a lot more handling at higher levels
*/ */
try (IResultIterator resultIterator = sb.createQuery(myParams, mySearchRuntimeDetails, myRequest, myRequestPartitionId)) { try (IResultIterator<JpaPid> resultIterator = sb.createQuery(myParams, mySearchRuntimeDetails, myRequest, myRequestPartitionId)) {
assert (resultIterator != null); assert (resultIterator != null);
/* /*

View File

@ -20,18 +20,18 @@ package ca.uhn.fhir.jpa.search.cache;
* #L% * #L%
*/ */
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao; import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchResult; import ca.uhn.fhir.jpa.entity.SearchResult;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -45,7 +45,7 @@ public class DatabaseSearchResultCacheSvcImpl implements ISearchResultCacheSvc {
@Override @Override
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED)
public List<ResourcePersistentId> fetchResultPids(Search theSearch, int theFrom, int theTo) { public List<JpaPid> fetchResultPids(Search theSearch, int theFrom, int theTo) {
final Pageable page = toPage(theFrom, theTo); final Pageable page = toPage(theFrom, theTo);
if (page == null) { if (page == null) {
return Collections.emptyList(); return Collections.emptyList();
@ -57,28 +57,28 @@ public class DatabaseSearchResultCacheSvcImpl implements ISearchResultCacheSvc {
ourLog.debug("fetchResultPids for range {}-{} returned {} pids", theFrom, theTo, retVal.size()); ourLog.debug("fetchResultPids for range {}-{} returned {} pids", theFrom, theTo, retVal.size());
return ResourcePersistentId.fromLongList(retVal); return JpaPid.fromLongList(retVal);
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED)
public List<ResourcePersistentId> fetchAllResultPids(Search theSearch) { public List<JpaPid> fetchAllResultPids(Search theSearch) {
List<Long> retVal = mySearchResultDao.findWithSearchPidOrderIndependent(theSearch.getId()); List<Long> retVal = mySearchResultDao.findWithSearchPidOrderIndependent(theSearch.getId());
ourLog.trace("fetchAllResultPids returned {} pids", retVal.size()); ourLog.trace("fetchAllResultPids returned {} pids", retVal.size());
return ResourcePersistentId.fromLongList(retVal); return JpaPid.fromLongList(retVal);
} }
@Override @Override
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED)
public void storeResults(Search theSearch, List<ResourcePersistentId> thePreviouslyStoredResourcePids, List<ResourcePersistentId> theNewResourcePids) { public void storeResults(Search theSearch, List<JpaPid> thePreviouslyStoredResourcePids, List<JpaPid> theNewResourcePids) {
List<SearchResult> resultsToSave = Lists.newArrayList(); List<SearchResult> resultsToSave = Lists.newArrayList();
ourLog.debug("Storing {} results with {} previous for search", theNewResourcePids.size(), thePreviouslyStoredResourcePids.size()); ourLog.debug("Storing {} results with {} previous for search", theNewResourcePids.size(), thePreviouslyStoredResourcePids.size());
int order = thePreviouslyStoredResourcePids.size(); int order = thePreviouslyStoredResourcePids.size();
for (ResourcePersistentId nextPid : theNewResourcePids) { for (JpaPid nextPid : theNewResourcePids) {
SearchResult nextResult = new SearchResult(theSearch); SearchResult nextResult = new SearchResult(theSearch);
nextResult.setResourcePid(nextPid.getIdAsLong()); nextResult.setResourcePid(nextPid.getId());
nextResult.setOrder(order); nextResult.setOrder(order);
resultsToSave.add(nextResult); resultsToSave.add(nextResult);
ourLog.trace("Saving ORDER[{}] Resource {}", order, nextResult.getResourcePid()); ourLog.trace("Saving ORDER[{}] Resource {}", order, nextResult.getResourcePid());

View File

@ -20,8 +20,8 @@ package ca.uhn.fhir.jpa.search.cache;
* #L% * #L%
*/ */
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List; import java.util.List;
@ -32,7 +32,7 @@ public interface ISearchResultCacheSvc {
* @param thePreviouslyStoredResourcePids A list of resource PIDs that have previously been saved to this search * @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) * @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<ResourcePersistentId> thePreviouslyStoredResourcePids, List<ResourcePersistentId> theNewResourcePids); void storeResults(Search theSearch, List<JpaPid> thePreviouslyStoredResourcePids, List<JpaPid> theNewResourcePids);
/** /**
* Fetch a sunset of the search result IDs from the cache * Fetch a sunset of the search result IDs from the cache
@ -44,7 +44,7 @@ public interface ISearchResultCacheSvc {
* have been removed from the cache for some reason, such as expiry or manual purge) * have been removed from the cache for some reason, such as expiry or manual purge)
*/ */
@Nullable @Nullable
List<ResourcePersistentId> fetchResultPids(Search theSearch, int theFrom, int theTo); List<JpaPid> fetchResultPids(Search theSearch, int theFrom, int theTo);
/** /**
* Fetch all result PIDs for a given search with no particular order required * Fetch all result PIDs for a given search with no particular order required
@ -54,6 +54,6 @@ public interface ISearchResultCacheSvc {
* have been removed from the cache for some reason, such as expiry or manual purge) * have been removed from the cache for some reason, such as expiry or manual purge)
*/ */
@Nullable @Nullable
List<ResourcePersistentId> fetchAllResultPids(Search theSearch); List<JpaPid> fetchAllResultPids(Search theSearch);
} }

View File

@ -20,8 +20,8 @@ package ca.uhn.fhir.jpa.search.lastn;
* #L% * #L%
*/ */
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.dao.TolerantJsonParser; import ca.uhn.fhir.jpa.dao.TolerantJsonParser;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.entity.IBaseResourceEntity; import ca.uhn.fhir.jpa.model.entity.IBaseResourceEntity;
@ -32,7 +32,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.util.LastNParameterHelper; import ca.uhn.fhir.jpa.searchparam.util.LastNParameterHelper;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
@ -752,7 +752,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
} }
@Override @Override
public List<IBaseResource> getObservationResources(Collection<ResourcePersistentId> thePids) { public List<IBaseResource> getObservationResources(Collection<? extends IResourcePersistentId> thePids) {
SearchRequest searchRequest = buildObservationResourceSearchRequest(thePids); SearchRequest searchRequest = buildObservationResourceSearchRequest(thePids);
try { try {
SearchResponse observationDocumentResponse = executeSearchRequest(searchRequest); SearchResponse observationDocumentResponse = executeSearchRequest(searchRequest);
@ -780,7 +780,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
} }
} }
private SearchRequest buildObservationResourceSearchRequest(Collection<ResourcePersistentId> thePids) { private SearchRequest buildObservationResourceSearchRequest(Collection<? extends IResourcePersistentId> thePids) {
SearchRequest searchRequest = new SearchRequest(OBSERVATION_INDEX); SearchRequest searchRequest = new SearchRequest(OBSERVATION_INDEX);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// Query // Query

View File

@ -24,7 +24,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.search.lastn.json.CodeJson; import ca.uhn.fhir.jpa.search.lastn.json.CodeJson;
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson; import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import java.io.IOException; import java.io.IOException;
@ -96,6 +96,6 @@ public interface IElasticsearchSvc {
* @param thePids * @param thePids
* @return Resources list or empty if nothing found * @return Resources list or empty if nothing found
*/ */
List<IBaseResource> getObservationResources(Collection<ResourcePersistentId> thePids); List<IBaseResource> getObservationResources(Collection<? extends IResourcePersistentId> thePids);
} }

View File

@ -20,18 +20,18 @@ package ca.uhn.fhir.jpa.search.reindex;
* #L% * #L%
*/ */
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao; import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ForcedId; import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -84,7 +84,7 @@ public class ResourceReindexer {
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceTable.getResourceType()); IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceTable.getResourceType());
long expectedVersion = theResourceTable.getVersion(); long expectedVersion = theResourceTable.getVersion();
IBaseResource resource = dao.readByPid(new ResourcePersistentId(theResourceTable.getId()), true); IBaseResource resource = dao.readByPid(JpaPid.fromId(theResourceTable.getId()), true);
if (resource == null) { if (resource == null) {
throw new InternalErrorException(Msg.code(1171) + "Could not find resource version " + theResourceTable.getIdDt().toUnqualified().getValue() + " in database"); throw new InternalErrorException(Msg.code(1171) + "Could not find resource version " + theResourceTable.getIdDt().toUnqualified().getValue() + " in database");

View File

@ -40,6 +40,7 @@ import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptDesignation; import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.entity.TermConceptProperty; import ca.uhn.fhir.jpa.entity.TermConceptProperty;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
@ -48,7 +49,7 @@ import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet; import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.ObjectUtil; import ca.uhn.fhir.util.ObjectUtil;
@ -107,7 +108,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
@Autowired @Autowired
protected ITermConceptDesignationDao myConceptDesignationDao; protected ITermConceptDesignationDao myConceptDesignationDao;
@Autowired @Autowired
protected IIdHelperService myIdHelperService; protected IIdHelperService<JpaPid> myIdHelperService;
@Autowired @Autowired
private ITermConceptParentChildLinkDao myConceptParentChildLinkDao; private ITermConceptParentChildLinkDao myConceptParentChildLinkDao;
@Autowired @Autowired
@ -278,7 +279,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
Long pid = (Long)theCodeSystem.getUserData(RESOURCE_PID_KEY); Long pid = (Long)theCodeSystem.getUserData(RESOURCE_PID_KEY);
assert pid != null; assert pid != null;
ResourcePersistentId codeSystemResourcePid = new ResourcePersistentId(pid); JpaPid codeSystemResourcePid = JpaPid.fromId(pid);
/* /*
* If this is a not-present codesystem and codesystem version already exists, we don't want to * If this is a not-present codesystem and codesystem version already exists, we don't want to
@ -321,8 +322,8 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
// Note that this creates the TermCodeSystem and TermCodeSystemVersion entities if needed // Note that this creates the TermCodeSystem and TermCodeSystemVersion entities if needed
IIdType csId = myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(theCodeSystemResource, theRequest); IIdType csId = myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(theCodeSystemResource, theRequest);
ResourcePersistentId codeSystemResourcePid = myIdHelperService.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), csId.getResourceType(), csId.getIdPart()); JpaPid codeSystemResourcePid = myIdHelperService.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), csId.getResourceType(), csId.getIdPart());
ResourceTable resource = myResourceTableDao.getOne(codeSystemResourcePid.getIdAsLong()); ResourceTable resource = myResourceTableDao.getOne(codeSystemResourcePid.getId());
ourLog.info("CodeSystem resource has ID: {}", csId.getValue()); ourLog.info("CodeSystem resource has ID: {}", csId.getValue());
@ -339,7 +340,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
@Override @Override
@Transactional @Transactional
public void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, public void storeNewCodeSystemVersion(IResourcePersistentId theCodeSystemResourcePid, String theSystemUri,
String theSystemName, String theCodeSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, String theSystemName, String theCodeSystemVersionId, TermCodeSystemVersion theCodeSystemVersion,
ResourceTable theCodeSystemResourceTable, RequestDetails theRequestDetails) { ResourceTable theCodeSystemResourceTable, RequestDetails theRequestDetails) {
assert TransactionSynchronizationManager.isActualTransactionActive(); assert TransactionSynchronizationManager.isActualTransactionActive();
@ -352,7 +353,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
TermCodeSystem codeSystem = getOrCreateDistinctTermCodeSystem(theCodeSystemResourcePid, theSystemUri, theSystemName, theCodeSystemVersionId, theCodeSystemResourceTable); TermCodeSystem codeSystem = getOrCreateDistinctTermCodeSystem(theCodeSystemResourcePid, theSystemUri, theSystemName, theCodeSystemVersionId, theCodeSystemResourceTable);
List<TermCodeSystemVersion> existing = myCodeSystemVersionDao.findByCodeSystemResourcePid(theCodeSystemResourcePid.getIdAsLong()); List<TermCodeSystemVersion> existing = myCodeSystemVersionDao.findByCodeSystemResourcePid(((JpaPid)theCodeSystemResourcePid).getId());
for (TermCodeSystemVersion next : existing) { for (TermCodeSystemVersion next : existing) {
if (Objects.equals(next.getCodeSystemVersionId(), theCodeSystemVersionId) && myConceptDao.countByCodeSystemVersion(next.getPid()) == 0) { if (Objects.equals(next.getCodeSystemVersionId(), theCodeSystemVersionId) && myConceptDao.countByCodeSystemVersion(next.getPid()) == 0) {
@ -629,10 +630,10 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
} }
@Nonnull @Nonnull
private TermCodeSystem getOrCreateDistinctTermCodeSystem(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, ResourceTable theCodeSystemResourceTable) { private TermCodeSystem getOrCreateDistinctTermCodeSystem(IResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, ResourceTable theCodeSystemResourceTable) {
TermCodeSystem codeSystem = myCodeSystemDao.findByCodeSystemUri(theSystemUri); TermCodeSystem codeSystem = myCodeSystemDao.findByCodeSystemUri(theSystemUri);
if (codeSystem == null) { if (codeSystem == null) {
codeSystem = myCodeSystemDao.findByResourcePid(theCodeSystemResourcePid.getIdAsLong()); codeSystem = myCodeSystemDao.findByResourcePid(((JpaPid)theCodeSystemResourcePid).getId());
if (codeSystem == null) { if (codeSystem == null) {
codeSystem = new TermCodeSystem(); codeSystem = new TermCodeSystem();
} }

View File

@ -36,11 +36,11 @@ import ca.uhn.fhir.jpa.entity.TermConceptMap;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroup; import ca.uhn.fhir.jpa.entity.TermConceptMapGroup;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement; import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget; import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc; import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.util.ScrollableResultsIterator; import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
@ -107,7 +107,7 @@ public class TermConceptMappingSvcImpl implements ITermConceptMappingSvc {
@Autowired @Autowired
private MemoryCacheService myMemoryCacheService; private MemoryCacheService myMemoryCacheService;
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<JpaPid> myIdHelperService;
@Override @Override
@Transactional @Transactional
@ -362,8 +362,8 @@ public class TermConceptMappingSvcImpl implements ITermConceptMappingSvc {
if (translationQuery.hasResourceId()) { if (translationQuery.hasResourceId()) {
IIdType resourceId = translationQuery.getResourceId(); IIdType resourceId = translationQuery.getResourceId();
ResourcePersistentId resourcePid = myIdHelperService.getPidOrThrowException(RequestPartitionId.defaultPartition(), resourceId); JpaPid resourcePid = myIdHelperService.getPidOrThrowException(RequestPartitionId.defaultPartition(), resourceId);
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myResourcePid"), resourcePid.getIdAsLong())); predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myResourcePid"), resourcePid.getId()));
} }
Predicate outerPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[0])); Predicate outerPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[0]));
@ -491,8 +491,8 @@ public class TermConceptMappingSvcImpl implements ITermConceptMappingSvc {
if (translationQuery.hasResourceId()) { if (translationQuery.hasResourceId()) {
IIdType resourceId = translationQuery.getResourceId(); IIdType resourceId = translationQuery.getResourceId();
ResourcePersistentId resourcePid = myIdHelperService.getPidOrThrowException(RequestPartitionId.defaultPartition(), resourceId); JpaPid resourcePid = myIdHelperService.getPidOrThrowException(RequestPartitionId.defaultPartition(), resourceId);
predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myResourcePid"), resourcePid.getIdAsLong())); predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myResourcePid"), resourcePid.getId()));
} }
Predicate outerPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[0])); Predicate outerPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[0]));

View File

@ -39,8 +39,6 @@ import ca.uhn.fhir.jpa.config.util.ConnectionPoolInfoProvider;
import ca.uhn.fhir.jpa.config.util.IConnectionPoolInfoProvider; import ca.uhn.fhir.jpa.config.util.IConnectionPoolInfoProvider;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser; import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser;
import ca.uhn.fhir.jpa.dao.IStorageResourceParser;
import ca.uhn.fhir.jpa.dao.JpaStorageResourceParser;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao; import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao; import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao; import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
@ -63,6 +61,7 @@ import ca.uhn.fhir.jpa.entity.TermConceptPropertyTypeEnum;
import ca.uhn.fhir.jpa.entity.TermValueSet; import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.entity.TermValueSetConcept; import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum; import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ForcedId; import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.sched.HapiJob; import ca.uhn.fhir.jpa.model.sched.HapiJob;
@ -76,7 +75,6 @@ import ca.uhn.fhir.jpa.term.api.ReindexTerminologyResult;
import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException; import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -255,7 +253,7 @@ public class TermReadSvcImpl implements ITermReadSvc {
@Autowired(required = false) @Autowired(required = false)
private ITermDeferredStorageSvc myDeferredStorageSvc; private ITermDeferredStorageSvc myDeferredStorageSvc;
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<JpaPid> myIdHelperService;
@Autowired @Autowired
private ApplicationContext myApplicationContext; private ApplicationContext myApplicationContext;
private volatile IValidationSupport myJpaValidationSupport; private volatile IValidationSupport myJpaValidationSupport;
@ -1606,11 +1604,11 @@ public class TermReadSvcImpl implements ITermReadSvc {
} }
private Optional<TermValueSet> fetchValueSetEntity(ValueSet theValueSet) { private Optional<TermValueSet> fetchValueSetEntity(ValueSet theValueSet) {
ResourcePersistentId valueSetResourcePid = getValueSetResourcePersistentId(theValueSet); JpaPid valueSetResourcePid = getValueSetResourcePersistentId(theValueSet);
return myTermValueSetDao.findByResourcePid(valueSetResourcePid.getIdAsLong()); return myTermValueSetDao.findByResourcePid(valueSetResourcePid.getId());
} }
private ResourcePersistentId getValueSetResourcePersistentId(ValueSet theValueSet) { private JpaPid getValueSetResourcePersistentId(ValueSet theValueSet) {
return myIdHelperService.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), theValueSet.getIdElement().getResourceType(), theValueSet.getIdElement().getIdPart()); return myIdHelperService.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), theValueSet.getIdElement().getResourceType(), theValueSet.getIdElement().getIdPart());
} }
@ -1620,13 +1618,13 @@ public class TermReadSvcImpl implements ITermReadSvc {
assert TransactionSynchronizationManager.isSynchronizationActive(); assert TransactionSynchronizationManager.isSynchronizationActive();
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet.hasId(), "ValueSet.id is required"); ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet.hasId(), "ValueSet.id is required");
ResourcePersistentId valueSetResourcePid = getValueSetResourcePersistentId(theValueSet); JpaPid valueSetResourcePid = getValueSetResourcePersistentId(theValueSet);
List<TermValueSetConcept> concepts = new ArrayList<>(); List<TermValueSetConcept> concepts = new ArrayList<>();
if (isNotBlank(theCode)) { if (isNotBlank(theCode)) {
if (theValidationOptions.isInferSystem()) { if (theValidationOptions.isInferSystem()) {
concepts.addAll(myValueSetConceptDao.findByValueSetResourcePidAndCode(valueSetResourcePid.getIdAsLong(), theCode)); concepts.addAll(myValueSetConceptDao.findByValueSetResourcePidAndCode(valueSetResourcePid.getId(), theCode));
} else if (isNotBlank(theSystem)) { } else if (isNotBlank(theSystem)) {
concepts.addAll(findByValueSetResourcePidSystemAndCode(valueSetResourcePid, theSystem, theCode)); concepts.addAll(findByValueSetResourcePidSystemAndCode(valueSetResourcePid, theSystem, theCode));
} }
@ -1647,7 +1645,7 @@ public class TermReadSvcImpl implements ITermReadSvc {
return null; return null;
} }
TermValueSet valueSetEntity = myTermValueSetDao.findByResourcePid(valueSetResourcePid.getIdAsLong()).orElseThrow(IllegalStateException::new); TermValueSet valueSetEntity = myTermValueSetDao.findByResourcePid(valueSetResourcePid.getId()).orElseThrow(IllegalStateException::new);
String timingDescription = toHumanReadableExpansionTimestamp(valueSetEntity); String timingDescription = toHumanReadableExpansionTimestamp(valueSetEntity);
String msg = myContext.getLocalizer().getMessage(TermReadSvcImpl.class, "validationPerformedAgainstPreExpansion", timingDescription); String msg = myContext.getLocalizer().getMessage(TermReadSvcImpl.class, "validationPerformedAgainstPreExpansion", timingDescription);
@ -1696,7 +1694,7 @@ public class TermReadSvcImpl implements ITermReadSvc {
.setMessage("Unable to validate code " + theSystem + "#" + theCode + theAppend); .setMessage("Unable to validate code " + theSystem + "#" + theCode + theAppend);
} }
private List<TermValueSetConcept> findByValueSetResourcePidSystemAndCode(ResourcePersistentId theResourcePid, String theSystem, String theCode) { private List<TermValueSetConcept> findByValueSetResourcePidSystemAndCode(JpaPid theResourcePid, String theSystem, String theCode) {
assert TransactionSynchronizationManager.isSynchronizationActive(); assert TransactionSynchronizationManager.isSynchronizationActive();
List<TermValueSetConcept> retVal = new ArrayList<>(); List<TermValueSetConcept> retVal = new ArrayList<>();
@ -1705,9 +1703,11 @@ public class TermReadSvcImpl implements ITermReadSvc {
if (versionIndex >= 0) { if (versionIndex >= 0) {
String systemUrl = theSystem.substring(0, versionIndex); String systemUrl = theSystem.substring(0, versionIndex);
String systemVersion = theSystem.substring(versionIndex + 1); String systemVersion = theSystem.substring(versionIndex + 1);
optionalTermValueSetConcept = myValueSetConceptDao.findByValueSetResourcePidSystemAndCodeWithVersion(theResourcePid.getIdAsLong(), systemUrl, systemVersion, theCode); optionalTermValueSetConcept = myValueSetConceptDao.findByValueSetResourcePidSystemAndCodeWithVersion(
theResourcePid.getId(), systemUrl, systemVersion, theCode);
} else { } else {
optionalTermValueSetConcept = myValueSetConceptDao.findByValueSetResourcePidSystemAndCode(theResourcePid.getIdAsLong(), theSystem, theCode); optionalTermValueSetConcept = myValueSetConceptDao.findByValueSetResourcePidSystemAndCode(
theResourcePid.getId(), theSystem, theCode);
} }
optionalTermValueSetConcept.ifPresent(retVal::add); optionalTermValueSetConcept.ifPresent(retVal::add);
return retVal; return retVal;

View File

@ -26,12 +26,12 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.UploadStatistics; import ca.uhn.fhir.jpa.term.UploadStatistics;
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet; import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.model.ValueSet;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
/** /**
@ -50,16 +50,16 @@ public interface ITermCodeSystemStorageSvc {
(boolean) theRequestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE); (boolean) theRequestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
} }
void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, void storeNewCodeSystemVersion(IResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName,
String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable,
RequestDetails theRequestDetails); RequestDetails theRequestDetails);
/** /**
* Default implementation supports previous signature of method which was added RequestDetails parameter * Default implementation supports previous signature of method which was added RequestDetails parameter
*/ */
@Transactional @Transactional
default void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, default void storeNewCodeSystemVersion(IResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName,
String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) { String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) {
storeNewCodeSystemVersion(theCodeSystemResourcePid, theSystemUri, theSystemName, theSystemVersionId, storeNewCodeSystemVersion(theCodeSystemResourcePid, theSystemUri, theSystemName, theSystemVersionId,
theCodeSystemVersion, theCodeSystemResourceTable, null); theCodeSystemVersion, theCodeSystemResourceTable, null);

View File

@ -25,12 +25,12 @@ import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchInclude; import ca.uhn.fhir.jpa.entity.SearchInclude;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum; import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
@ -194,7 +194,7 @@ public class QueryParameterUtils {
return lastUpdatedPredicates; return lastUpdatedPredicates;
} }
public static List<ResourcePersistentId> filterResourceIdsByLastUpdated(EntityManager theEntityManager, final DateRangeParam theLastUpdated, Collection<ResourcePersistentId> thePids) { public static List<JpaPid> filterResourceIdsByLastUpdated(EntityManager theEntityManager, final DateRangeParam theLastUpdated, Collection<JpaPid> thePids) {
if (thePids.isEmpty()) { if (thePids.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
@ -204,12 +204,13 @@ public class QueryParameterUtils {
cq.select(from.get("myId").as(Long.class)); cq.select(from.get("myId").as(Long.class));
List<Predicate> lastUpdatedPredicates = createLastUpdatedPredicates(theLastUpdated, builder, from); List<Predicate> lastUpdatedPredicates = createLastUpdatedPredicates(theLastUpdated, builder, from);
lastUpdatedPredicates.add(from.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(thePids))); List<Long> longIds = thePids.stream().map(JpaPid::getId).collect(Collectors.toList());
lastUpdatedPredicates.add(from.get("myId").as(Long.class).in(longIds));
cq.where(toPredicateArray(lastUpdatedPredicates)); cq.where(toPredicateArray(lastUpdatedPredicates));
TypedQuery<Long> query = theEntityManager.createQuery(cq); TypedQuery<Long> query = theEntityManager.createQuery(cq);
return ResourcePersistentId.fromLongList(query.getResultList()); return query.getResultList().stream().map(JpaPid::fromId).collect(Collectors.toList());
} }
public static void verifySearchHasntFailedOrThrowInternalErrorException(Search theSearch) { public static void verifySearchHasntFailedOrThrowInternalErrorException(Search theSearch) {

View File

@ -13,6 +13,7 @@ import ca.uhn.fhir.jpa.dao.IResultIterator;
import ca.uhn.fhir.jpa.dao.ISearchBuilder; import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.dao.mdm.MdmExpansionCacheSvc; import ca.uhn.fhir.jpa.dao.mdm.MdmExpansionCacheSvc;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -21,10 +22,8 @@ import ca.uhn.fhir.mdm.dao.IMdmLinkDao;
import ca.uhn.fhir.mdm.model.MdmPidTuple; import ca.uhn.fhir.mdm.model.MdmPidTuple;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions; import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.BaseResourcePersistentId;
import ca.uhn.fhir.rest.param.HasOrListParam; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.param.HasParam;
import ch.qos.logback.classic.spi.ILoggingEvent;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Group; import org.hl7.fhir.r4.model.Group;
@ -34,7 +33,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.ArgumentMatcher;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Spy; import org.mockito.Spy;
@ -52,7 +50,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import static ca.uhn.fhir.rest.api.Constants.PARAM_HAS;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
@ -60,9 +57,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.AdditionalMatchers.not; import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -72,11 +67,11 @@ public class JpaBulkExportProcessorTest {
private class ListResultIterator implements IResultIterator { private class ListResultIterator implements IResultIterator {
private List<ResourcePersistentId> myList; private List<IResourcePersistentId> myList;
private int index; private int index;
public ListResultIterator(List<ResourcePersistentId> theList) { public ListResultIterator(List<IResourcePersistentId> theList) {
myList = theList; myList = theList;
} }
@ -91,7 +86,7 @@ public class JpaBulkExportProcessorTest {
} }
@Override @Override
public Collection<ResourcePersistentId> getNextResultBatch(long theBatchSize) { public Collection<IResourcePersistentId> getNextResultBatch(long theBatchSize) {
return null; return null;
} }
@ -106,7 +101,7 @@ public class JpaBulkExportProcessorTest {
} }
@Override @Override
public ResourcePersistentId next() { public IResourcePersistentId next() {
return myList.get(index++); return myList.get(index++);
} }
} }
@ -163,17 +158,7 @@ public class JpaBulkExportProcessorTest {
} }
private MdmPidTuple createTuple(long theGroupId, long theGoldenId) { private MdmPidTuple createTuple(long theGroupId, long theGoldenId) {
return new MdmPidTuple() { return MdmPidTuple.fromGoldenAndSource(JpaPid.fromId(theGoldenId), JpaPid.fromId(theGroupId));
@Override
public ResourcePersistentId getGoldenPid() {
return new ResourcePersistentId(theGoldenId);
}
@Override
public ResourcePersistentId getSourcePid() {
return new ResourcePersistentId(theGroupId);
}
};
} }
@Test @Test
@ -186,8 +171,8 @@ public class JpaBulkExportProcessorTest {
List<SearchParameterMap> maps = new ArrayList<>(); List<SearchParameterMap> maps = new ArrayList<>();
maps.add(map); maps.add(map);
ResourcePersistentId pid = new ResourcePersistentId("Patient/123"); JpaPid pid = JpaPid.fromId(123L);
ResourcePersistentId pid2 = new ResourcePersistentId("Observation/123"); JpaPid pid2 = JpaPid.fromId(456L);
ListResultIterator resultIterator = new ListResultIterator( ListResultIterator resultIterator = new ListResultIterator(
Arrays.asList(pid, pid2) Arrays.asList(pid, pid2)
); );
@ -215,7 +200,7 @@ public class JpaBulkExportProcessorTest {
.thenReturn(resultIterator); .thenReturn(resultIterator);
// test // test
Iterator<ResourcePersistentId> pidIterator = myProcessor.getResourcePidIterator(parameters); Iterator<JpaPid> pidIterator = myProcessor.getResourcePidIterator(parameters);
// verify // verify
assertNotNull(pidIterator); assertNotNull(pidIterator);
@ -252,19 +237,19 @@ public class JpaBulkExportProcessorTest {
ExportPIDIteratorParameters parameters = createExportParameters(BulkDataExportOptions.ExportStyle.GROUP); ExportPIDIteratorParameters parameters = createExportParameters(BulkDataExportOptions.ExportStyle.GROUP);
parameters.setResourceType("Patient"); parameters.setResourceType("Patient");
ResourcePersistentId groupId = new ResourcePersistentId(Long.parseLong(parameters.getGroupId())); JpaPid groupId = JpaPid.fromId(Long.parseLong(parameters.getGroupId()));
long groupGoldenPid = 4567l; long groupGoldenPid = 4567l;
Group groupResource = new Group(); Group groupResource = new Group();
groupResource.setId(parameters.getGroupId()); groupResource.setId(parameters.getGroupId());
List<IPrimitiveType> patientTypes = createPatientTypes(); List<IPrimitiveType> patientTypes = createPatientTypes();
List<ResourcePersistentId> pids = new ArrayList<>(); List<IResourcePersistentId> pids = new ArrayList<>();
for (IPrimitiveType type : patientTypes) { for (IPrimitiveType type : patientTypes) {
pids.add(new ResourcePersistentId(((IdDt) type).getIdPartAsLong())); pids.add(JpaPid.fromId(((IdDt) type).getIdPartAsLong()));
} }
MdmPidTuple tuple = createTuple(groupId.getIdAsLong(), groupGoldenPid); MdmPidTuple tuple = createTuple(groupId.getId(), groupGoldenPid);
IFhirResourceDao<Group> groupDao = mock(IFhirResourceDao.class); IFhirResourceDao<Group> groupDao = mock(IFhirResourceDao.class);
parameters.setExpandMdm(theMdm); // set mdm expansion parameters.setExpandMdm(theMdm); // set mdm expansion
@ -297,32 +282,32 @@ public class JpaBulkExportProcessorTest {
.thenReturn(groupResource); .thenReturn(groupResource);
when(myIdHelperService.translatePidsToForcedIds(any(Set.class))) when(myIdHelperService.translatePidsToForcedIds(any(Set.class)))
.thenAnswer(params -> { .thenAnswer(params -> {
Set<ResourcePersistentId> uniqPids = params.getArgument(0); Set<IResourcePersistentId> uniqPids = params.getArgument(0);
HashMap<ResourcePersistentId, Optional<String>> answer = new HashMap<>(); HashMap<IResourcePersistentId, Optional<String>> answer = new HashMap<>();
for (ResourcePersistentId l : uniqPids) { for (IResourcePersistentId l : uniqPids) {
answer.put(l, Optional.empty()); answer.put(l, Optional.empty());
} }
return new PersistentIdToForcedIdMap(answer); return new PersistentIdToForcedIdMap(answer);
}); });
when(myIdHelperService.getPidOrNull(any(), any(Group.class))) when(myIdHelperService.getPidOrNull(any(), any(Group.class)))
.thenReturn(groupId); .thenReturn(groupId);
when(myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(any(ResourcePersistentId.class), eq(MdmMatchResultEnum.MATCH))) when(myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(any(BaseResourcePersistentId.class), eq(MdmMatchResultEnum.MATCH)))
.thenReturn(Collections.singletonList(tuple)); .thenReturn(Collections.singletonList(tuple));
when(myMdmExpansionCacheSvc.hasBeenPopulated()) when(myMdmExpansionCacheSvc.hasBeenPopulated())
.thenReturn(false); // does not matter, since if false, it then goes and populates .thenReturn(false); // does not matter, since if false, it then goes and populates
} }
// test // test
Iterator<ResourcePersistentId> pidIterator = myProcessor.getResourcePidIterator(parameters); Iterator<JpaPid> pidIterator = myProcessor.getResourcePidIterator(parameters);
// verify // verify
assertNotNull(pidIterator); assertNotNull(pidIterator);
int count = 0; int count = 0;
assertTrue(pidIterator.hasNext()); assertTrue(pidIterator.hasNext());
while (pidIterator.hasNext()) { while (pidIterator.hasNext()) {
ResourcePersistentId pid = pidIterator.next(); JpaPid pid = pidIterator.next();
long idAsLong = pid.getIdAsLong(); long idAsLong = pid.getId();
boolean existing = pids.contains(new ResourcePersistentId(idAsLong)); boolean existing = pids.contains(JpaPid.fromId(idAsLong));
if (!existing) { if (!existing) {
assertTrue(theMdm); assertTrue(theMdm);
assertEquals(groupGoldenPid, idAsLong); assertEquals(groupGoldenPid, idAsLong);
@ -341,18 +326,18 @@ public class JpaBulkExportProcessorTest {
ExportPIDIteratorParameters parameters = createExportParameters(BulkDataExportOptions.ExportStyle.GROUP); ExportPIDIteratorParameters parameters = createExportParameters(BulkDataExportOptions.ExportStyle.GROUP);
parameters.setResourceType("Observation"); parameters.setResourceType("Observation");
ResourcePersistentId groupId = new ResourcePersistentId(Long.parseLong(parameters.getGroupId())); JpaPid groupId = JpaPid.fromId(Long.parseLong(parameters.getGroupId()));
Group groupResource = new Group(); Group groupResource = new Group();
groupResource.setId(parameters.getGroupId()); groupResource.setId(parameters.getGroupId());
long groupGoldenPid = 4567l; long groupGoldenPid = 4567l;
ResourcePersistentId pid = new ResourcePersistentId("Patient/123"); JpaPid pid = JpaPid.fromId(123L);
ResourcePersistentId pid2 = new ResourcePersistentId("Observation/123"); JpaPid pid2 = JpaPid.fromId(456L);
ListResultIterator resultIterator = new ListResultIterator( ListResultIterator resultIterator = new ListResultIterator(
Arrays.asList(pid, pid2) Arrays.asList(pid, pid2)
); );
MdmPidTuple tuple = createTuple(groupId.getIdAsLong(), groupGoldenPid); MdmPidTuple tuple = createTuple(groupId.getId(), groupGoldenPid);
List<IPrimitiveType> patientTypes = createPatientTypes(); List<IPrimitiveType> patientTypes = createPatientTypes();
IFhirResourceDao<Group> groupDao = mock(IFhirResourceDao.class); IFhirResourceDao<Group> groupDao = mock(IFhirResourceDao.class);
@ -387,13 +372,13 @@ public class JpaBulkExportProcessorTest {
.thenReturn(resultIterator); .thenReturn(resultIterator);
if (theMdm) { if (theMdm) {
when(myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(any(ResourcePersistentId.class), eq(MdmMatchResultEnum.MATCH))) when(myMdmLinkDao.expandPidsFromGroupPidGivenMatchResult(any(BaseResourcePersistentId.class), eq(MdmMatchResultEnum.MATCH)))
.thenReturn(Collections.singletonList(tuple)); .thenReturn(Collections.singletonList(tuple));
when(myIdHelperService.translatePidsToForcedIds(any(Set.class))) when(myIdHelperService.translatePidsToForcedIds(any(Set.class)))
.thenAnswer(params -> { .thenAnswer(params -> {
Set<ResourcePersistentId> uniqPids = params.getArgument(0); Set<IResourcePersistentId> uniqPids = params.getArgument(0);
HashMap<ResourcePersistentId, Optional<String>> answer = new HashMap<>(); HashMap<IResourcePersistentId, Optional<String>> answer = new HashMap<>();
for (ResourcePersistentId l : uniqPids) { for (IResourcePersistentId l : uniqPids) {
answer.put(l, Optional.empty()); answer.put(l, Optional.empty());
} }
return new PersistentIdToForcedIdMap(answer); return new PersistentIdToForcedIdMap(answer);
@ -401,7 +386,7 @@ public class JpaBulkExportProcessorTest {
} }
// test // test
Iterator<ResourcePersistentId> pidIterator = myProcessor.getResourcePidIterator(parameters); Iterator<JpaPid> pidIterator = myProcessor.getResourcePidIterator(parameters);
// verify // verify
assertNotNull(pidIterator, "PID iterator null for mdm = " + theMdm); assertNotNull(pidIterator, "PID iterator null for mdm = " + theMdm);
@ -414,8 +399,8 @@ public class JpaBulkExportProcessorTest {
ExportPIDIteratorParameters parameters = createExportParameters(BulkDataExportOptions.ExportStyle.SYSTEM); ExportPIDIteratorParameters parameters = createExportParameters(BulkDataExportOptions.ExportStyle.SYSTEM);
parameters.setResourceType("Patient"); parameters.setResourceType("Patient");
ResourcePersistentId pid = new ResourcePersistentId("Patient/123"); JpaPid pid = JpaPid.fromId(123L);
ResourcePersistentId pid2 = new ResourcePersistentId("Observation/123"); JpaPid pid2 = JpaPid.fromId(456L);
ListResultIterator resultIterator = new ListResultIterator( ListResultIterator resultIterator = new ListResultIterator(
Arrays.asList(pid, pid2) Arrays.asList(pid, pid2)
); );
@ -444,14 +429,14 @@ public class JpaBulkExportProcessorTest {
)).thenReturn(resultIterator); )).thenReturn(resultIterator);
// test // test
Iterator<ResourcePersistentId> iterator = myProcessor.getResourcePidIterator(parameters); Iterator<JpaPid> iterator = myProcessor.getResourcePidIterator(parameters);
// verify // verify
assertNotNull(iterator); assertNotNull(iterator);
assertTrue(iterator.hasNext()); assertTrue(iterator.hasNext());
int count = 0; int count = 0;
while (iterator.hasNext()) { while (iterator.hasNext()) {
ResourcePersistentId ret = iterator.next(); IResourcePersistentId ret = iterator.next();
assertTrue( assertTrue(
ret.equals(pid) || ret.equals(pid2) ret.equals(pid) || ret.equals(pid2)
); );

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -1,10 +1,10 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.search.builder.SearchBuilder; import ca.uhn.fhir.jpa.search.builder.SearchBuilder;
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl; import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
@ -135,10 +135,10 @@ public class FhirResourceDaoR4SearchLastNIT extends BaseR4SearchLastN {
} }
void verifyResourcesLoadedFromElastic(List<IIdType> theObservationIds, List<String> theResults) { void verifyResourcesLoadedFromElastic(List<IIdType> theObservationIds, List<String> theResults) {
List<ResourcePersistentId> expectedArgumentPids = ResourcePersistentId.fromLongList( List<JpaPid> expectedArgumentPids = JpaPid.fromLongList(
theObservationIds.stream().map(IIdType::getIdPartAsLong).collect(Collectors.toList()) theObservationIds.stream().map(IIdType::getIdPartAsLong).collect(Collectors.toList())
); );
ArgumentCaptor<List<ResourcePersistentId>> actualPids = ArgumentCaptor.forClass(List.class); ArgumentCaptor<List<JpaPid>> actualPids = ArgumentCaptor.forClass(List.class);
verify(myElasticsearchSvc, times(1)).getObservationResources(actualPids.capture()); verify(myElasticsearchSvc, times(1)).getObservationResources(actualPids.capture());
assertThat(actualPids.getValue(), is(expectedArgumentPids)); assertThat(actualPids.getValue(), is(expectedArgumentPids));

View File

@ -17,6 +17,7 @@ import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
@ -35,7 +36,7 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SearchTotalModeEnum; import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringOrListParam; import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.StringParam;
@ -880,7 +881,7 @@ public class FhirResourceDaoR4SearchWithElasticSearchIT extends BaseJpaTest impl
TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA"); TermConcept childCA = new TermConcept(cs, "childCA").setDisplay("Child CA");
parentC.addChild(childCA, TermConceptParentChildLink.RelationshipTypeEnum.ISA); parentC.addChild(childCA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table); myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(JpaPid.fromId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
return codeSystem; return codeSystem;
} }
@ -939,7 +940,7 @@ public class FhirResourceDaoR4SearchWithElasticSearchIT extends BaseJpaTest impl
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map = new SearchParameterMap();
map.add("code", new TokenParam().setSystem("http://example.com")); map.add("code", new TokenParam().setSystem("http://example.com"));
List<ResourcePersistentId> bp = myObservationDao.searchForIds(map, new ServletRequestDetails()); List<IResourcePersistentId> bp = myObservationDao.searchForIds(map, new ServletRequestDetails());
assertNotNull(bp); assertNotNull(bp);
assertEquals(600, bp.size()); assertEquals(600, bp.size());

View File

@ -11,11 +11,11 @@ import ca.uhn.fhir.jpa.config.TestR4ConfigWithElasticHSearch;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.test.BaseJpaTest; import ca.uhn.fhir.jpa.test.BaseJpaTest;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.test.utilities.docker.RequiresDocker; import ca.uhn.fhir.test.utilities.docker.RequiresDocker;
@ -120,7 +120,7 @@ public class FhirResourceDaoR4TerminologyElasticsearchIT extends BaseJpaTest {
concept = new TermConcept(cs, "LA9999-7"); concept = new TermConcept(cs, "LA9999-7");
cs.getConcepts().add(concept); cs.getConcepts().add(concept);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table); myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(JpaPid.fromId(table.getId()), URL_MY_CODE_SYSTEM, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
ValueSet valueSet = new ValueSet(); ValueSet valueSet = new ValueSet();
valueSet.setUrl(URL_MY_VALUE_SET); valueSet.setUrl(URL_MY_VALUE_SET);

View File

@ -15,6 +15,7 @@ import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.entity.TermValueSet; import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum; import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
@ -23,7 +24,6 @@ import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc; import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet; import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
import ca.uhn.fhir.jpa.test.BaseJpaTest; import ca.uhn.fhir.jpa.test.BaseJpaTest;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
@ -171,7 +171,7 @@ public class ValueSetExpansionR4ElasticsearchIT extends BaseJpaTest {
TermConcept parentB = new TermConcept(cs, "ParentB"); TermConcept parentB = new TermConcept(cs, "ParentB");
cs.getConcepts().add(parentB); cs.getConcepts().add(parentB);
myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(new ResourcePersistentId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table); myTermCodeSystemStorageSvc.storeNewCodeSystemVersion(JpaPid.fromId(table.getId()), CS_URL, "SYSTEM NAME", "SYSTEM VERSION", cs, table);
} }

View File

@ -6,10 +6,11 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>6.3.2-SNAPSHOT</version> <version>6.3.3-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<!-- Note that even though this project has jpaserver in the name, it is not require a hapi-fhir jpa database to be available -->
<artifactId>hapi-fhir-jpaserver-mdm</artifactId> <artifactId>hapi-fhir-jpaserver-mdm</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -25,17 +26,18 @@
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId> <artifactId>spring-data-jpa</artifactId>
</dependency> </dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-jpaserver-base</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-storage-mdm</artifactId> <artifactId>hapi-fhir-storage-mdm</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- test --> <!-- test -->
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-jpaserver-base</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-jpaserver-test-utilities</artifactId> <artifactId>hapi-fhir-jpaserver-test-utilities</artifactId>
@ -117,6 +119,29 @@
</dependency> </dependency>
</dependencies> </dependencies>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-banned-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<!-- It is important that this project not depend on jpaserver-base -->
<exclude>ca.uhn.hapi.fhir:hapi-fhir-jpaserver-base:${project.version}:jar:compile</exclude>
</excludes>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -21,17 +21,13 @@ package ca.uhn.fhir.jpa.mdm.config;
*/ */
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.mdm.MdmLinkDaoJpaImpl;
import ca.uhn.fhir.jpa.mdm.dao.JpaMdmLinkImplFactory;
import ca.uhn.fhir.jpa.mdm.interceptor.MdmSubmitterInterceptorLoader; import ca.uhn.fhir.jpa.mdm.interceptor.MdmSubmitterInterceptorLoader;
import ca.uhn.fhir.mdm.dao.IMdmLinkImplFactory;
import ca.uhn.fhir.mdm.svc.MdmChannelSubmitterSvcImpl;
import ca.uhn.fhir.mdm.dao.IMdmLinkDao;
import ca.uhn.fhir.mdm.svc.MdmSearchParamSvc;
import ca.uhn.fhir.mdm.svc.MdmSubmitSvcImpl;
import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory; import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory;
import ca.uhn.fhir.mdm.api.IMdmChannelSubmitterSvc; import ca.uhn.fhir.mdm.api.IMdmChannelSubmitterSvc;
import ca.uhn.fhir.mdm.api.IMdmSubmitSvc; import ca.uhn.fhir.mdm.api.IMdmSubmitSvc;
import ca.uhn.fhir.mdm.svc.MdmChannelSubmitterSvcImpl;
import ca.uhn.fhir.mdm.svc.MdmSearchParamSvc;
import ca.uhn.fhir.mdm.svc.MdmSubmitSvcImpl;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@ -61,12 +57,4 @@ public class MdmSubmitterConfig {
IMdmSubmitSvc mdmSubmitService() { IMdmSubmitSvc mdmSubmitService() {
return new MdmSubmitSvcImpl(); return new MdmSubmitSvcImpl();
} }
@Bean
IMdmLinkDao mdmLinkDao(){
return new MdmLinkDaoJpaImpl();
}
@Bean
IMdmLinkImplFactory mdmLinkImplFactory() {return new JpaMdmLinkImplFactory();}
} }

View File

@ -34,7 +34,7 @@ import ca.uhn.fhir.mdm.dao.MdmLinkFactory;
import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
@ -52,22 +52,22 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
public class MdmLinkDaoSvc { public class MdmLinkDaoSvc<P extends IResourcePersistentId, M extends IMdmLink<P>> {
private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); private static final Logger ourLog = Logs.getMdmTroubleshootingLog();
@Autowired @Autowired
private IMdmLinkDao myMdmLinkDao; private IMdmLinkDao<P, M> myMdmLinkDao;
@Autowired @Autowired
private MdmLinkFactory myMdmLinkFactory; private MdmLinkFactory<M> myMdmLinkFactory;
@Autowired @Autowired
private IIdHelperService myIdHelperService; private IIdHelperService<P> myIdHelperService;
@Autowired @Autowired
private FhirContext myFhirContext; private FhirContext myFhirContext;
@Transactional @Transactional
public IMdmLink createOrUpdateLinkEntity(IAnyResource theGoldenResource, IAnyResource theSourceResource, MdmMatchOutcome theMatchOutcome, MdmLinkSourceEnum theLinkSource, @Nullable MdmTransactionContext theMdmTransactionContext) { public M createOrUpdateLinkEntity(IAnyResource theGoldenResource, IAnyResource theSourceResource, MdmMatchOutcome theMatchOutcome, MdmLinkSourceEnum theLinkSource, @Nullable MdmTransactionContext theMdmTransactionContext) {
IMdmLink mdmLink = getOrCreateMdmLinkByGoldenResourceAndSourceResource(theGoldenResource, theSourceResource); M mdmLink = getOrCreateMdmLinkByGoldenResourceAndSourceResource(theGoldenResource, theSourceResource);
mdmLink.setLinkSource(theLinkSource); mdmLink.setLinkSource(theLinkSource);
mdmLink.setMatchResult(theMatchOutcome.getMatchResultEnum()); mdmLink.setMatchResult(theMatchOutcome.getMatchResultEnum());
// Preserve these flags for link updates // Preserve these flags for link updates
@ -93,16 +93,16 @@ public class MdmLinkDaoSvc {
} }
@Nonnull @Nonnull
public IMdmLink getOrCreateMdmLinkByGoldenResourceAndSourceResource( public M getOrCreateMdmLinkByGoldenResourceAndSourceResource(
IAnyResource theGoldenResource, IAnyResource theSourceResource IAnyResource theGoldenResource, IAnyResource theSourceResource
) { ) {
ResourcePersistentId goldenResourcePid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theGoldenResource); P goldenResourcePid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theGoldenResource);
ResourcePersistentId sourceResourcePid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource); P sourceResourcePid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource);
Optional<? extends IMdmLink> oExisting = getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourcePid, sourceResourcePid); Optional<M> oExisting = getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourcePid, sourceResourcePid);
if (oExisting.isPresent()) { if (oExisting.isPresent()) {
return oExisting.get(); return oExisting.get();
} else { } else {
IMdmLink newLink = myMdmLinkFactory.newMdmLink(); M newLink = myMdmLinkFactory.newMdmLink();
newLink.setGoldenResourcePersistenceId(goldenResourcePid); newLink.setGoldenResourcePersistenceId(goldenResourcePid);
newLink.setSourcePersistenceId(sourceResourcePid); newLink.setSourcePersistenceId(sourceResourcePid);
return newLink; return newLink;
@ -111,14 +111,15 @@ public class MdmLinkDaoSvc {
/** /**
* Given a golden resource Pid and source Pid, return the mdm link that matches these criterias if exists * Given a golden resource Pid and source Pid, return the mdm link that matches these criterias if exists
* @deprecated This was deprecated in favour of using ResourcePersistenceId rather than longs *
* @param theGoldenResourcePid * @param theGoldenResourcePid
* @param theSourceResourcePid * @param theSourceResourcePid
* @return * @return
* @deprecated This was deprecated in favour of using ResourcePersistenceId rather than longs
*/ */
@Deprecated @Deprecated
public Optional<? extends IMdmLink> getLinkByGoldenResourcePidAndSourceResourcePid(Long theGoldenResourcePid, Long theSourceResourcePid) { public Optional<M> getLinkByGoldenResourcePidAndSourceResourcePid(Long theGoldenResourcePid, Long theSourceResourcePid) {
return getLinkByGoldenResourcePidAndSourceResourcePid(new ResourcePersistentId(theGoldenResourcePid), new ResourcePersistentId(theSourceResourcePid)); return getLinkByGoldenResourcePidAndSourceResourcePid(myIdHelperService.newPid(theGoldenResourcePid), myIdHelperService.newPid(theSourceResourcePid));
} }
/** /**
@ -128,16 +129,16 @@ public class MdmLinkDaoSvc {
* @return The {@link IMdmLink} entity that matches these criteria if exists * @return The {@link IMdmLink} entity that matches these criteria if exists
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Optional<? extends IMdmLink> getLinkByGoldenResourcePidAndSourceResourcePid(ResourcePersistentId theGoldenResourcePid, ResourcePersistentId theSourceResourcePid) { public Optional<M> getLinkByGoldenResourcePidAndSourceResourcePid(P theGoldenResourcePid, P theSourceResourcePid) {
if (theSourceResourcePid == null || theGoldenResourcePid == null) { if (theSourceResourcePid == null || theGoldenResourcePid == null) {
return Optional.empty(); return Optional.empty();
} }
IMdmLink link = myMdmLinkFactory.newMdmLink(); M link = myMdmLinkFactory.newMdmLink();
link.setSourcePersistenceId(theSourceResourcePid); link.setSourcePersistenceId(theSourceResourcePid);
link.setGoldenResourcePersistenceId(theGoldenResourcePid); link.setGoldenResourcePersistenceId(theGoldenResourcePid);
//TODO - replace the use of example search //TODO - replace the use of example search
Example<? extends IMdmLink> example = Example.of(link); Example<M> example = Example.of(link);
return myMdmLinkDao.findOne(example); return myMdmLinkDao.findOne(example);
} }
@ -149,11 +150,11 @@ public class MdmLinkDaoSvc {
* @param theMatchResult the Match Result of the relationship * @param theMatchResult the Match Result of the relationship
* @return a list of {@link IMdmLink} entities matching these criteria. * @return a list of {@link IMdmLink} entities matching these criteria.
*/ */
public List<? extends IMdmLink> getMdmLinksBySourcePidAndMatchResult(ResourcePersistentId theSourcePid, MdmMatchResultEnum theMatchResult) { public List<M> getMdmLinksBySourcePidAndMatchResult(P theSourcePid, MdmMatchResultEnum theMatchResult) {
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setSourcePersistenceId(theSourcePid); exampleLink.setSourcePersistenceId(theSourcePid);
exampleLink.setMatchResult(theMatchResult); exampleLink.setMatchResult(theMatchResult);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findAll(example); return myMdmLinkDao.findAll(example);
} }
@ -166,7 +167,7 @@ public class MdmLinkDaoSvc {
*/ */
@Deprecated @Deprecated
@Transactional @Transactional
public Optional<? extends IMdmLink> getMatchedLinkForSourcePid(ResourcePersistentId theSourcePid) { public Optional<M> getMatchedLinkForSourcePid(P theSourcePid) {
return myMdmLinkDao.findBySourcePidAndMatchResult(theSourcePid, MdmMatchResultEnum.MATCH); return myMdmLinkDao.findBySourcePidAndMatchResult(theSourcePid, MdmMatchResultEnum.MATCH);
} }
@ -177,25 +178,25 @@ public class MdmLinkDaoSvc {
* @param theSourceResource The IBaseResource representing the source you wish to find the matching link for. * @param theSourceResource The IBaseResource representing the source you wish to find the matching link for.
* @return the {@link IMdmLink} that contains the Match information for the source. * @return the {@link IMdmLink} that contains the Match information for the source.
*/ */
public Optional<? extends IMdmLink> getMatchedLinkForSource(IBaseResource theSourceResource) { public Optional<M> getMatchedLinkForSource(IBaseResource theSourceResource) {
return getMdmLinkWithMatchResult(theSourceResource, MdmMatchResultEnum.MATCH); return getMdmLinkWithMatchResult(theSourceResource, MdmMatchResultEnum.MATCH);
} }
public Optional<? extends IMdmLink> getPossibleMatchedLinkForSource(IBaseResource theSourceResource) { public Optional<M> getPossibleMatchedLinkForSource(IBaseResource theSourceResource) {
return getMdmLinkWithMatchResult(theSourceResource, MdmMatchResultEnum.POSSIBLE_MATCH); return getMdmLinkWithMatchResult(theSourceResource, MdmMatchResultEnum.POSSIBLE_MATCH);
} }
@Nonnull @Nonnull
private Optional<? extends IMdmLink> getMdmLinkWithMatchResult(IBaseResource theSourceResource, MdmMatchResultEnum theMatchResult) { private Optional<M> getMdmLinkWithMatchResult(IBaseResource theSourceResource, MdmMatchResultEnum theMatchResult) {
ResourcePersistentId pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource); P pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource);
if (pid == null) { if (pid == null) {
return Optional.empty(); return Optional.empty();
} }
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setSourcePersistenceId(pid); exampleLink.setSourcePersistenceId(pid);
exampleLink.setMatchResult(theMatchResult); exampleLink.setMatchResult(theMatchResult);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findOne(example); return myMdmLinkDao.findOne(example);
} }
@ -207,18 +208,18 @@ public class MdmLinkDaoSvc {
* @param theMatchResult The MatchResult you are looking for. * @param theMatchResult The MatchResult you are looking for.
* @return an Optional {@link IMdmLink} containing the matched link if it exists. * @return an Optional {@link IMdmLink} containing the matched link if it exists.
*/ */
public Optional<? extends IMdmLink> getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(Long theGoldenResourcePid, public Optional<M> getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(Long theGoldenResourcePid,
Long theSourcePid, MdmMatchResultEnum theMatchResult) { Long theSourcePid, MdmMatchResultEnum theMatchResult) {
return getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(new ResourcePersistentId(theGoldenResourcePid), new ResourcePersistentId(theSourcePid), theMatchResult); return getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(myIdHelperService.newPid(theGoldenResourcePid), myIdHelperService.newPid(theSourcePid), theMatchResult);
} }
public Optional<? extends IMdmLink> getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(ResourcePersistentId theGoldenResourcePid, public Optional<M> getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(P theGoldenResourcePid,
ResourcePersistentId theSourcePid, MdmMatchResultEnum theMatchResult) { P theSourcePid, MdmMatchResultEnum theMatchResult) {
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setGoldenResourcePersistenceId(theGoldenResourcePid); exampleLink.setGoldenResourcePersistenceId(theGoldenResourcePid);
exampleLink.setSourcePersistenceId(theSourcePid); exampleLink.setSourcePersistenceId(theSourcePid);
exampleLink.setMatchResult(theMatchResult); exampleLink.setMatchResult(theMatchResult);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findOne(example); return myMdmLinkDao.findOne(example);
} }
@ -227,22 +228,22 @@ public class MdmLinkDaoSvc {
* *
* @return A list of {@link IMdmLink} that hold potential duplicate golden resources. * @return A list of {@link IMdmLink} that hold potential duplicate golden resources.
*/ */
public List<? extends IMdmLink> getPossibleDuplicates() { public List<M> getPossibleDuplicates() {
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setMatchResult(MdmMatchResultEnum.POSSIBLE_DUPLICATE); exampleLink.setMatchResult(MdmMatchResultEnum.POSSIBLE_DUPLICATE);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findAll(example); return myMdmLinkDao.findAll(example);
} }
@Transactional @Transactional
public Optional<? extends IMdmLink> findMdmLinkBySource(IBaseResource theSourceResource) { public Optional<M> findMdmLinkBySource(IBaseResource theSourceResource) {
@Nullable ResourcePersistentId pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource); @Nullable P pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource);
if (pid == null) { if (pid == null) {
return Optional.empty(); return Optional.empty();
} }
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setSourcePersistenceId(pid); exampleLink.setSourcePersistenceId(pid);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findOne(example); return myMdmLinkDao.findOne(example);
} }
@ -253,7 +254,7 @@ public class MdmLinkDaoSvc {
* @param theMdmLink the {@link IMdmLink} to delete. * @param theMdmLink the {@link IMdmLink} to delete.
*/ */
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRES_NEW)
public void deleteLink(IMdmLink theMdmLink) { public void deleteLink(M theMdmLink) {
myMdmLinkDao.validateMdmLink(theMdmLink); myMdmLinkDao.validateMdmLink(theMdmLink);
myMdmLinkDao.delete(theMdmLink); myMdmLinkDao.delete(theMdmLink);
} }
@ -265,14 +266,14 @@ public class MdmLinkDaoSvc {
* @return A list of all {@link IMdmLink} entities in which theGoldenResource is the source Golden Resource * @return A list of all {@link IMdmLink} entities in which theGoldenResource is the source Golden Resource
*/ */
@Transactional @Transactional
public List<? extends IMdmLink> findMdmLinksByGoldenResource(IBaseResource theGoldenResource) { public List<M> findMdmLinksByGoldenResource(IBaseResource theGoldenResource) {
ResourcePersistentId pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theGoldenResource); P pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theGoldenResource);
if (pid == null) { if (pid == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setGoldenResourcePersistenceId(pid); exampleLink.setGoldenResourcePersistenceId(pid);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findAll(example); return myMdmLinkDao.findAll(example);
} }
@ -282,8 +283,8 @@ public class MdmLinkDaoSvc {
* @param theMdmLink the link to save. * @param theMdmLink the link to save.
* @return the persisted {@link IMdmLink} entity. * @return the persisted {@link IMdmLink} entity.
*/ */
public IMdmLink save(IMdmLink theMdmLink) { public M save(M theMdmLink) {
IMdmLink mdmLink = myMdmLinkDao.validateMdmLink(theMdmLink); M mdmLink = myMdmLinkDao.validateMdmLink(theMdmLink);
if (mdmLink.getCreated() == null) { if (mdmLink.getCreated() == null) {
mdmLink.setCreated(new Date()); mdmLink.setCreated(new Date());
} }
@ -303,7 +304,7 @@ public class MdmLinkDaoSvc {
* @param thePartitionId List of partitions ID being searched, where the link's partition must be in the list. * @param thePartitionId List of partitions ID being searched, where the link's partition must be in the list.
* @return a list of {@link IMdmLink} entities which match the example. * @return a list of {@link IMdmLink} entities which match the example.
*/ */
public Page<? extends IMdmLink> executeTypedQuery(IIdType theGoldenResourceId, IIdType theSourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource, MdmPageRequest thePageRequest, List<Integer> thePartitionId) { public Page<M> executeTypedQuery(IIdType theGoldenResourceId, IIdType theSourceId, MdmMatchResultEnum theMatchResult, MdmLinkSourceEnum theLinkSource, MdmPageRequest thePageRequest, List<Integer> thePartitionId) {
return myMdmLinkDao.search(theGoldenResourceId, theSourceId, theMatchResult, theLinkSource, thePageRequest, thePartitionId); return myMdmLinkDao.search(theGoldenResourceId, theSourceId, theMatchResult, theLinkSource, thePageRequest, thePartitionId);
} }
@ -315,14 +316,14 @@ public class MdmLinkDaoSvc {
* @return all links for the source. * @return all links for the source.
*/ */
@Transactional @Transactional
public List<? extends IMdmLink> findMdmLinksBySourceResource(IBaseResource theSourceResource) { public List<M> findMdmLinksBySourceResource(IBaseResource theSourceResource) {
ResourcePersistentId pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource); P pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theSourceResource);
if (pid == null) { if (pid == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setSourcePersistenceId(pid); exampleLink.setSourcePersistenceId(pid);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findAll(example); return myMdmLinkDao.findAll(example);
} }
@ -333,15 +334,15 @@ public class MdmLinkDaoSvc {
* @param theGoldenResource the source resource to find links for. * @param theGoldenResource the source resource to find links for.
* @return all links for the source. * @return all links for the source.
*/ */
public List<? extends IMdmLink> findMdmMatchLinksByGoldenResource(IBaseResource theGoldenResource) { public List<M> findMdmMatchLinksByGoldenResource(IBaseResource theGoldenResource) {
ResourcePersistentId pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theGoldenResource); P pid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theGoldenResource);
if (pid == null) { if (pid == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
IMdmLink exampleLink = myMdmLinkFactory.newMdmLink(); M exampleLink = myMdmLinkFactory.newMdmLink();
exampleLink.setGoldenResourcePersistenceId(pid); exampleLink.setGoldenResourcePersistenceId(pid);
exampleLink.setMatchResult(MdmMatchResultEnum.MATCH); exampleLink.setMatchResult(MdmMatchResultEnum.MATCH);
Example<? extends IMdmLink> example = Example.of(exampleLink); Example<M> example = Example.of(exampleLink);
return myMdmLinkDao.findAll(example); return myMdmLinkDao.findAll(example);
} }
@ -355,16 +356,16 @@ public class MdmLinkDaoSvc {
return myMdmLinkFactory.newMdmLink(); return myMdmLinkFactory.newMdmLink();
} }
public Optional<? extends IMdmLink> getMatchedOrPossibleMatchedLinkForSource(IAnyResource theResource) { public Optional<M> getMatchedOrPossibleMatchedLinkForSource(IAnyResource theResource) {
// TODO KHS instead of two queries, just do one query with an OR // TODO KHS instead of two queries, just do one query with an OR
Optional<? extends IMdmLink> retval = getMatchedLinkForSource(theResource); Optional<M> retval = getMatchedLinkForSource(theResource);
if (!retval.isPresent()) { if (!retval.isPresent()) {
retval = getPossibleMatchedLinkForSource(theResource); retval = getPossibleMatchedLinkForSource(theResource);
} }
return retval; return retval;
} }
public Optional<? extends IMdmLink> getLinkByGoldenResourceAndSourceResource(@Nullable IAnyResource theGoldenResource, @Nullable IAnyResource theSourceResource) { public Optional<M> getLinkByGoldenResourceAndSourceResource(@Nullable IAnyResource theGoldenResource, @Nullable IAnyResource theSourceResource) {
if (theGoldenResource == null || theSourceResource == null) { if (theGoldenResource == null || theSourceResource == null) {
return Optional.empty(); return Optional.empty();
} }
@ -374,7 +375,7 @@ public class MdmLinkDaoSvc {
} }
@Transactional(propagation = Propagation.MANDATORY) @Transactional(propagation = Propagation.MANDATORY)
public void deleteLinksWithAnyReferenceToPids(List<ResourcePersistentId> theGoldenResourcePids) { public void deleteLinksWithAnyReferenceToPids(List<P> theGoldenResourcePids) {
myMdmLinkDao.deleteLinksWithAnyReferenceToPids(theGoldenResourcePids); myMdmLinkDao.deleteLinksWithAnyReferenceToPids(theGoldenResourcePids);
} }
} }

View File

@ -36,7 +36,7 @@ import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.util.GoldenResourceHelper; import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
import ca.uhn.fhir.mdm.util.MdmResourceUtil; import ca.uhn.fhir.mdm.util.MdmResourceUtil;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
@ -178,7 +178,7 @@ public class GoldenResourceMergerSvcImpl implements IGoldenResourceMergerSvc {
List<? extends IMdmLink> toLinks = myMdmLinkDaoSvc.findMdmLinksByGoldenResource(theToResource); List<? extends IMdmLink> toLinks = myMdmLinkDaoSvc.findMdmLinksByGoldenResource(theToResource);
List<IMdmLink> toDelete = new ArrayList<>(); List<IMdmLink> toDelete = new ArrayList<>();
ResourcePersistentId goldenResourcePid = myIdHelperService.resolveResourcePersistentIds( IResourcePersistentId goldenResourcePid = myIdHelperService.resolveResourcePersistentIds(
getPartitionIdForResource(theToResource), getPartitionIdForResource(theToResource),
theToResource.getIdElement().getResourceType(), theToResource.getIdElement().getResourceType(),
theToResource.getIdElement().getIdPart() theToResource.getIdElement().getIdPart()

View File

@ -35,7 +35,7 @@ import ca.uhn.fhir.mdm.api.MdmConstants;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortOrderEnum; import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.util.DateRangeUtil; import ca.uhn.fhir.util.DateRangeUtil;
@ -77,7 +77,7 @@ public class GoldenResourceSearchSvcImpl implements IGoldenResourceSearchSvc {
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceType); IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceType);
SystemRequestDetails request = new SystemRequestDetails(); SystemRequestDetails request = new SystemRequestDetails();
request.setRequestPartitionId(theRequestPartitionId); request.setRequestPartitionId(theRequestPartitionId);
List<ResourcePersistentId> ids = dao.searchForIds(searchParamMap, request); List<IResourcePersistentId> ids = dao.searchForIds(searchParamMap, request);
Date lastDate = null; Date lastDate = null;
if (ids.size() > 0) { if (ids.size() > 0) {

View File

@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.mdm.svc;
* #L% * #L%
*/ */
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLink;
import ca.uhn.fhir.mdm.api.MdmLinkJson; import ca.uhn.fhir.mdm.api.MdmLinkJson;

View File

@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.mdm.svc;
* #L% * #L%
*/ */
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc; import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
import ca.uhn.fhir.jpa.mdm.svc.candidate.MatchedGoldenResourceCandidate; import ca.uhn.fhir.jpa.mdm.svc.candidate.MatchedGoldenResourceCandidate;
import ca.uhn.fhir.jpa.mdm.svc.candidate.MdmGoldenResourceFindingSvc; import ca.uhn.fhir.jpa.mdm.svc.candidate.MdmGoldenResourceFindingSvc;
@ -35,7 +34,7 @@ import ca.uhn.fhir.mdm.model.CanonicalEID;
import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.util.EIDHelper; import ca.uhn.fhir.mdm.util.EIDHelper;
import ca.uhn.fhir.mdm.util.GoldenResourceHelper; import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -168,7 +167,7 @@ public class MdmEidUpdateService {
if (theExistingMatchOrPossibleMatchLink.isPresent()) { if (theExistingMatchOrPossibleMatchLink.isPresent()) {
IMdmLink mdmLink = theExistingMatchOrPossibleMatchLink.get(); IMdmLink mdmLink = theExistingMatchOrPossibleMatchLink.get();
ResourcePersistentId existingGoldenResourcePid = mdmLink.getGoldenResourcePersistenceId(); IResourcePersistentId existingGoldenResourcePid = mdmLink.getGoldenResourcePersistenceId();
myExistingGoldenResource = myMdmResourceDaoSvc.readGoldenResourceByPid(existingGoldenResourcePid, resourceType); myExistingGoldenResource = myMdmResourceDaoSvc.readGoldenResourceByPid(existingGoldenResourcePid, resourceType);
myRemainsMatchedToSameGoldenResource = candidateIsSameAsMdmLinkGoldenResource(mdmLink, theMatchedGoldenResourceCandidate); myRemainsMatchedToSameGoldenResource = candidateIsSameAsMdmLinkGoldenResource(mdmLink, theMatchedGoldenResourceCandidate);
} else { } else {

View File

@ -37,7 +37,7 @@ import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.util.MdmResourceUtil; import ca.uhn.fhir.mdm.util.MdmResourceUtil;
import ca.uhn.fhir.mdm.util.MessageHelper; import ca.uhn.fhir.mdm.util.MessageHelper;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -71,8 +71,8 @@ public class MdmLinkCreateSvcImpl implements IMdmLinkCreateSvc {
validateCreateLinkRequest(theGoldenResource, theSourceResource, sourceType); validateCreateLinkRequest(theGoldenResource, theSourceResource, sourceType);
ResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource); IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
ResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(theSourceResource); IResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(theSourceResource);
// check if the golden resource and the source resource are in the same partition, throw error if not // check if the golden resource and the source resource are in the same partition, throw error if not
myMdmPartitionHelper.validateResourcesInSamePartition(theGoldenResource, theSourceResource); myMdmPartitionHelper.validateResourcesInSamePartition(theGoldenResource, theSourceResource);

View File

@ -31,18 +31,17 @@ import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
/** /**
* This class is in charge of managing MdmLinks between Golden Resources and source resources * This class is in charge of managing MdmLinks between Golden Resources and source resources
@ -79,8 +78,8 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
} }
private boolean goldenResourceLinkedAsNoMatch(IAnyResource theGoldenResource, IAnyResource theSourceResource) { private boolean goldenResourceLinkedAsNoMatch(IAnyResource theGoldenResource, IAnyResource theSourceResource) {
ResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource); IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
ResourcePersistentId sourceId = myIdHelperService.getPidOrThrowException(theSourceResource); IResourcePersistentId sourceId = myIdHelperService.getPidOrThrowException(theSourceResource);
// TODO perf collapse into one query // TODO perf collapse into one query
return myMdmLinkDaoSvc.getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(goldenResourceId, sourceId, MdmMatchResultEnum.NO_MATCH).isPresent() || return myMdmLinkDaoSvc.getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(goldenResourceId, sourceId, MdmMatchResultEnum.NO_MATCH).isPresent() ||
myMdmLinkDaoSvc.getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(sourceId, goldenResourceId, MdmMatchResultEnum.NO_MATCH).isPresent(); myMdmLinkDaoSvc.getMdmLinksByGoldenResourcePidSourcePidAndMatchResult(sourceId, goldenResourceId, MdmMatchResultEnum.NO_MATCH).isPresent();
@ -102,7 +101,7 @@ public class MdmLinkSvcImpl implements IMdmLinkSvc {
@Override @Override
@Transactional @Transactional
public void deleteLinksWithAnyReferenceTo(List<ResourcePersistentId> theGoldenResourceIds) { public void deleteLinksWithAnyReferenceTo(List<IResourcePersistentId> theGoldenResourceIds) {
myMdmLinkDaoSvc.deleteLinksWithAnyReferenceToPids(theGoldenResourceIds); myMdmLinkDaoSvc.deleteLinksWithAnyReferenceToPids(theGoldenResourceIds);
} }

View File

@ -38,7 +38,7 @@ import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.util.MdmResourceUtil; import ca.uhn.fhir.mdm.util.MdmResourceUtil;
import ca.uhn.fhir.mdm.util.MessageHelper; import ca.uhn.fhir.mdm.util.MessageHelper;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
@ -80,8 +80,8 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
validateUpdateLinkRequest(theGoldenResource, theSourceResource, theMatchResult, sourceType); validateUpdateLinkRequest(theGoldenResource, theSourceResource, theMatchResult, sourceType);
ResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource); IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
ResourcePersistentId sourceResourceId = myIdHelperService.getPidOrThrowException(theSourceResource); IResourcePersistentId sourceResourceId = myIdHelperService.getPidOrThrowException(theSourceResource);
// check if the golden resource and the source resource are in the same partition, throw error if not // check if the golden resource and the source resource are in the same partition, throw error if not
myMdmPartitionHelper.validateResourcesInSamePartition(theGoldenResource, theSourceResource); myMdmPartitionHelper.validateResourcesInSamePartition(theGoldenResource, theSourceResource);
@ -130,12 +130,12 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
* doesn't exist, because a resource mustn't be a MATCH to more than one golden resource * doesn't exist, because a resource mustn't be a MATCH to more than one golden resource
*/ */
private void validateNoMatchPresentWhenAcceptingPossibleMatch(IAnyResource theSourceResource, private void validateNoMatchPresentWhenAcceptingPossibleMatch(IAnyResource theSourceResource,
ResourcePersistentId theGoldenResourceId, MdmMatchResultEnum theMatchResult) { IResourcePersistentId theGoldenResourceId, MdmMatchResultEnum theMatchResult) {
// if theMatchResult != MATCH, we are not accepting POSSIBLE_MATCH so there is nothing to validate // if theMatchResult != MATCH, we are not accepting POSSIBLE_MATCH so there is nothing to validate
if (theMatchResult != MdmMatchResultEnum.MATCH) { return; } if (theMatchResult != MdmMatchResultEnum.MATCH) { return; }
ResourcePersistentId sourceResourceId = myIdHelperService.getPidOrThrowException(theSourceResource); IResourcePersistentId sourceResourceId = myIdHelperService.getPidOrThrowException(theSourceResource);
List<? extends IMdmLink> mdmLinks = myMdmLinkDaoSvc List<? extends IMdmLink> mdmLinks = myMdmLinkDaoSvc
.getMdmLinksBySourcePidAndMatchResult(sourceResourceId, MdmMatchResultEnum.MATCH); .getMdmLinksBySourcePidAndMatchResult(sourceResourceId, MdmMatchResultEnum.MATCH);
@ -184,8 +184,8 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
public void notDuplicateGoldenResource(IAnyResource theGoldenResource, IAnyResource theTargetGoldenResource, MdmTransactionContext theMdmContext) { public void notDuplicateGoldenResource(IAnyResource theGoldenResource, IAnyResource theTargetGoldenResource, MdmTransactionContext theMdmContext) {
validateNotDuplicateGoldenResourceRequest(theGoldenResource, theTargetGoldenResource); validateNotDuplicateGoldenResourceRequest(theGoldenResource, theTargetGoldenResource);
ResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource); IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
ResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(theTargetGoldenResource); IResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(theTargetGoldenResource);
Optional<? extends IMdmLink> oMdmLink = myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, targetId); Optional<? extends IMdmLink> oMdmLink = myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, targetId);
if (oMdmLink.isEmpty()) { if (oMdmLink.isEmpty()) {

View File

@ -30,14 +30,14 @@ import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.util.GoldenResourceHelper; import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
import ca.uhn.fhir.mdm.util.MdmResourceUtil; import ca.uhn.fhir.mdm.util.MdmResourceUtil;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.server.TransactionLogMessages; import ca.uhn.fhir.rest.server.TransactionLogMessages;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -93,7 +93,7 @@ public class MdmMatchLinkSvc {
private void handleMdmWithMultipleCandidates(IAnyResource theResource, CandidateList theCandidateList, MdmTransactionContext theMdmTransactionContext) { private void handleMdmWithMultipleCandidates(IAnyResource theResource, CandidateList theCandidateList, MdmTransactionContext theMdmTransactionContext) {
MatchedGoldenResourceCandidate firstMatch = theCandidateList.getFirstMatch(); MatchedGoldenResourceCandidate firstMatch = theCandidateList.getFirstMatch();
ResourcePersistentId sampleGoldenResourcePid = firstMatch.getCandidateGoldenResourcePid(); IResourcePersistentId sampleGoldenResourcePid = firstMatch.getCandidateGoldenResourcePid();
boolean allSameGoldenResource = theCandidateList.stream() boolean allSameGoldenResource = theCandidateList.stream()
.allMatch(candidate -> candidate.getCandidateGoldenResourcePid().equals(sampleGoldenResourcePid)); .allMatch(candidate -> candidate.getCandidateGoldenResourcePid().equals(sampleGoldenResourcePid));

View File

@ -20,8 +20,8 @@ package ca.uhn.fhir.jpa.mdm.svc;
* #L% * #L%
*/ */
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
@ -33,7 +33,7 @@ import ca.uhn.fhir.mdm.api.MdmConstants;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
@ -77,7 +77,7 @@ public class MdmResourceDaoSvc {
resourceDao.removeTag(theGoldenResource.getIdElement(), TagTypeEnum.TAG, MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD, requestDetails); resourceDao.removeTag(theGoldenResource.getIdElement(), TagTypeEnum.TAG, MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD, requestDetails);
} }
public IAnyResource readGoldenResourceByPid(ResourcePersistentId theGoldenResourcePid, String theResourceType) { public IAnyResource readGoldenResourceByPid(IResourcePersistentId theGoldenResourcePid, String theResourceType) {
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType); IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType);
return (IAnyResource) resourceDao.readByPid(theGoldenResourcePid); return (IAnyResource) resourceDao.readByPid(theGoldenResourcePid);
} }

View File

@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
*/ */
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc; import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc;
import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLink;
@ -30,7 +29,7 @@ import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.model.CanonicalEID; import ca.uhn.fhir.mdm.model.CanonicalEID;
import ca.uhn.fhir.mdm.util.EIDHelper; import ca.uhn.fhir.mdm.util.EIDHelper;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -66,7 +65,7 @@ public class FindCandidateByEidSvc extends BaseCandidateFinder {
if (isNoMatch(foundGoldenResource, theIncomingResource)) { if (isNoMatch(foundGoldenResource, theIncomingResource)) {
continue; continue;
} }
ResourcePersistentId pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), foundGoldenResource); IResourcePersistentId pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), foundGoldenResource);
MatchedGoldenResourceCandidate mpc = new MatchedGoldenResourceCandidate(pidOrNull, MdmMatchOutcome.EID_MATCH); MatchedGoldenResourceCandidate mpc = new MatchedGoldenResourceCandidate(pidOrNull, MdmMatchOutcome.EID_MATCH);
ourLog.debug("Incoming Resource {} matched Golden Resource {} by EID {}", theIncomingResource.getIdElement().toUnqualifiedVersionless(), foundGoldenResource.getIdElement().toUnqualifiedVersionless(), eid); ourLog.debug("Incoming Resource {} matched Golden Resource {} by EID {}", theIncomingResource.getIdElement().toUnqualifiedVersionless(), foundGoldenResource.getIdElement().toUnqualifiedVersionless(), eid);
@ -82,7 +81,7 @@ public class FindCandidateByEidSvc extends BaseCandidateFinder {
if (oLink.isEmpty()) { if (oLink.isEmpty()) {
return false; return false;
} }
MdmLink link = (MdmLink) oLink.get(); IMdmLink link = oLink.get();
return link.isNoMatch(); return link.isNoMatch();
} }

View File

@ -30,7 +30,7 @@ import ca.uhn.fhir.mdm.api.MatchedTarget;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -43,14 +43,14 @@ import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
public class FindCandidateByExampleSvc extends BaseCandidateFinder { public class FindCandidateByExampleSvc<P extends IResourcePersistentId> extends BaseCandidateFinder {
private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); private static final Logger ourLog = Logs.getMdmTroubleshootingLog();
@Autowired @Autowired
IIdHelperService myIdHelperService; IIdHelperService<P> myIdHelperService;
@Autowired @Autowired
private FhirContext myFhirContext; private FhirContext myFhirContext;
@Autowired @Autowired
private MdmLinkDaoSvc myMdmLinkDaoSvc; private MdmLinkDaoSvc<P, IMdmLink<P>> myMdmLinkDaoSvc;
@Autowired @Autowired
private IMdmMatchFinderSvc myMdmMatchFinderSvc; private IMdmMatchFinderSvc myMdmMatchFinderSvc;
@ -66,7 +66,7 @@ public class FindCandidateByExampleSvc extends BaseCandidateFinder {
protected List<MatchedGoldenResourceCandidate> findMatchGoldenResourceCandidates(IAnyResource theTarget) { protected List<MatchedGoldenResourceCandidate> findMatchGoldenResourceCandidates(IAnyResource theTarget) {
List<MatchedGoldenResourceCandidate> retval = new ArrayList<>(); List<MatchedGoldenResourceCandidate> retval = new ArrayList<>();
List<ResourcePersistentId> goldenResourcePidsToExclude = getNoMatchGoldenResourcePids(theTarget); List<P> goldenResourcePidsToExclude = getNoMatchGoldenResourcePids(theTarget);
List<MatchedTarget> matchedCandidates = myMdmMatchFinderSvc.getMatchedTargets(myFhirContext.getResourceType(theTarget), theTarget, (RequestPartitionId) theTarget.getUserData(Constants.RESOURCE_PARTITION_ID)); List<MatchedTarget> matchedCandidates = myMdmMatchFinderSvc.getMatchedTargets(myFhirContext.getResourceType(theTarget), theTarget, (RequestPartitionId) theTarget.getUserData(Constants.RESOURCE_PARTITION_ID));
@ -113,8 +113,8 @@ public class FindCandidateByExampleSvc extends BaseCandidateFinder {
return retval; return retval;
} }
private List<ResourcePersistentId> getNoMatchGoldenResourcePids(IBaseResource theBaseResource) { private List<P> getNoMatchGoldenResourcePids(IBaseResource theBaseResource) {
ResourcePersistentId targetPid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theBaseResource); P targetPid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theBaseResource);
return myMdmLinkDaoSvc.getMdmLinksBySourcePidAndMatchResult(targetPid, MdmMatchResultEnum.NO_MATCH) return myMdmLinkDaoSvc.getMdmLinksBySourcePidAndMatchResult(targetPid, MdmMatchResultEnum.NO_MATCH)
.stream() .stream()
.map(IMdmLink::getGoldenResourcePersistenceId) .map(IMdmLink::getGoldenResourcePersistenceId)

View File

@ -21,10 +21,9 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
*/ */
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLink;
import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -38,7 +37,7 @@ public class FindCandidateByLinkSvc extends BaseCandidateFinder {
private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); private static final Logger ourLog = Logs.getMdmTroubleshootingLog();
/** /**
* Attempt to find a currently matching Golden Resource, based on the presence of an {@link MdmLink} entity. * Attempt to find a currently matching Golden Resource, based on the presence of an {@link IMdmLink} entity.
* *
* @param theTarget the {@link IAnyResource} that we want to find candidate Golden Resources for. * @param theTarget the {@link IAnyResource} that we want to find candidate Golden Resources for.
* @return an Optional list of {@link MatchedGoldenResourceCandidate} indicating matches. * @return an Optional list of {@link MatchedGoldenResourceCandidate} indicating matches.
@ -47,11 +46,11 @@ public class FindCandidateByLinkSvc extends BaseCandidateFinder {
protected List<MatchedGoldenResourceCandidate> findMatchGoldenResourceCandidates(IAnyResource theTarget) { protected List<MatchedGoldenResourceCandidate> findMatchGoldenResourceCandidates(IAnyResource theTarget) {
List<MatchedGoldenResourceCandidate> retval = new ArrayList<>(); List<MatchedGoldenResourceCandidate> retval = new ArrayList<>();
ResourcePersistentId targetPid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theTarget); IResourcePersistentId targetPid = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theTarget);
if (targetPid != null) { if (targetPid != null) {
Optional<? extends IMdmLink> oLink = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(targetPid); Optional<? extends IMdmLink> oLink = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(targetPid);
if (oLink.isPresent()) { if (oLink.isPresent()) {
ResourcePersistentId goldenResourcePid = oLink.get().getGoldenResourcePersistenceId(); IResourcePersistentId goldenResourcePid = oLink.get().getGoldenResourcePersistenceId();
ourLog.debug("Resource previously linked. Using existing link."); ourLog.debug("Resource previously linked. Using existing link.");
retval.add(new MatchedGoldenResourceCandidate(goldenResourcePid, oLink.get())); retval.add(new MatchedGoldenResourceCandidate(goldenResourcePid, oLink.get()));
} }

View File

@ -22,25 +22,24 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLink;
import ca.uhn.fhir.mdm.api.MdmMatchOutcome; import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
public class MatchedGoldenResourceCandidate { public class MatchedGoldenResourceCandidate {
private final ResourcePersistentId myCandidateGoldenResourcePid; private final IResourcePersistentId myCandidateGoldenResourcePid;
private final MdmMatchOutcome myMdmMatchOutcome; private final MdmMatchOutcome myMdmMatchOutcome;
public MatchedGoldenResourceCandidate(ResourcePersistentId theCandidate, MdmMatchOutcome theMdmMatchOutcome) { public MatchedGoldenResourceCandidate(IResourcePersistentId theCandidate, MdmMatchOutcome theMdmMatchOutcome) {
myCandidateGoldenResourcePid = theCandidate; myCandidateGoldenResourcePid = theCandidate;
myMdmMatchOutcome = theMdmMatchOutcome; myMdmMatchOutcome = theMdmMatchOutcome;
} }
public MatchedGoldenResourceCandidate(ResourcePersistentId theGoldenResourcePid, IMdmLink theMdmLink) { public MatchedGoldenResourceCandidate(IResourcePersistentId theGoldenResourcePid, IMdmLink theMdmLink) {
myCandidateGoldenResourcePid = theGoldenResourcePid; myCandidateGoldenResourcePid = theGoldenResourcePid;
myMdmMatchOutcome = new MdmMatchOutcome(theMdmLink.getVector(), theMdmLink.getScore()).setMatchResultEnum(theMdmLink.getMatchResult()); myMdmMatchOutcome = new MdmMatchOutcome(theMdmLink.getVector(), theMdmLink.getScore()).setMatchResultEnum(theMdmLink.getMatchResult());
} }
public ResourcePersistentId getCandidateGoldenResourcePid() { public IResourcePersistentId getCandidateGoldenResourcePid() {
return myCandidateGoldenResourcePid; return myCandidateGoldenResourcePid;
} }

View File

@ -20,15 +20,15 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
* #L% * #L%
*/ */
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.api.IMdmSettings;
import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.rules.json.MdmFilterSearchParamJson; import ca.uhn.fhir.mdm.rules.json.MdmFilterSearchParamJson;
import ca.uhn.fhir.mdm.rules.json.MdmResourceSearchParamJson; import ca.uhn.fhir.mdm.rules.json.MdmResourceSearchParamJson;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -75,7 +75,7 @@ public class MdmCandidateSearchSvc {
*/ */
@Transactional @Transactional
public Collection<IAnyResource> findCandidates(String theResourceType, IAnyResource theResource, RequestPartitionId theRequestPartitionId) { public Collection<IAnyResource> findCandidates(String theResourceType, IAnyResource theResource, RequestPartitionId theRequestPartitionId) {
Map<ResourcePersistentId, IAnyResource> matchedPidsToResources = new HashMap<>(); Map<IResourcePersistentId, IAnyResource> matchedPidsToResources = new HashMap<>();
List<MdmFilterSearchParamJson> filterSearchParams = myMdmSettings.getMdmRules().getCandidateFilterSearchParams(); List<MdmFilterSearchParamJson> filterSearchParams = myMdmSettings.getMdmRules().getCandidateFilterSearchParams();
List<String> filterCriteria = buildFilterQuery(filterSearchParams, theResourceType); List<String> filterCriteria = buildFilterQuery(filterSearchParams, theResourceType);
List<MdmResourceSearchParamJson> candidateSearchParams = myMdmSettings.getMdmRules().getCandidateSearchParams(); List<MdmResourceSearchParamJson> candidateSearchParams = myMdmSettings.getMdmRules().getCandidateSearchParams();
@ -120,7 +120,7 @@ public class MdmCandidateSearchSvc {
* 4. Store all results in `theMatchedPidsToResources` * 4. Store all results in `theMatchedPidsToResources`
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private void searchForIdsAndAddToMap(String theResourceType, IAnyResource theResource, Map<ResourcePersistentId, IAnyResource> theMatchedPidsToResources, List<String> theFilterCriteria, MdmResourceSearchParamJson resourceSearchParam, RequestPartitionId theRequestPartitionId) { private void searchForIdsAndAddToMap(String theResourceType, IAnyResource theResource, Map<IResourcePersistentId, IAnyResource> theMatchedPidsToResources, List<String> theFilterCriteria, MdmResourceSearchParamJson resourceSearchParam, RequestPartitionId theRequestPartitionId) {
//1. //1.
Optional<String> oResourceCriteria = myMdmCandidateSearchCriteriaBuilderSvc.buildResourceQueryString(theResourceType, theResource, theFilterCriteria, resourceSearchParam); Optional<String> oResourceCriteria = myMdmCandidateSearchCriteriaBuilderSvc.buildResourceQueryString(theResourceType, theResource, theFilterCriteria, resourceSearchParam);
if (!oResourceCriteria.isPresent()) { if (!oResourceCriteria.isPresent()) {

View File

@ -22,7 +22,7 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc;
import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -77,7 +77,7 @@ public class MdmGoldenResourceFindingSvc {
} }
public IAnyResource getGoldenResourceFromMatchedGoldenResourceCandidate(MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, String theResourceType) { public IAnyResource getGoldenResourceFromMatchedGoldenResourceCandidate(MatchedGoldenResourceCandidate theMatchedGoldenResourceCandidate, String theResourceType) {
ResourcePersistentId goldenResourcePid = theMatchedGoldenResourceCandidate.getCandidateGoldenResourcePid(); IResourcePersistentId goldenResourcePid = theMatchedGoldenResourceCandidate.getCandidateGoldenResourcePid();
return myMdmResourceDaoSvc.readGoldenResourceByPid(goldenResourcePid, theResourceType); return myMdmResourceDaoSvc.readGoldenResourceByPid(goldenResourcePid, theResourceType);
} }
} }

View File

@ -19,6 +19,7 @@ import ca.uhn.fhir.jpa.mdm.matcher.IsPossibleMatchWith;
import ca.uhn.fhir.jpa.mdm.matcher.IsSameGoldenResourceAs; import ca.uhn.fhir.jpa.mdm.matcher.IsSameGoldenResourceAs;
import ca.uhn.fhir.jpa.mdm.svc.MdmMatchLinkSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmMatchLinkSvc;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc; import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -38,7 +39,6 @@ import ca.uhn.fhir.mdm.util.MdmResourceUtil;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -113,11 +113,11 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test {
@Autowired @Autowired
protected MdmResourceMatcherSvc myMdmResourceMatcherSvc; protected MdmResourceMatcherSvc myMdmResourceMatcherSvc;
@Autowired @Autowired
protected IMdmLinkDao myMdmLinkDao; protected IMdmLinkDao<JpaPid, MdmLink> myMdmLinkDao;
@Autowired @Autowired
protected MdmLinkDaoSvc myMdmLinkDaoSvc; protected MdmLinkDaoSvc<JpaPid, MdmLink> myMdmLinkDaoSvc;
@Autowired @Autowired
protected IIdHelperService myIdHelperService; protected IIdHelperService<JpaPid> myIdHelperService;
@Autowired @Autowired
protected IMdmSettings myMdmSettings; protected IMdmSettings myMdmSettings;
@Autowired @Autowired
@ -361,10 +361,10 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test {
String resourceType = theBaseResource.getIdElement().getResourceType(); String resourceType = theBaseResource.getIdElement().getResourceType();
IFhirResourceDao relevantDao = myDaoRegistry.getResourceDao(resourceType); IFhirResourceDao relevantDao = myDaoRegistry.getResourceDao(resourceType);
Optional<? extends IMdmLink> matchedLinkForTargetPid = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(runInTransaction(() -> myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theBaseResource))); Optional<MdmLink> matchedLinkForTargetPid = myMdmLinkDaoSvc.getMatchedLinkForSourcePid(runInTransaction(() -> myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), theBaseResource)));
if (matchedLinkForTargetPid.isPresent()) { if (matchedLinkForTargetPid.isPresent()) {
Long goldenResourcePid = matchedLinkForTargetPid.get().getGoldenResourcePersistenceId().getIdAsLong(); JpaPid jpaPid = matchedLinkForTargetPid.get().getGoldenResourcePersistenceId();
return (T) relevantDao.readByPid(new ResourcePersistentId(goldenResourcePid)); return (T) relevantDao.readByPid(jpaPid);
} else { } else {
return null; return null;
} }
@ -372,7 +372,7 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test {
protected <T extends IBaseResource> T getTargetResourceFromMdmLink(IMdmLink theMdmLink, String theResourceType) { protected <T extends IBaseResource> T getTargetResourceFromMdmLink(IMdmLink theMdmLink, String theResourceType) {
IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType); IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType);
return (T) resourceDao.readByPid(new ResourcePersistentId(theMdmLink.getGoldenResourcePersistenceId().getIdAsLong())); return (T) resourceDao.readByPid(theMdmLink.getGoldenResourcePersistenceId());
} }
protected Patient addExternalEID(Patient thePatient, String theEID) { protected Patient addExternalEID(Patient thePatient, String theEID) {

View File

@ -1,10 +1,8 @@
package ca.uhn.fhir.jpa.mdm.config; package ca.uhn.fhir.jpa.mdm.config;
import ca.uhn.fhir.jpa.mdm.dao.JpaMdmLinkImplFactory;
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig; import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig;
import ca.uhn.fhir.jpa.subscription.submit.config.SubscriptionSubmitterConfig; import ca.uhn.fhir.jpa.subscription.submit.config.SubscriptionSubmitterConfig;
import ca.uhn.fhir.mdm.dao.IMdmLinkImplFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;

View File

@ -1,16 +1,15 @@
package ca.uhn.fhir.jpa.mdm.dao; package ca.uhn.fhir.jpa.mdm.dao;
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.dao.data.IMdmLinkJpaRepository;
import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.jpa.util.TestUtil;
import ca.uhn.fhir.mdm.api.IMdmLink; import ca.uhn.fhir.mdm.api.IMdmLink;
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.model.MdmPidTuple; import ca.uhn.fhir.mdm.model.MdmPidTuple;
import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; import ca.uhn.fhir.mdm.rules.json.MdmRulesJson;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -45,11 +44,11 @@ public class MdmLinkDaoSvcTest extends BaseMdmR4Test {
@Test @Test
public void testUpdate() { public void testUpdate() {
IMdmLink createdLink = myMdmLinkDaoSvc.save(createResourcesAndBuildTestMDMLink()); MdmLink createdLink = myMdmLinkDaoSvc.save(createResourcesAndBuildTestMDMLink());
assertThat(createdLink.getLinkSource(), is(MdmLinkSourceEnum.MANUAL)); assertThat(createdLink.getLinkSource(), is(MdmLinkSourceEnum.MANUAL));
TestUtil.sleepOneClick(); TestUtil.sleepOneClick();
createdLink.setLinkSource(MdmLinkSourceEnum.AUTO); createdLink.setLinkSource(MdmLinkSourceEnum.AUTO);
IMdmLink updatedLink = myMdmLinkDaoSvc.save(createdLink); MdmLink updatedLink = myMdmLinkDaoSvc.save(createdLink);
assertNotEquals(updatedLink.getCreated(), updatedLink.getUpdated()); assertNotEquals(updatedLink.getCreated(), updatedLink.getUpdated());
} }
@ -80,14 +79,14 @@ public class MdmLinkDaoSvcTest extends BaseMdmR4Test {
List<Long> expectedExpandedPids = mdmLinks.stream().map(MdmLink::getSourcePid).collect(Collectors.toList()); List<Long> expectedExpandedPids = mdmLinks.stream().map(MdmLink::getSourcePid).collect(Collectors.toList());
//SUT //SUT
List<MdmPidTuple> lists = runInTransaction(()->myMdmLinkDao.expandPidsBySourcePidAndMatchResult(new ResourcePersistentId(mdmLinks.get(0).getSourcePid()), MdmMatchResultEnum.MATCH)); List<MdmPidTuple<JpaPid>> lists = runInTransaction(() -> myMdmLinkDao.expandPidsBySourcePidAndMatchResult(JpaPid.fromId(mdmLinks.get(0).getSourcePid()), MdmMatchResultEnum.MATCH));
assertThat(lists, hasSize(10)); assertThat(lists, hasSize(10));
lists.stream() lists.stream()
.forEach(tuple -> { .forEach(tuple -> {
assertThat(tuple.getGoldenPid().getIdAsLong(), is(equalTo(golden.getIdElement().getIdPartAsLong()))); assertThat(tuple.getGoldenPid().getId(), is(equalTo(myIdHelperService.getPidOrThrowException(golden).getId())));
assertThat(tuple.getSourcePid().getIdAsLong(), is(in(expectedExpandedPids))); assertThat(tuple.getSourcePid().getId(), is(in(expectedExpandedPids)));
}); });
} }
@ -99,9 +98,9 @@ public class MdmLinkDaoSvcTest extends BaseMdmR4Test {
mdmLink.setMatchResult(theMdmMatchResultEnum); mdmLink.setMatchResult(theMdmMatchResultEnum);
mdmLink.setCreated(new Date()); mdmLink.setCreated(new Date());
mdmLink.setUpdated(new Date()); mdmLink.setUpdated(new Date());
mdmLink.setGoldenResourcePersistenceId(new ResourcePersistentId(thePatientPid)); mdmLink.setGoldenResourcePersistenceId(JpaPid.fromId(thePatientPid));
mdmLink.setSourcePersistenceId(runInTransaction(()->myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), patient))); mdmLink.setSourcePersistenceId(runInTransaction(()->myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), patient)));
MdmLink saved= (MdmLink) myMdmLinkDao.save(mdmLink); MdmLink saved= myMdmLinkDao.save(mdmLink);
return saved; return saved;
} }
} }

View File

@ -8,6 +8,7 @@ import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
import ca.uhn.fhir.jpa.mdm.helper.testmodels.MDMLinkResults; import ca.uhn.fhir.jpa.mdm.helper.testmodels.MDMLinkResults;
import ca.uhn.fhir.jpa.mdm.helper.testmodels.MDMState; import ca.uhn.fhir.jpa.mdm.helper.testmodels.MDMState;
import ca.uhn.fhir.jpa.mdm.helper.testmodels.MdmTestLinkExpression; import ca.uhn.fhir.jpa.mdm.helper.testmodels.MdmTestLinkExpression;
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.api.MdmMatchOutcome; import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
@ -16,7 +17,6 @@ import ca.uhn.fhir.mdm.dao.IMdmLinkDao;
import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.mdm.util.MdmResourceUtil; import ca.uhn.fhir.mdm.util.MdmResourceUtil;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.r4.model.Identifier; import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -49,10 +49,10 @@ public class MdmLinkHelper {
@Autowired @Autowired
private IFhirResourceDao<Patient> myPatientDao; private IFhirResourceDao<Patient> myPatientDao;
@Autowired @Autowired
private MdmLinkDaoSvc myMdmLinkDaoSvc; private MdmLinkDaoSvc<JpaPid, MdmLink> myMdmLinkDaoSvc;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Autowired @Autowired
private IMdmLinkDao myMdmLinkDao; private IMdmLinkDao<JpaPid, MdmLink> myMdmLinkDao;
@Autowired @Autowired
private IdHelperService myIdHelperService; private IdHelperService myIdHelperService;
@ -81,7 +81,7 @@ public class MdmLinkHelper {
* These links will be returned in an MDMLinkResults object, in case * These links will be returned in an MDMLinkResults object, in case
* they are needed. * they are needed.
*/ */
public MDMLinkResults setup(MDMState<Patient> theState) { public MDMLinkResults setup(MDMState<Patient, JpaPid> theState) {
MDMLinkResults results = new MDMLinkResults(); MDMLinkResults results = new MDMLinkResults();
List<MdmTestLinkExpression> inputExpressions = theState.getParsedInputState(); List<MdmTestLinkExpression> inputExpressions = theState.getParsedInputState();
@ -122,7 +122,7 @@ public class MdmLinkHelper {
return results; return results;
} }
private void createIfNeeded(MDMState<Patient> theState, String thePatientId) { private void createIfNeeded(MDMState<Patient, JpaPid> theState, String thePatientId) {
Patient patient = theState.getParameter(thePatientId); Patient patient = theState.getParameter(thePatientId);
if (patient == null) { if (patient == null) {
// if it doesn't exist, create it // if it doesn't exist, create it
@ -131,7 +131,7 @@ public class MdmLinkHelper {
} }
} }
private Patient createPatientAndTags(String theId, MDMState<Patient> theState) { private Patient createPatientAndTags(String theId, MDMState<Patient, JpaPid> theState) {
Patient patient = new Patient(); Patient patient = new Patient();
patient.setActive(true); // all mdm patients must be active patient.setActive(true); // all mdm patients must be active
@ -150,11 +150,11 @@ public class MdmLinkHelper {
DaoMethodOutcome outcome = myPatientDao.update(patient, DaoMethodOutcome outcome = myPatientDao.update(patient,
SystemRequestDetails.forAllPartitions()); SystemRequestDetails.forAllPartitions());
Patient outputPatient = (Patient) outcome.getResource(); Patient outputPatient = (Patient) outcome.getResource();
theState.addPID(theId, outcome.getPersistentId()); theState.addPID(theId, (JpaPid) outcome.getPersistentId());
return outputPatient; return outputPatient;
} }
public void validateResults(MDMState<Patient> theState) { public void validateResults(MDMState<Patient, JpaPid> theState) {
List<MdmTestLinkExpression> expectedOutputStates = theState.getParsedOutputState(); List<MdmTestLinkExpression> expectedOutputStates = theState.getParsedOutputState();
StringBuilder outputStateSB = new StringBuilder(); StringBuilder outputStateSB = new StringBuilder();
@ -222,9 +222,9 @@ public class MdmLinkHelper {
MdmLink theLink, MdmLink theLink,
Patient theResource, Patient theResource,
Side theSide, Side theSide,
MDMState<Patient> theState MDMState<Patient, JpaPid> theState
) { ) {
ResourcePersistentId resourcePid = theState.getPID(theResource.getIdElement().getIdPart()); JpaPid resourcePid = theState.getPID(theResource.getIdElement().getIdPart());
long linkPid; long linkPid;
if (theSide == Side.LHS) { if (theSide == Side.LHS) {
@ -235,10 +235,10 @@ public class MdmLinkHelper {
linkPid = theLink.getSourcePid(); linkPid = theLink.getSourcePid();
} }
return linkPid == resourcePid.getIdAsLong(); return linkPid == resourcePid.getId();
} }
private String createStateFromLink(MdmLink theLink, MDMState<Patient> theState) { private String createStateFromLink(MdmLink theLink, MDMState<Patient, JpaPid> theState) {
String LHS = ""; String LHS = "";
String RHS = ""; String RHS = "";
for (Map.Entry<String, Patient> set : theState.getParameterToValue().entrySet()) { for (Map.Entry<String, Patient> set : theState.getParameterToValue().entrySet()) {

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