issue-2901 review fixes - moving methods to idhelperservice
This commit is contained in:
parent
64270a51e0
commit
69287b6bc3
|
@ -162,15 +162,6 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
|
|||
*/
|
||||
T read(IIdType theId);
|
||||
|
||||
/**
|
||||
* Helper method to determine if some resources exist in the DB (without throwing).
|
||||
* Returns a set that contains the IIdType for every resource found.
|
||||
* If it's not found, it won't be included in the set.
|
||||
* @param theIds - list of IIdType ids (for the same resource)
|
||||
* @return
|
||||
*/
|
||||
Map<IIdType, ResourcePersistentId> getIdsOfExistingResources(RequestPartitionId partitionId, Collection<IIdType> theIds);
|
||||
|
||||
/**
|
||||
* Read a resource by its internal PID
|
||||
*/
|
||||
|
|
|
@ -27,11 +27,9 @@ import ca.uhn.fhir.jpa.bulk.imprt.api.IBulkDataImportSvc;
|
|||
import ca.uhn.fhir.jpa.bulk.imprt.svc.BulkDataImportSvcImpl;
|
||||
import ca.uhn.fhir.jpa.cache.IResourceVersionSvc;
|
||||
import ca.uhn.fhir.jpa.cache.ResourceVersionSvcDaoImpl;
|
||||
import ca.uhn.fhir.jpa.dao.AutoVersioningServiceImpl;
|
||||
import ca.uhn.fhir.jpa.dao.DaoSearchParamProvider;
|
||||
import ca.uhn.fhir.jpa.dao.HistoryBuilder;
|
||||
import ca.uhn.fhir.jpa.dao.HistoryBuilderFactory;
|
||||
import ca.uhn.fhir.jpa.dao.IAutoVersioningService;
|
||||
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
|
||||
import ca.uhn.fhir.jpa.dao.LegacySearchBuilder;
|
||||
import ca.uhn.fhir.jpa.dao.MatchResourceUrlService;
|
||||
|
@ -232,11 +230,6 @@ public abstract class BaseConfig {
|
|||
public void initSettings() {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IAutoVersioningService autoVersioningService() {
|
||||
return new AutoVersioningServiceImpl();
|
||||
}
|
||||
|
||||
public void setSearchCoordCorePoolSize(Integer searchCoordCorePoolSize) {
|
||||
this.searchCoordCorePoolSize = searchCoordCorePoolSize;
|
||||
}
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
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.IFhirResourceDao;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AutoVersioningServiceImpl implements IAutoVersioningService {
|
||||
|
||||
@Autowired
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
@Override
|
||||
public Map<IIdType, ResourcePersistentId> getExistingAutoversionsForIds(RequestPartitionId theRequestPartitionId, Collection<IIdType> theIds) {
|
||||
HashMap<IIdType, ResourcePersistentId> idToPID = new HashMap<>();
|
||||
HashMap<String, List<IIdType>> resourceTypeToIds = new HashMap<>();
|
||||
|
||||
for (IIdType id : theIds) {
|
||||
String resourceType = id.getResourceType();
|
||||
if (!resourceTypeToIds.containsKey(resourceType)) {
|
||||
resourceTypeToIds.put(resourceType, new ArrayList<>());
|
||||
}
|
||||
resourceTypeToIds.get(resourceType).add(id);
|
||||
}
|
||||
|
||||
for (String resourceType : resourceTypeToIds.keySet()) {
|
||||
IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceType);
|
||||
|
||||
Map<IIdType, ResourcePersistentId> idAndPID = dao.getIdsOfExistingResources(theRequestPartitionId,
|
||||
resourceTypeToIds.get(resourceType));
|
||||
idToPID.putAll(idAndPID);
|
||||
}
|
||||
|
||||
return idToPID;
|
||||
}
|
||||
}
|
|
@ -1158,55 +1158,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
return myTransactionService.execute(theRequest, transactionDetails, tx -> doRead(theId, theRequest, theDeletedOk));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<IIdType, ResourcePersistentId> getIdsOfExistingResources(RequestPartitionId thePartitionId,
|
||||
Collection<IIdType> theIds) {
|
||||
// these are the found Ids that were in the db
|
||||
HashMap<IIdType, ResourcePersistentId> collected = new HashMap<>();
|
||||
|
||||
if (theIds == null || theIds.isEmpty()) {
|
||||
return collected;
|
||||
}
|
||||
|
||||
List<ResourcePersistentId> resourcePersistentIds = myIdHelperService.resolveResourcePersistentIdsWithCache(thePartitionId,
|
||||
theIds.stream().collect(Collectors.toList()));
|
||||
|
||||
// we'll use this map to fetch pids that require versions
|
||||
HashMap<Long, ResourcePersistentId> pidsToVersionToResourcePid = new HashMap<>();
|
||||
|
||||
// fill in our map
|
||||
for (ResourcePersistentId pid : resourcePersistentIds) {
|
||||
if (pid.getVersion() == null) {
|
||||
pidsToVersionToResourcePid.put(pid.getIdAsLong(), pid);
|
||||
}
|
||||
Optional<IIdType> idOp = theIds.stream()
|
||||
.filter(i -> i.getIdPart().equals(pid.getAssociatedResourceId().getIdPart()))
|
||||
.findFirst();
|
||||
// this should always be present
|
||||
// since it was passed in.
|
||||
// but land of optionals...
|
||||
idOp.ifPresent(id -> {
|
||||
collected.put(id, pid);
|
||||
});
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
public T doRead(IIdType theId, RequestDetails theRequest, boolean theDeletedOk) {
|
||||
assert TransactionSynchronizationManager.isActualTransactionActive();
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
|||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||
import ca.uhn.fhir.jpa.api.model.LazyDaoMethodOutcome;
|
||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
|
@ -93,7 +94,7 @@ public abstract class BaseStorageDao {
|
|||
@Autowired
|
||||
protected ModelConfig myModelConfig;
|
||||
@Autowired
|
||||
protected IAutoVersioningService myAutoVersioningService;
|
||||
protected IdHelperService myIdHelperService;
|
||||
@Autowired
|
||||
protected DaoConfig myDaoConfig;
|
||||
|
||||
|
@ -210,7 +211,7 @@ public abstract class BaseStorageDao {
|
|||
IIdType referenceElement = nextReference.getReferenceElement();
|
||||
if (!referenceElement.hasBaseUrl()) {
|
||||
|
||||
Map<IIdType, ResourcePersistentId> idToPID = myAutoVersioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||
Map<IIdType, ResourcePersistentId> idToPID = myIdHelperService.getLatestVersionIdsForResourceIds(RequestPartitionId.allPartitions(),
|
||||
Collections.singletonList(referenceElement)
|
||||
);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
|||
import ca.uhn.fhir.jpa.api.model.DeleteConflict;
|
||||
import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
|
||||
import ca.uhn.fhir.jpa.api.model.DeleteMethodOutcome;
|
||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
|
||||
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
|
||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||
|
@ -159,7 +160,7 @@ public abstract class BaseTransactionProcessor {
|
|||
private TaskExecutor myExecutor ;
|
||||
|
||||
@Autowired
|
||||
private IAutoVersioningService myAutoVersioningService;
|
||||
private IdHelperService myIdHelperService;
|
||||
|
||||
@VisibleForTesting
|
||||
public void setDaoConfig(DaoConfig theDaoConfig) {
|
||||
|
@ -696,7 +697,7 @@ public abstract class BaseTransactionProcessor {
|
|||
*
|
||||
* @param theEntries
|
||||
*/
|
||||
private void consolidateDuplicateConditionalCreates(List<IBase> theEntries) {
|
||||
private void consolidateDuplicateConditionals(List<IBase> theEntries) {
|
||||
final HashMap<String, String> keyToUuid = new HashMap<>();
|
||||
for (int index = 0, originalIndex = 0; index < theEntries.size(); index++, originalIndex++) {
|
||||
IBase nextReqEntry = theEntries.get(index);
|
||||
|
@ -832,7 +833,7 @@ public abstract class BaseTransactionProcessor {
|
|||
/*
|
||||
* Look for duplicate conditional creates and consolidate them
|
||||
*/
|
||||
consolidateDuplicateConditionalCreates(theEntries);
|
||||
consolidateDuplicateConditionals(theEntries);
|
||||
|
||||
/*
|
||||
* Loop through the request and process any entries of type
|
||||
|
@ -1270,7 +1271,7 @@ public abstract class BaseTransactionProcessor {
|
|||
// get a map of
|
||||
// existing ids -> PID (for resources that exist in the DB)
|
||||
// should this be allPartitions?
|
||||
Map<IIdType, ResourcePersistentId> idToPID = myAutoVersioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||
Map<IIdType, ResourcePersistentId> idToPID = myIdHelperService.getLatestVersionIdsForResourceIds(RequestPartitionId.allPartitions(),
|
||||
theReferencesToAutoVersion.stream()
|
||||
.map(ref -> ref.getReferenceElement()).collect(Collectors.toList()));
|
||||
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IAutoVersioningService {
|
||||
/**
|
||||
* Takes in a list of IIdType and returns a map of
|
||||
* IIdType -> ResourcePersistentId.
|
||||
* ResourcePersistentId will contain the history version
|
||||
* but the returned IIdType will not (this is to allow consumers
|
||||
* to use their passed in IIdType as a lookup value).
|
||||
*
|
||||
* If the returned map does not return an IIdType -> ResourcePersistentId
|
||||
* then it means that it is a non-existing resource in the DB
|
||||
* @param theIds
|
||||
* @param thePartitionId - the partition id
|
||||
* @return
|
||||
*/
|
||||
Map<IIdType, ResourcePersistentId> getExistingAutoversionsForIds(RequestPartitionId thePartitionId, Collection<IIdType> theIds);
|
||||
}
|
|
@ -530,6 +530,95 @@ public class IdHelperService {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to determine if some resources exist in the DB (without throwing).
|
||||
* Returns a set that contains the IIdType for every resource found.
|
||||
* If it's not found, it won't be included in the set.
|
||||
* @param theIds - list of IIdType ids (for the same resource)
|
||||
* @return
|
||||
*/
|
||||
private Map<IIdType, ResourcePersistentId> getIdsOfExistingResources(RequestPartitionId thePartitionId,
|
||||
Collection<IIdType> theIds) {
|
||||
// these are the found Ids that were in the db
|
||||
HashMap<IIdType, ResourcePersistentId> collected = new HashMap<>();
|
||||
|
||||
if (theIds == null || theIds.isEmpty()) {
|
||||
return collected;
|
||||
}
|
||||
|
||||
List<ResourcePersistentId> resourcePersistentIds = resolveResourcePersistentIdsWithCache(thePartitionId,
|
||||
theIds.stream().collect(Collectors.toList()));
|
||||
|
||||
// we'll use this map to fetch pids that require versions
|
||||
HashMap<Long, ResourcePersistentId> pidsToVersionToResourcePid = new HashMap<>();
|
||||
|
||||
// fill in our map
|
||||
for (ResourcePersistentId pid : resourcePersistentIds) {
|
||||
if (pid.getVersion() == null) {
|
||||
pidsToVersionToResourcePid.put(pid.getIdAsLong(), pid);
|
||||
}
|
||||
Optional<IIdType> idOp = theIds.stream()
|
||||
.filter(i -> i.getIdPart().equals(pid.getAssociatedResourceId().getIdPart()))
|
||||
.findFirst();
|
||||
// this should always be present
|
||||
// since it was passed in.
|
||||
// but land of optionals...
|
||||
idOp.ifPresent(id -> {
|
||||
collected.put(id, pid);
|
||||
});
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the latest versions for any resourceid that are found.
|
||||
* If they are not found, they will not be contained in the returned map.
|
||||
* The key should be the same value that was passed in to allow
|
||||
* consumer to look up the value using the id they already have.
|
||||
*
|
||||
* This method should not throw, so it can safely be consumed in
|
||||
* transactions.
|
||||
*
|
||||
* @param theRequestPartitionId - request partition id
|
||||
* @param theIds - list of IIdTypes for resources of interest.
|
||||
* @return
|
||||
*/
|
||||
public Map<IIdType, ResourcePersistentId> getLatestVersionIdsForResourceIds(RequestPartitionId theRequestPartitionId, Collection<IIdType> theIds) {
|
||||
HashMap<IIdType, ResourcePersistentId> idToPID = new HashMap<>();
|
||||
HashMap<String, List<IIdType>> resourceTypeToIds = new HashMap<>();
|
||||
|
||||
for (IIdType id : theIds) {
|
||||
String resourceType = id.getResourceType();
|
||||
if (!resourceTypeToIds.containsKey(resourceType)) {
|
||||
resourceTypeToIds.put(resourceType, new ArrayList<>());
|
||||
}
|
||||
resourceTypeToIds.get(resourceType).add(id);
|
||||
}
|
||||
|
||||
for (String resourceType : resourceTypeToIds.keySet()) {
|
||||
Map<IIdType, ResourcePersistentId> idAndPID = getIdsOfExistingResources(theRequestPartitionId,
|
||||
resourceTypeToIds.get(resourceType));
|
||||
idToPID.putAll(idAndPID);
|
||||
}
|
||||
|
||||
return idToPID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
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.IFhirResourceDao;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class AutoVersioningServiceImplTests {
|
||||
|
||||
@Mock
|
||||
private DaoRegistry daoRegistry;
|
||||
|
||||
@InjectMocks
|
||||
private AutoVersioningServiceImpl myAutoversioningService;
|
||||
|
||||
@Test
|
||||
public void getAutoversionsForIds_whenResourceExists_returnsMapWithPIDAndVersion() {
|
||||
IIdType type = new IdDt("Patient/RED");
|
||||
ResourcePersistentId pid = new ResourcePersistentId(1);
|
||||
pid.setVersion(2L);
|
||||
HashMap<IIdType, ResourcePersistentId> map = new HashMap<>();
|
||||
map.put(type, pid);
|
||||
|
||||
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
||||
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.any(RequestPartitionId.class),
|
||||
Mockito.anyList()))
|
||||
.thenReturn(map);
|
||||
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
||||
.thenReturn(daoMock);
|
||||
|
||||
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||
Collections.singletonList(type));
|
||||
|
||||
Assertions.assertTrue(retMap.containsKey(type));
|
||||
Assertions.assertEquals(pid.getVersion(), map.get(type).getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAutoversionsForIds_whenResourceDoesNotExist_returnsEmptyMap() {
|
||||
IIdType type = new IdDt("Patient/RED");
|
||||
|
||||
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
||||
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.any(RequestPartitionId.class),
|
||||
Mockito.anyList()))
|
||||
.thenReturn(new HashMap<>());
|
||||
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
||||
.thenReturn(daoMock);
|
||||
|
||||
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(RequestPartitionId.allPartitions(),
|
||||
Collections.singletonList(type));
|
||||
|
||||
Assertions.assertTrue(retMap.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAutoversionsForIds_whenSomeResourcesDoNotExist_returnsOnlyExistingElements() {
|
||||
IIdType type = new IdDt("Patient/RED");
|
||||
ResourcePersistentId pid = new ResourcePersistentId(1);
|
||||
pid.setVersion(2L);
|
||||
HashMap<IIdType, ResourcePersistentId> map = new HashMap<>();
|
||||
map.put(type, pid);
|
||||
IIdType type2 = new IdDt("Patient/BLUE");
|
||||
|
||||
// when
|
||||
IFhirResourceDao daoMock = Mockito.mock(IFhirResourceDao.class);
|
||||
Mockito.when(daoMock.getIdsOfExistingResources(Mockito.any(RequestPartitionId.class), Mockito.anyList()))
|
||||
.thenReturn(map);
|
||||
Mockito.when(daoRegistry.getResourceDao(Mockito.anyString()))
|
||||
.thenReturn(daoMock);
|
||||
|
||||
// test
|
||||
Map<IIdType, ResourcePersistentId> retMap = myAutoversioningService.getExistingAutoversionsForIds(
|
||||
RequestPartitionId.allPartitions(),
|
||||
Arrays.asList(type, type2)
|
||||
);
|
||||
|
||||
// verify
|
||||
Assertions.assertEquals(map.size(), retMap.size());
|
||||
Assertions.assertTrue(retMap.containsKey(type));
|
||||
Assertions.assertFalse(retMap.containsKey(type2));
|
||||
}
|
||||
}
|
|
@ -1,188 +1,22 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
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.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.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
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.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoTestRule;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class BaseHapiFhirResourceDaoTest {
|
||||
|
||||
// our simple concrete test class for BaseHapiFhirResourceDao
|
||||
private class SimpleTestDao extends BaseHapiFhirResourceDao<Patient> {
|
||||
public SimpleTestDao() {
|
||||
super();
|
||||
// post inject hooks
|
||||
setResourceType(Patient.class);
|
||||
RuntimeResourceDefinition resourceDefinition = Mockito.mock(RuntimeResourceDefinition.class);
|
||||
Mockito.when(resourceDefinition.getName()).thenReturn("Patient");
|
||||
FhirContext myFhirContextMock = Mockito.mock(FhirContext.class);
|
||||
Mockito.when(myFhirContextMock.getResourceDefinition(Mockito.any(Class.class)))
|
||||
.thenReturn(resourceDefinition);
|
||||
setContext(myFhirContextMock);
|
||||
postConstruct();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@InjectMocks
|
||||
private BaseHapiFhirResourceDao myBaseHapiFhirResourceDao = new SimpleTestDao();
|
||||
|
||||
// @Mock
|
||||
// private IForcedIdDao myIForcedIdDao;
|
||||
|
||||
@Mock
|
||||
private IdHelperService myIdHelperService;
|
||||
|
||||
@Mock
|
||||
private IResourceTableDao myResourceTableDao;
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ResourceTable record for getResourceVersionsForPid
|
||||
* Order matters!
|
||||
* @param resourceType
|
||||
* @param pid
|
||||
* @param version
|
||||
* @return
|
||||
*/
|
||||
private Object[] getResourceTableRecordForResourceTypeAndPid(String resourceType, long pid, long version) {
|
||||
return new Object[] {
|
||||
pid, // long
|
||||
resourceType, // string
|
||||
version // long
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdsOfExistingResources_forExistingResources_returnsMapOfIdToPIDWithVersion() {
|
||||
// setup
|
||||
IIdType patientIdAndType = new IdDt("Patient/RED");
|
||||
long patientPID = 1L;
|
||||
long patientResourceVersion = 2L;
|
||||
ResourcePersistentId pat1ResourcePID = getResourcePersistentIdFromResource(patientIdAndType, patientPID);
|
||||
IIdType patient2IdAndType = new IdDt("Patient/BLUE");
|
||||
long patient2PID = 3L;
|
||||
long patient2ResourceVersion = 4L;
|
||||
ResourcePersistentId pat2ResourcePID = getResourcePersistentIdFromResource(patient2IdAndType, patient2PID);
|
||||
List<IIdType> inputList = new ArrayList<>();
|
||||
inputList.add(patientIdAndType);
|
||||
inputList.add(patient2IdAndType);
|
||||
|
||||
Collection<Object[]> matches = Arrays.asList(
|
||||
getResourceTableRecordForResourceTypeAndPid(patientIdAndType.getResourceType(), patientPID, patientResourceVersion),
|
||||
getResourceTableRecordForResourceTypeAndPid(patient2IdAndType.getResourceType(), patient2PID, patient2ResourceVersion)
|
||||
);
|
||||
|
||||
// when
|
||||
Mockito.when(myIdHelperService.resolveResourcePersistentIdsWithCache(Mockito.any(RequestPartitionId.class),
|
||||
Mockito.anyList()))
|
||||
.thenReturn(Arrays.asList(pat1ResourcePID, pat2ResourcePID));
|
||||
Mockito.when(myResourceTableDao.getResourceVersionsForPid(Mockito.anyList()))
|
||||
.thenReturn(matches);
|
||||
|
||||
Map<IIdType, ResourcePersistentId> idToPIDOfExistingResources = myBaseHapiFhirResourceDao.getIdsOfExistingResources(RequestPartitionId.allPartitions(),
|
||||
inputList);
|
||||
|
||||
Assertions.assertEquals(inputList.size(), idToPIDOfExistingResources.size());
|
||||
Assertions.assertTrue(idToPIDOfExistingResources.containsKey(patientIdAndType));
|
||||
Assertions.assertTrue(idToPIDOfExistingResources.containsKey(patient2IdAndType));
|
||||
|
||||
Assertions.assertEquals(patientPID, idToPIDOfExistingResources.get(patientIdAndType).getIdAsLong());
|
||||
Assertions.assertEquals(patient2PID, idToPIDOfExistingResources.get(patient2IdAndType).getIdAsLong(), patient2PID);
|
||||
Assertions.assertEquals(patientResourceVersion, idToPIDOfExistingResources.get(patientIdAndType).getVersion());
|
||||
Assertions.assertEquals(patient2ResourceVersion, idToPIDOfExistingResources.get(patient2IdAndType).getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdsOfExistingResources_forNonExistentResources_returnsEmptyMap() {
|
||||
//setup
|
||||
IIdType patient = new IdDt("Patient/RED");
|
||||
|
||||
// when
|
||||
Mockito.when(myIdHelperService.resolveResourcePersistentIdsWithCache(Mockito.any(RequestPartitionId.class),
|
||||
Mockito.anyList()))
|
||||
.thenReturn(new ArrayList<>());
|
||||
|
||||
Map<IIdType, ResourcePersistentId> map = myBaseHapiFhirResourceDao.getIdsOfExistingResources(RequestPartitionId.allPartitions(),
|
||||
Collections.singletonList(patient));
|
||||
|
||||
Assertions.assertTrue(map.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdsOfExistingResources_whenSomeResourcesExist_returnsOnlyExistingResourcesInMap() {
|
||||
// setup
|
||||
IIdType patientIdAndType = new IdDt("Patient/RED");
|
||||
long patientPID = 1L;
|
||||
long patientResourceVersion = 2L;
|
||||
IIdType patient2IdAndType = new IdDt("Patient/BLUE");
|
||||
List<IIdType> inputList = new ArrayList<>();
|
||||
inputList.add(patientIdAndType);
|
||||
inputList.add(patient2IdAndType);
|
||||
|
||||
// when
|
||||
Mockito.when(myIdHelperService
|
||||
.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(RequestPartitionId.allPartitions(),
|
||||
inputList);
|
||||
|
||||
// verify
|
||||
Assertions.assertFalse(map.isEmpty());
|
||||
Assertions.assertEquals(inputList.size() - 1, map.size());
|
||||
Assertions.assertTrue(map.containsKey(patientIdAndType));
|
||||
Assertions.assertFalse(map.containsKey(patient2IdAndType));
|
||||
}
|
||||
|
||||
/*******************/
|
||||
|
||||
TestResourceDao mySvc = new TestResourceDao();
|
||||
|
||||
@Test
|
||||
|
|
|
@ -70,8 +70,6 @@ public class TransactionProcessorTest {
|
|||
private MatchUrlService myMatchUrlService;
|
||||
@MockBean
|
||||
private IRequestPartitionHelperSvc myRequestPartitionHelperSvc;
|
||||
@MockBean
|
||||
private IAutoVersioningService myAutoVersioningService;
|
||||
|
||||
@MockBean(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private SessionImpl mySession;
|
||||
|
|
|
@ -1,13 +1,215 @@
|
|||
package ca.uhn.fhir.jpa.dao.index;
|
||||
|
||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Root;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class IdHelperServiceTest {
|
||||
|
||||
// helper class to package up data for helper methods
|
||||
private class ResourceIdPackage {
|
||||
public IIdType MyResourceId;
|
||||
public ResourcePersistentId MyPid;
|
||||
public Long MyVersion;
|
||||
|
||||
public ResourceIdPackage(IIdType id,
|
||||
ResourcePersistentId pid,
|
||||
Long version) {
|
||||
MyResourceId = id;
|
||||
MyPid = pid;
|
||||
MyVersion = version;
|
||||
}
|
||||
}
|
||||
|
||||
@Mock
|
||||
private IResourceTableDao myResourceTableDao;
|
||||
|
||||
@Mock
|
||||
private DaoConfig myDaoConfig;
|
||||
|
||||
@Mock
|
||||
private MemoryCacheService myMemoryCacheService;
|
||||
|
||||
@Mock
|
||||
private EntityManager myEntityManager;
|
||||
|
||||
@InjectMocks
|
||||
private IdHelperService myIdHelperService;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ResourceTable record for getResourceVersionsForPid
|
||||
* Order matters!
|
||||
* @param resourceType
|
||||
* @param pid
|
||||
* @param version
|
||||
* @return
|
||||
*/
|
||||
private Object[] getResourceTableRecordForResourceTypeAndPid(String resourceType, long pid, long version) {
|
||||
return new Object[] {
|
||||
pid, // long
|
||||
resourceType, // string
|
||||
version // long
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to mock out resolveResourcePersistentIdsWithCache
|
||||
* to return empty lists (as if no resources were found).
|
||||
*/
|
||||
private void mock_resolveResourcePersistentIdsWithCache_toReturnNothing() {
|
||||
CriteriaBuilder cb = Mockito.mock(CriteriaBuilder.class);
|
||||
CriteriaQuery<ForcedId> criteriaQuery = Mockito.mock(CriteriaQuery.class);
|
||||
Root<ForcedId> from = Mockito.mock(Root.class);
|
||||
Path path = Mockito.mock(Path.class);
|
||||
|
||||
Mockito.when(cb.createQuery(Mockito.any(Class.class)))
|
||||
.thenReturn(criteriaQuery);
|
||||
Mockito.when(criteriaQuery.from(Mockito.any(Class.class)))
|
||||
.thenReturn(from);
|
||||
Mockito.when(from.get(Mockito.anyString()))
|
||||
.thenReturn(path);
|
||||
|
||||
TypedQuery<ForcedId> queryMock = Mockito.mock(TypedQuery.class);
|
||||
Mockito.when(queryMock.getResultList()).thenReturn(new ArrayList<>()); // not found
|
||||
|
||||
Mockito.when(myEntityManager.getCriteriaBuilder())
|
||||
.thenReturn(cb);
|
||||
Mockito.when(myEntityManager.createQuery(Mockito.any(CriteriaQuery.class)))
|
||||
.thenReturn(queryMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to mock out getIdsOfExistingResources
|
||||
* to return the matches and resources matching those provided
|
||||
* by parameters.
|
||||
* @param theResourcePacks
|
||||
*/
|
||||
private void mockReturnsFor_getIdsOfExistingResources(ResourceIdPackage... theResourcePacks) {
|
||||
List<ResourcePersistentId> resourcePersistentIds = new ArrayList<>();
|
||||
List<Object[]> matches = new ArrayList<>();
|
||||
|
||||
for (ResourceIdPackage pack : theResourcePacks) {
|
||||
resourcePersistentIds.add(pack.MyPid);
|
||||
|
||||
matches.add(getResourceTableRecordForResourceTypeAndPid(
|
||||
pack.MyResourceId.getResourceType(),
|
||||
pack.MyPid.getIdAsLong(),
|
||||
pack.MyVersion
|
||||
));
|
||||
}
|
||||
|
||||
ResourcePersistentId first = resourcePersistentIds.remove(0);
|
||||
if (resourcePersistentIds.isEmpty()) {
|
||||
Mockito.when(myMemoryCacheService.getIfPresent(Mockito.any(MemoryCacheService.CacheEnum.class), Mockito.anyString()))
|
||||
.thenReturn(first).thenReturn(null);
|
||||
}
|
||||
else {
|
||||
Mockito.when(myMemoryCacheService.getIfPresent(Mockito.any(MemoryCacheService.CacheEnum.class), Mockito.anyString()))
|
||||
.thenReturn(first, resourcePersistentIds.toArray());
|
||||
}
|
||||
Mockito.when(myResourceTableDao.getResourceVersionsForPid(Mockito.anyList()))
|
||||
.thenReturn(matches);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLatestVersionIdsForResourceIds_whenResourceExists_returnsMapWithPIDAndVersion() {
|
||||
IIdType type = new IdDt("Patient/RED");
|
||||
ResourcePersistentId pid = new ResourcePersistentId(1L);
|
||||
pid.setAssociatedResourceId(type);
|
||||
HashMap<IIdType, ResourcePersistentId> map = new HashMap<>();
|
||||
map.put(type, pid);
|
||||
ResourceIdPackage pack = new ResourceIdPackage(type, pid, 2L);
|
||||
|
||||
// when
|
||||
mockReturnsFor_getIdsOfExistingResources(pack);
|
||||
|
||||
// test
|
||||
Map<IIdType, ResourcePersistentId> retMap = myIdHelperService.getLatestVersionIdsForResourceIds(RequestPartitionId.allPartitions(),
|
||||
Collections.singletonList(type));
|
||||
|
||||
Assertions.assertTrue(retMap.containsKey(type));
|
||||
Assertions.assertEquals(pid.getVersion(), map.get(type).getVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLatestVersionIdsForResourceIds_whenResourceDoesNotExist_returnsEmptyMap() {
|
||||
IIdType type = new IdDt("Patient/RED");
|
||||
|
||||
// when
|
||||
mock_resolveResourcePersistentIdsWithCache_toReturnNothing();
|
||||
|
||||
// test
|
||||
Map<IIdType, ResourcePersistentId> retMap = myIdHelperService.getLatestVersionIdsForResourceIds(RequestPartitionId.allPartitions(),
|
||||
Collections.singletonList(type));
|
||||
|
||||
Assertions.assertTrue(retMap.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLatestVersionIdsForResourceIds_whenSomeResourcesDoNotExist_returnsOnlyExistingElements() {
|
||||
// resource to be found
|
||||
IIdType type = new IdDt("Patient/RED");
|
||||
ResourcePersistentId pid = new ResourcePersistentId(1L);
|
||||
pid.setAssociatedResourceId(type);
|
||||
ResourceIdPackage pack = new ResourceIdPackage(type, pid, 2L);
|
||||
|
||||
// resource that won't be found
|
||||
IIdType type2 = new IdDt("Patient/BLUE");
|
||||
|
||||
// when
|
||||
mock_resolveResourcePersistentIdsWithCache_toReturnNothing();
|
||||
mockReturnsFor_getIdsOfExistingResources(pack);
|
||||
|
||||
// test
|
||||
Map<IIdType, ResourcePersistentId> retMap = myIdHelperService.getLatestVersionIdsForResourceIds(
|
||||
RequestPartitionId.allPartitions(),
|
||||
Arrays.asList(type, type2)
|
||||
);
|
||||
|
||||
// verify
|
||||
Assertions.assertEquals(1, retMap.size());
|
||||
Assertions.assertTrue(retMap.containsKey(type));
|
||||
Assertions.assertFalse(retMap.containsKey(type2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceDefault_AllPartitions() {
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import ca.uhn.fhir.jpa.binstore.BinaryStorageInterceptor;
|
|||
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportSvc;
|
||||
import ca.uhn.fhir.jpa.config.TestR4Config;
|
||||
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
|
||||
import ca.uhn.fhir.jpa.dao.IAutoVersioningService;
|
||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IMdmLinkDao;
|
||||
|
@ -499,8 +498,6 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
|
|||
protected ValidationSettings myValidationSettings;
|
||||
@Autowired
|
||||
protected IMdmLinkDao myMdmLinkDao;
|
||||
@Autowired
|
||||
protected IAutoVersioningService myAutoVersioningService;
|
||||
|
||||
@AfterEach()
|
||||
public void afterCleanupDao() {
|
||||
|
|
Loading…
Reference in New Issue