issue-2901 review fixes
This commit is contained in:
parent
78c71ce761
commit
64270a51e0
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.api.dao;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
|
import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
|
||||||
import ca.uhn.fhir.jpa.api.model.DeleteMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DeleteMethodOutcome;
|
||||||
|
@ -168,7 +169,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
|
||||||
* @param theIds - list of IIdType ids (for the same resource)
|
* @param theIds - list of IIdType ids (for the same resource)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Map<IIdType, ResourcePersistentId> getIdsOfExistingResources(Collection<IIdType> theIds);
|
Map<IIdType, ResourcePersistentId> getIdsOfExistingResources(RequestPartitionId partitionId, Collection<IIdType> theIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a resource by its internal PID
|
* Read a resource by its internal PID
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
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.rest.api.server.storage.ResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||||
|
@ -18,7 +19,7 @@ public class AutoVersioningServiceImpl implements IAutoVersioningService {
|
||||||
private DaoRegistry myDaoRegistry;
|
private DaoRegistry myDaoRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<IIdType, ResourcePersistentId> getExistingAutoversionsForIds(Collection<IIdType> theIds) {
|
public Map<IIdType, ResourcePersistentId> getExistingAutoversionsForIds(RequestPartitionId theRequestPartitionId, Collection<IIdType> theIds) {
|
||||||
HashMap<IIdType, ResourcePersistentId> idToPID = new HashMap<>();
|
HashMap<IIdType, ResourcePersistentId> idToPID = new HashMap<>();
|
||||||
HashMap<String, List<IIdType>> resourceTypeToIds = new HashMap<>();
|
HashMap<String, List<IIdType>> resourceTypeToIds = new HashMap<>();
|
||||||
|
|
||||||
|
@ -33,7 +34,8 @@ public class AutoVersioningServiceImpl implements IAutoVersioningService {
|
||||||
for (String resourceType : resourceTypeToIds.keySet()) {
|
for (String resourceType : resourceTypeToIds.keySet()) {
|
||||||
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceType);
|
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceType);
|
||||||
|
|
||||||
Map<IIdType, ResourcePersistentId> idAndPID = dao.getIdsOfExistingResources(resourceTypeToIds.get(resourceType));
|
Map<IIdType, ResourcePersistentId> idAndPID = dao.getIdsOfExistingResources(theRequestPartitionId,
|
||||||
|
resourceTypeToIds.get(resourceType));
|
||||||
idToPID.putAll(idAndPID);
|
idToPID.putAll(idAndPID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ import ca.uhn.fhir.jpa.api.model.LazyDaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
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.DeleteConflictService;
|
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
|
||||||
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
|
||||||
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;
|
||||||
|
@ -52,7 +51,6 @@ import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.jpa.patch.FhirPatch;
|
import ca.uhn.fhir.jpa.patch.FhirPatch;
|
||||||
import ca.uhn.fhir.jpa.patch.JsonPatchUtils;
|
import ca.uhn.fhir.jpa.patch.JsonPatchUtils;
|
||||||
import ca.uhn.fhir.jpa.patch.XmlPatchUtils;
|
import ca.uhn.fhir.jpa.patch.XmlPatchUtils;
|
||||||
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
||||||
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
|
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
|
||||||
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
||||||
|
@ -141,6 +139,7 @@ import java.util.Date;
|
||||||
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.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -1160,7 +1159,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<IIdType, ResourcePersistentId> getIdsOfExistingResources(Collection<IIdType> theIds) {
|
public Map<IIdType, ResourcePersistentId> getIdsOfExistingResources(RequestPartitionId thePartitionId,
|
||||||
|
Collection<IIdType> theIds) {
|
||||||
// these are the found Ids that were in the db
|
// these are the found Ids that were in the db
|
||||||
HashMap<IIdType, ResourcePersistentId> collected = new HashMap<>();
|
HashMap<IIdType, ResourcePersistentId> collected = new HashMap<>();
|
||||||
|
|
||||||
|
@ -1168,26 +1168,40 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
return collected;
|
return collected;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> idPortions = theIds
|
List<ResourcePersistentId> resourcePersistentIds = myIdHelperService.resolveResourcePersistentIdsWithCache(thePartitionId,
|
||||||
.stream()
|
theIds.stream().collect(Collectors.toList()));
|
||||||
.map(IIdType::getIdPart)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
Collection<Object[]> matches = myForcedIdDao.findResourcesByForcedId(getResourceName(),
|
// we'll use this map to fetch pids that require versions
|
||||||
idPortions);
|
HashMap<Long, ResourcePersistentId> pidsToVersionToResourcePid = new HashMap<>();
|
||||||
|
|
||||||
for (Object[] match : matches) {
|
// fill in our map
|
||||||
String resourceType = (String) match[0];
|
for (ResourcePersistentId pid : resourcePersistentIds) {
|
||||||
String forcedId = (String) match[1];
|
if (pid.getVersion() == null) {
|
||||||
Long pid = (Long) match[2];
|
pidsToVersionToResourcePid.put(pid.getIdAsLong(), pid);
|
||||||
Long versionId = (Long) match[3];
|
}
|
||||||
IIdType id = new IdDt(resourceType, forcedId);
|
Optional<IIdType> idOp = theIds.stream()
|
||||||
// we won't put the version on the IIdType
|
.filter(i -> i.getIdPart().equals(pid.getAssociatedResourceId().getIdPart()))
|
||||||
// so callers can use this as a lookup to match to
|
.findFirst();
|
||||||
ResourcePersistentId persistentId = new ResourcePersistentId(pid);
|
// this should always be present
|
||||||
persistentId.setVersion(versionId);
|
// since it was passed in.
|
||||||
|
// but land of optionals...
|
||||||
|
idOp.ifPresent(id -> {
|
||||||
|
collected.put(id, pid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
collected.put(id, persistentId);
|
// set any versions we don't already have
|
||||||
|
if (!pidsToVersionToResourcePid.isEmpty()) {
|
||||||
|
Collection<Object[]> resourceEntries = myResourceTableDao
|
||||||
|
.getResourceVersionsForPid(new ArrayList<>(pidsToVersionToResourcePid.keySet()));
|
||||||
|
|
||||||
|
for (Object[] record : resourceEntries) {
|
||||||
|
// order matters!
|
||||||
|
Long retPid = (Long)record[0];
|
||||||
|
String resType = (String)record[1];
|
||||||
|
Long version = (Long)record[2];
|
||||||
|
pidsToVersionToResourcePid.get(retPid).setVersion(version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return collected;
|
return collected;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
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;
|
||||||
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
|
@ -209,7 +210,7 @@ public abstract class BaseStorageDao {
|
||||||
IIdType referenceElement = nextReference.getReferenceElement();
|
IIdType referenceElement = nextReference.getReferenceElement();
|
||||||
if (!referenceElement.hasBaseUrl()) {
|
if (!referenceElement.hasBaseUrl()) {
|
||||||
|
|
||||||
Map<IIdType, ResourcePersistentId> idToPID = myAutoVersioningService.getExistingAutoversionsForIds(
|
Map<IIdType, ResourcePersistentId> idToPID = myAutoVersioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||||
Collections.singletonList(referenceElement)
|
Collections.singletonList(referenceElement)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -220,7 +221,7 @@ public abstract class BaseStorageDao {
|
||||||
Long version;
|
Long version;
|
||||||
if (idToPID.containsKey(referenceElement)) {
|
if (idToPID.containsKey(referenceElement)) {
|
||||||
// the resource exists... latest id
|
// the resource exists... latest id
|
||||||
// will bbe the value in the ResourcePersistentId
|
// will be the value in the ResourcePersistentId
|
||||||
version = idToPID.get(referenceElement).getVersion();
|
version = idToPID.get(referenceElement).getVersion();
|
||||||
}
|
}
|
||||||
else if (myDaoConfig.isAutoCreatePlaceholderReferenceTargets()) {
|
else if (myDaoConfig.isAutoCreatePlaceholderReferenceTargets()) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
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;
|
||||||
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.interceptor.model.TransactionWriteOperationsDetails;
|
import ca.uhn.fhir.interceptor.model.TransactionWriteOperationsDetails;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
|
@ -1268,7 +1269,9 @@ public abstract class BaseTransactionProcessor {
|
||||||
} else {
|
} else {
|
||||||
// get a map of
|
// get a map of
|
||||||
// existing ids -> PID (for resources that exist in the DB)
|
// existing ids -> PID (for resources that exist in the DB)
|
||||||
Map<IIdType, ResourcePersistentId> idToPID = myAutoVersioningService.getExistingAutoversionsForIds(theReferencesToAutoVersion.stream()
|
// should this be allPartitions?
|
||||||
|
Map<IIdType, ResourcePersistentId> idToPID = myAutoVersioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||||
|
theReferencesToAutoVersion.stream()
|
||||||
.map(ref -> ref.getReferenceElement()).collect(Collectors.toList()));
|
.map(ref -> ref.getReferenceElement()).collect(Collectors.toList()));
|
||||||
|
|
||||||
for (IBaseReference baseRef : theReferencesToAutoVersion) {
|
for (IBaseReference baseRef : theReferencesToAutoVersion) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
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;
|
||||||
|
|
||||||
|
@ -17,7 +18,8 @@ public interface IAutoVersioningService {
|
||||||
* If the returned map does not return an IIdType -> ResourcePersistentId
|
* If the returned map does not return an IIdType -> ResourcePersistentId
|
||||||
* then it means that it is a non-existing resource in the DB
|
* then it means that it is a non-existing resource in the DB
|
||||||
* @param theIds
|
* @param theIds
|
||||||
|
* @param thePartitionId - the partition id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Map<IIdType, ResourcePersistentId> getExistingAutoversionsForIds(Collection<IIdType> theIds);
|
Map<IIdType, ResourcePersistentId> getExistingAutoversionsForIds(RequestPartitionId thePartitionId, Collection<IIdType> theIds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,23 +111,6 @@ public interface IForcedIdDao extends JpaRepository<ForcedId, Long> {
|
||||||
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id )")
|
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id )")
|
||||||
Collection<Object[]> findAndResolveByForcedIdWithNoType(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedIds);
|
Collection<Object[]> findAndResolveByForcedIdWithNoType(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedIds);
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns a collection where eah row is an element in the collection.
|
|
||||||
* Each element in the collection is an object array where order matters.
|
|
||||||
* The returned order of each object array element is:
|
|
||||||
* ResourceType (Patient, etc - String), ForcedId (String), ResourcePID (Long), Version (Long)
|
|
||||||
* @param theResourceType
|
|
||||||
* @param theForcedIds
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Query("" +
|
|
||||||
"SELECT " +
|
|
||||||
" f.myResourceType, f.myForcedId, f.myResourcePid, t.myVersion " +
|
|
||||||
"FROM ForcedId f " +
|
|
||||||
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
|
||||||
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id )")
|
|
||||||
Collection<Object[]> findResourcesByForcedId(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedIds);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
||||||
|
|
|
@ -100,6 +100,16 @@ public interface IResourceTableDao extends JpaRepository<ResourceTable, Long> {
|
||||||
@Query("SELECT t.myVersion FROM ResourceTable t WHERE t.myId = :pid")
|
@Query("SELECT t.myVersion FROM ResourceTable t WHERE t.myId = :pid")
|
||||||
Long findCurrentVersionByPid(@Param("pid") Long thePid);
|
Long findCurrentVersionByPid(@Param("pid") Long thePid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This query will return rows with the following values:
|
||||||
|
* Id (resource pid - long), ResourceType (Patient, etc), version (long)
|
||||||
|
* Order matters!
|
||||||
|
* @param pid - list of pids to get versions for
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Query("SELECT t.myId, t.myResourceType, t.myVersion FROM ResourceTable t WHERE t.myId IN ( :pid )")
|
||||||
|
Collection<Object[]> getResourceVersionsForPid(@Param("pid") List<Long> pid);
|
||||||
|
|
||||||
@Query("SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId IS NULL AND t.myId = :pid")
|
@Query("SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId IS NULL AND t.myId = :pid")
|
||||||
Optional<ResourceTable> readByPartitionIdNull(@Param("pid") Long theResourceId);
|
Optional<ResourceTable> readByPartitionIdNull(@Param("pid") Long theResourceId);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
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.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
@ -36,12 +37,14 @@ public class AutoVersioningServiceImplTests {
|
||||||
map.put(type, pid);
|
map.put(type, pid);
|
||||||
|
|
||||||
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
||||||
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.anyList()))
|
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.any(RequestPartitionId.class),
|
||||||
|
Mockito.anyList()))
|
||||||
.thenReturn(map);
|
.thenReturn(map);
|
||||||
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
||||||
.thenReturn(daoMock);
|
.thenReturn(daoMock);
|
||||||
|
|
||||||
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(Collections.singletonList(type));
|
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||||
|
Collections.singletonList(type));
|
||||||
|
|
||||||
Assertions.assertTrue(retMap.containsKey(type));
|
Assertions.assertTrue(retMap.containsKey(type));
|
||||||
Assertions.assertEquals(pid.getVersion(), map.get(type).getVersion());
|
Assertions.assertEquals(pid.getVersion(), map.get(type).getVersion());
|
||||||
|
@ -52,12 +55,14 @@ public class AutoVersioningServiceImplTests {
|
||||||
IIdType type = new IdDt("Patient/RED");
|
IIdType type = new IdDt("Patient/RED");
|
||||||
|
|
||||||
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
||||||
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.anyList()))
|
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.any(RequestPartitionId.class),
|
||||||
|
Mockito.anyList()))
|
||||||
.thenReturn(new HashMap<>());
|
.thenReturn(new HashMap<>());
|
||||||
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
||||||
.thenReturn(daoMock);
|
.thenReturn(daoMock);
|
||||||
|
|
||||||
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(Collections.singletonList(type));
|
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||||
|
Collections.singletonList(type));
|
||||||
|
|
||||||
Assertions.assertTrue(retMap.isEmpty());
|
Assertions.assertTrue(retMap.isEmpty());
|
||||||
}
|
}
|
||||||
|
@ -73,13 +78,14 @@ public class AutoVersioningServiceImplTests {
|
||||||
|
|
||||||
// when
|
// when
|
||||||
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
||||||
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.anyList()))
|
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.any(RequestPartitionId.class), Mockito.anyList()))
|
||||||
.thenReturn(map);
|
.thenReturn(map);
|
||||||
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
||||||
.thenReturn(daoMock);
|
.thenReturn(daoMock);
|
||||||
|
|
||||||
// test
|
// test
|
||||||
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(
|
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(
|
||||||
|
RequestPartitionId.allPartitions(),
|
||||||
Arrays.asList(type, type2)
|
Arrays.asList(type, type2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,11 @@ package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
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.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||||
import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
||||||
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;
|
||||||
|
@ -13,12 +16,14 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.Request;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoTestRule;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -54,27 +59,40 @@ class BaseHapiFhirResourceDaoTest {
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private BaseHapiFhirResourceDao myBaseHapiFhirResourceDao = new SimpleTestDao();
|
private BaseHapiFhirResourceDao myBaseHapiFhirResourceDao = new SimpleTestDao();
|
||||||
|
|
||||||
|
// @Mock
|
||||||
|
// private IForcedIdDao myIForcedIdDao;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private IForcedIdDao myIForcedIdDao;
|
private IdHelperService myIdHelperService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IResourceTableDao myResourceTableDao;
|
||||||
|
|
||||||
//TODO - all other dependency mocks
|
//TODO - all other dependency mocks
|
||||||
|
|
||||||
|
|
||||||
|
private ResourcePersistentId getResourcePersistentIdFromResource(IIdType theId, long thePid) {
|
||||||
|
ResourcePersistentId id = new ResourcePersistentId(thePid);
|
||||||
|
String idPortion = theId.getIdPart();
|
||||||
|
IIdType newId = new IdDt(theId.getResourceType(), idPortion);
|
||||||
|
id.setAssociatedResourceId(newId);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a match entry to be returned by myIForcedIdDao.
|
* Gets a ResourceTable record for getResourceVersionsForPid
|
||||||
* This ordering matters (see IForcedIdDao)
|
* Order matters!
|
||||||
* @param theId
|
* @param resourceType
|
||||||
* @param thePID
|
* @param pid
|
||||||
* @param theResourceVersion
|
* @param version
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private Object[] createMatchEntryForGetIdsOfExistingResources(IIdType theId, long thePID, long theResourceVersion) {
|
private Object[] getResourceTableRecordForResourceTypeAndPid(String resourceType, long pid, long version) {
|
||||||
Object[] arr = new Object[] {
|
return new Object[] {
|
||||||
theId.getResourceType(),
|
pid, // long
|
||||||
theId.getIdPart(),
|
resourceType, // string
|
||||||
thePID,
|
version // long
|
||||||
theResourceVersion
|
|
||||||
};
|
};
|
||||||
return arr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -83,31 +101,38 @@ class BaseHapiFhirResourceDaoTest {
|
||||||
IIdType patientIdAndType = new IdDt("Patient/RED");
|
IIdType patientIdAndType = new IdDt("Patient/RED");
|
||||||
long patientPID = 1L;
|
long patientPID = 1L;
|
||||||
long patientResourceVersion = 2L;
|
long patientResourceVersion = 2L;
|
||||||
|
ResourcePersistentId pat1ResourcePID = getResourcePersistentIdFromResource(patientIdAndType, patientPID);
|
||||||
IIdType patient2IdAndType = new IdDt("Patient/BLUE");
|
IIdType patient2IdAndType = new IdDt("Patient/BLUE");
|
||||||
long patient2PID = 3L;
|
long patient2PID = 3L;
|
||||||
long patient2ResourceVersion = 4L;
|
long patient2ResourceVersion = 4L;
|
||||||
|
ResourcePersistentId pat2ResourcePID = getResourcePersistentIdFromResource(patient2IdAndType, patient2PID);
|
||||||
List<IIdType> inputList = new ArrayList<>();
|
List<IIdType> inputList = new ArrayList<>();
|
||||||
inputList.add(patientIdAndType);
|
inputList.add(patientIdAndType);
|
||||||
inputList.add(patient2IdAndType);
|
inputList.add(patient2IdAndType);
|
||||||
|
|
||||||
Collection<Object[]> matches = Arrays.asList(
|
Collection<Object[]> matches = Arrays.asList(
|
||||||
createMatchEntryForGetIdsOfExistingResources(patientIdAndType, patientPID, patientResourceVersion),
|
getResourceTableRecordForResourceTypeAndPid(patientIdAndType.getResourceType(), patientPID, patientResourceVersion),
|
||||||
createMatchEntryForGetIdsOfExistingResources(patient2IdAndType, patient2PID, patient2ResourceVersion)
|
getResourceTableRecordForResourceTypeAndPid(patient2IdAndType.getResourceType(), patient2PID, patient2ResourceVersion)
|
||||||
);
|
);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Mockito.when(myIForcedIdDao.findResourcesByForcedId(Mockito.anyString(),
|
Mockito.when(myIdHelperService.resolveResourcePersistentIdsWithCache(Mockito.any(RequestPartitionId.class),
|
||||||
Mockito.anyList())).thenReturn(matches);
|
Mockito.anyList()))
|
||||||
|
.thenReturn(Arrays.asList(pat1ResourcePID, pat2ResourcePID));
|
||||||
|
Mockito.when(myResourceTableDao.getResourceVersionsForPid(Mockito.anyList()))
|
||||||
|
.thenReturn(matches);
|
||||||
|
|
||||||
Map<IIdType, ResourcePersistentId> idToPIDOfExistingResources = myBaseHapiFhirResourceDao.getIdsOfExistingResources(inputList);
|
Map<IIdType, ResourcePersistentId> idToPIDOfExistingResources = myBaseHapiFhirResourceDao.getIdsOfExistingResources(RequestPartitionId.allPartitions(),
|
||||||
|
inputList);
|
||||||
|
|
||||||
Assertions.assertEquals(inputList.size(), idToPIDOfExistingResources.size());
|
Assertions.assertEquals(inputList.size(), idToPIDOfExistingResources.size());
|
||||||
Assertions.assertTrue(idToPIDOfExistingResources.containsKey(patientIdAndType));
|
Assertions.assertTrue(idToPIDOfExistingResources.containsKey(patientIdAndType));
|
||||||
Assertions.assertTrue(idToPIDOfExistingResources.containsKey(patient2IdAndType));
|
Assertions.assertTrue(idToPIDOfExistingResources.containsKey(patient2IdAndType));
|
||||||
Assertions.assertEquals(idToPIDOfExistingResources.get(patientIdAndType).getIdAsLong(), patientPID);
|
|
||||||
Assertions.assertEquals(idToPIDOfExistingResources.get(patient2IdAndType).getIdAsLong(), patient2PID);
|
Assertions.assertEquals(patientPID, idToPIDOfExistingResources.get(patientIdAndType).getIdAsLong());
|
||||||
Assertions.assertEquals(idToPIDOfExistingResources.get(patientIdAndType).getVersion(), patientResourceVersion);
|
Assertions.assertEquals(patient2PID, idToPIDOfExistingResources.get(patient2IdAndType).getIdAsLong(), patient2PID);
|
||||||
Assertions.assertEquals(idToPIDOfExistingResources.get(patient2IdAndType).getVersion(), patient2ResourceVersion);
|
Assertions.assertEquals(patientResourceVersion, idToPIDOfExistingResources.get(patientIdAndType).getVersion());
|
||||||
|
Assertions.assertEquals(patient2ResourceVersion, idToPIDOfExistingResources.get(patient2IdAndType).getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -116,10 +141,12 @@ class BaseHapiFhirResourceDaoTest {
|
||||||
IIdType patient = new IdDt("Patient/RED");
|
IIdType patient = new IdDt("Patient/RED");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Mockito.when(myIForcedIdDao.findResourcesByForcedId(Mockito.anyString(), Mockito.anyList()))
|
Mockito.when(myIdHelperService.resolveResourcePersistentIdsWithCache(Mockito.any(RequestPartitionId.class),
|
||||||
|
Mockito.anyList()))
|
||||||
.thenReturn(new ArrayList<>());
|
.thenReturn(new ArrayList<>());
|
||||||
|
|
||||||
Map<IIdType, ResourcePersistentId> map = myBaseHapiFhirResourceDao.getIdsOfExistingResources(Collections.singletonList(patient));
|
Map<IIdType, ResourcePersistentId> map = myBaseHapiFhirResourceDao.getIdsOfExistingResources(RequestPartitionId.allPartitions(),
|
||||||
|
Collections.singletonList(patient));
|
||||||
|
|
||||||
Assertions.assertTrue(map.isEmpty());
|
Assertions.assertTrue(map.isEmpty());
|
||||||
}
|
}
|
||||||
|
@ -135,15 +162,17 @@ class BaseHapiFhirResourceDaoTest {
|
||||||
inputList.add(patientIdAndType);
|
inputList.add(patientIdAndType);
|
||||||
inputList.add(patient2IdAndType);
|
inputList.add(patient2IdAndType);
|
||||||
|
|
||||||
Collection<Object[]> matches = Collections.singletonList(
|
|
||||||
createMatchEntryForGetIdsOfExistingResources(patientIdAndType, patientPID, patientResourceVersion)
|
|
||||||
);
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Mockito.when(myIForcedIdDao.findResourcesByForcedId(Mockito.anyString(), Mockito.anyList()))
|
Mockito.when(myIdHelperService
|
||||||
.thenReturn(matches);
|
.resolveResourcePersistentIdsWithCache(Mockito.any(RequestPartitionId.class),
|
||||||
|
Mockito.anyList()))
|
||||||
|
.thenReturn(Collections.singletonList(getResourcePersistentIdFromResource(patientIdAndType, patientPID)));
|
||||||
|
Mockito.when(myResourceTableDao.getResourceVersionsForPid(Mockito.anyList()))
|
||||||
|
.thenReturn(Collections
|
||||||
|
.singletonList(getResourceTableRecordForResourceTypeAndPid(patientIdAndType.getResourceType(), patientPID, patientResourceVersion)));
|
||||||
|
|
||||||
Map<IIdType, ResourcePersistentId> map = myBaseHapiFhirResourceDao.getIdsOfExistingResources(inputList);
|
Map<IIdType, ResourcePersistentId> map = myBaseHapiFhirResourceDao.getIdsOfExistingResources(RequestPartitionId.allPartitions(),
|
||||||
|
inputList);
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
Assertions.assertFalse(map.isEmpty());
|
Assertions.assertFalse(map.isEmpty());
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||||
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;
|
||||||
|
@ -538,7 +539,6 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
AuditEvent createdEvent = myAuditEventDao.read(id);
|
AuditEvent createdEvent = myAuditEventDao.read(id);
|
||||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(createdEvent));
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(createdEvent));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -558,7 +558,6 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test {
|
||||||
IIdType id = myObservationDao.create(obsToCreate, mySrd).getId();
|
IIdType id = myObservationDao.create(obsToCreate, mySrd).getId();
|
||||||
|
|
||||||
Observation createdObs = myObservationDao.read(id);
|
Observation createdObs = myObservationDao.read(id);
|
||||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(createdObs));
|
|
||||||
assertEquals("Patient/ABC", createdObs.getSubject().getReference());
|
assertEquals("Patient/ABC", createdObs.getSubject().getReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,8 +574,9 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
mySystemDao.transaction(new SystemRequestDetails(), (Bundle) builder.getBundle());
|
mySystemDao.transaction(new SystemRequestDetails(), (Bundle) builder.getBundle());
|
||||||
|
|
||||||
|
// verify subresource is created
|
||||||
Patient returned = myPatientDao.read(patientRef.getReferenceElement());
|
Patient returned = myPatientDao.read(patientRef.getReferenceElement());
|
||||||
Assertions.assertTrue(returned != null);
|
assertNotNull(returned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -607,10 +607,45 @@ public class FhirResourceDaoCreatePlaceholdersR4Test extends BaseJpaR4Test {
|
||||||
Bundle transaction = mySystemDao.transaction(new SystemRequestDetails(), (Bundle) builder.getBundle());
|
Bundle transaction = mySystemDao.transaction(new SystemRequestDetails(), (Bundle) builder.getBundle());
|
||||||
|
|
||||||
Patient returned = myPatientDao.read(patientRef.getReferenceElement());
|
Patient returned = myPatientDao.read(patientRef.getReferenceElement());
|
||||||
Assertions.assertTrue(returned != null);
|
assertNotNull(returned);
|
||||||
Assertions.assertTrue(returned.getActive());
|
Assertions.assertTrue(returned.getActive());
|
||||||
|
Assertions.assertEquals(2, returned.getIdElement().getVersionIdPartAsLong());
|
||||||
|
|
||||||
Observation retObservation = myObservationDao.read(obs.getIdElement());
|
Observation retObservation = myObservationDao.read(obs.getIdElement());
|
||||||
Assertions.assertTrue(retObservation != null);
|
assertNotNull(retObservation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAutocreatePlaceholderWithExistingTargetWithServerAssignedIdTest() {
|
||||||
|
myDaoConfig.setAutoCreatePlaceholderReferenceTargets(true);
|
||||||
|
myModelConfig.setAutoVersionReferenceAtPaths("Observation.subject");
|
||||||
|
|
||||||
|
// create
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setIdElement(new IdType("Patient"));
|
||||||
|
DaoMethodOutcome ret = myPatientDao.create(patient);
|
||||||
|
|
||||||
|
// update
|
||||||
|
patient.setActive(true);
|
||||||
|
myPatientDao.update(patient);
|
||||||
|
|
||||||
|
// observation (with version 2)
|
||||||
|
Observation obs = new Observation();
|
||||||
|
obs.setId("Observation/DEF");
|
||||||
|
Reference patientRef = new Reference("Patient/" + ret.getId().getIdPart());
|
||||||
|
obs.setSubject(patientRef);
|
||||||
|
BundleBuilder builder = new BundleBuilder(myFhirCtx);
|
||||||
|
builder.addTransactionUpdateEntry(obs);
|
||||||
|
|
||||||
|
Bundle transaction = mySystemDao.transaction(new SystemRequestDetails(), (Bundle) builder.getBundle());
|
||||||
|
|
||||||
|
Patient returned = myPatientDao.read(patientRef.getReferenceElement());
|
||||||
|
assertNotNull(returned);
|
||||||
|
Assertions.assertEquals(2, returned.getIdElement().getVersionIdPartAsLong());
|
||||||
|
|
||||||
|
Observation retObservation = myObservationDao.read(obs.getIdElement());
|
||||||
|
assertNotNull(retObservation);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue