remove newSearchBuilder from dao

This commit is contained in:
Ken Stevens 2020-01-24 13:01:35 -05:00
parent 16cb9a74e4
commit 9b0f850cf4
12 changed files with 51 additions and 36 deletions

View File

@ -21,10 +21,7 @@ package ca.uhn.fhir.jpa.bulk;
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.IResultIterator;
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.dao.data.IBulkExportCollectionDao;
import ca.uhn.fhir.jpa.dao.data.IBulkExportCollectionFileDao;
import ca.uhn.fhir.jpa.dao.data.IBulkExportJobDao;
@ -95,6 +92,8 @@ public class BulkDataExportSvcImpl implements IBulkDataExportSvc {
private FhirContext myContext;
@Autowired
private PlatformTransactionManager myTxManager;
@Autowired
private SearchBuilderFactory mySearchBuilderFactory;
private TransactionTemplate myTxTemplate;
private long myFileMaxChars = 500 * FileUtils.ONE_KB;
@ -214,7 +213,7 @@ public class BulkDataExportSvcImpl implements IBulkDataExportSvc {
ourLog.info("Bulk export assembling export of type {} for job {}", nextType, theJobUuid);
Class<? extends IBaseResource> nextTypeClass = myContext.getResourceDefinition(nextType).getImplementingClass();
ISearchBuilder sb = dao.newSearchBuilder(nextType, nextTypeClass);
ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(dao, nextType, nextTypeClass);
SearchParameterMap map = new SearchParameterMap();
map.setLoadSynchronous(true);

View File

@ -401,7 +401,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
search = mySearchCacheSvc.save(search);
return new PersistedJpaBundleProvider(theRequest, search.getUuid(), this);
return new PersistedJpaBundleProvider(theRequest, search.getUuid(), this, mySearchBuilderFactory);
}
void incrementId(T theResource, ResourceTable theSavedEntity, IIdType theResourceId) {
@ -435,12 +435,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
return LogicalReferenceHelper.isLogicalReference(myConfig.getModelConfig(), theId);
}
// TODO KHS inject a searchBuilderFactory into callers of this method and delete this method
@Override
public SearchBuilder newSearchBuilder(String theResourceName, Class<? extends IBaseResource> theResourceType) {
return mySearchBuilderFactory.newSearchBuilder(this, theResourceName, theResourceType);
}
public void notifyInterceptors(RestOperationTypeEnum theOperationType, ActionRequestDetails theRequestDetails) {
if (theRequestDetails.getId() != null && theRequestDetails.getId().hasResourceType() && isNotBlank(theRequestDetails.getResourceType())) {
if (theRequestDetails.getId().getResourceType().equals(theRequestDetails.getResourceType()) == false) {

View File

@ -91,6 +91,11 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
private MatchResourceUrlService myMatchResourceUrlService;
@Autowired
private IResourceReindexingSvc myResourceReindexingSvc;
@Autowired
private SearchBuilderFactory mySearchBuilderFactory;
@Autowired
private DaoRegistry myDaoRegistry;
private IInstanceValidatorModule myInstanceValidator;
private String myResourceName;
private Class<T> myResourceType;
@ -1093,7 +1098,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Override
public Set<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest) {
SearchBuilder builder = newSearchBuilder(getResourceName(), getResourceType());
ISearchBuilder builder = mySearchBuilderFactory.newSearchBuilder(this, getResourceName(), getResourceType());
// FIXME: fail if too many results

View File

@ -48,8 +48,6 @@ public interface IDao {
*/
void injectDependenciesIntoBundleProvider(PersistedJpaBundleProvider theProvider);
ISearchBuilder newSearchBuilder(String theResourceName, Class<? extends IBaseResource> theResourceType);
IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation);
<R extends IBaseResource> R toResource(Class<R> theResourceType, IBaseResourceEntity theEntity, Collection<ResourceTag> theTagList, boolean theForHistoryOperation);

View File

@ -27,5 +27,5 @@ import org.springframework.stereotype.Service;
@Service
public abstract class SearchBuilderFactory {
@Lookup
public abstract SearchBuilder newSearchBuilder(BaseHapiFhirDao theBaseHapiFhirResourceDao, String theResourceName, Class<? extends IBaseResource> theResourceType);
public abstract ISearchBuilder newSearchBuilder(IDao theDao, String theResourceName, Class<? extends IBaseResource> theResourceType);
}

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.search;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.BasePagingProvider;
@ -35,6 +36,8 @@ public class DatabaseBackedPagingProvider extends BasePagingProvider implements
@Autowired
private DaoRegistry myDaoRegistry;
@Autowired
private SearchBuilderFactory mySearchBuilderFactory;
/**
* Constructor
@ -55,7 +58,7 @@ public class DatabaseBackedPagingProvider extends BasePagingProvider implements
@Override
public synchronized IBundleProvider retrieveResultList(RequestDetails theRequestDetails, String theId) {
IFhirSystemDao<?, ?> systemDao = myDaoRegistry.getSystemDao();
PersistedJpaBundleProvider provider = new PersistedJpaBundleProvider(theRequestDetails, theId, systemDao);
PersistedJpaBundleProvider provider = new PersistedJpaBundleProvider(theRequestDetails, theId, systemDao, mySearchBuilderFactory);
if (!provider.ensureSearchEntityLoaded()) {
return null;
}

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.search;
*/
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
@ -37,7 +38,7 @@ public interface ISearchCoordinatorSvc {
List<ResourcePersistentId> getResources(String theUuid, int theFrom, int theTo, @Nullable RequestDetails theRequestDetails);
IBundleProvider registerSearch(IDao theCallingDao, SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective, @Nullable RequestDetails theRequestDetails);
IBundleProvider registerSearch(IFhirResourceDao theCallingDao, SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective, @Nullable RequestDetails theRequestDetails);
/**
* Fetch the total number of search results for the given currently executing search, if one is currently executing and

View File

@ -25,7 +25,9 @@ import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
@ -60,20 +62,22 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
private static final Logger ourLog = LoggerFactory.getLogger(PersistedJpaBundleProvider.class);
private final RequestDetails myRequest;
private FhirContext myContext;
private IDao myDao;
private final IDao myDao;
private EntityManager myEntityManager;
private PlatformTransactionManager myPlatformTransactionManager;
private ISearchCoordinatorSvc mySearchCoordinatorSvc;
private ISearchCacheSvc mySearchCacheSvc;
private Search mySearchEntity;
private String myUuid;
private final String myUuid;
private boolean myCacheHit;
private IInterceptorBroadcaster myInterceptorBroadcaster;
private final SearchBuilderFactory mySearchBuilderFactory;
public PersistedJpaBundleProvider(RequestDetails theRequest, String theSearchUuid, IDao theDao) {
public PersistedJpaBundleProvider(RequestDetails theRequest, String theSearchUuid, IDao theDao, SearchBuilderFactory theSearchBuilderFactory) {
myRequest = theRequest;
myUuid = theSearchUuid;
myDao = theDao;
mySearchBuilderFactory = theSearchBuilderFactory;
}
/**
@ -172,7 +176,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
}
String resourceName = mySearchEntity.getResourceType();
Class<? extends IBaseResource> resourceType = myContext.getResourceDefinition(resourceName).getImplementingClass();
final ISearchBuilder sb = myDao.newSearchBuilder(resourceName, resourceType);
final ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(myDao, resourceName, resourceType);
final List<ResourcePersistentId> pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex, myRequest);

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.search;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.ISearchBuilder;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
@ -50,8 +51,9 @@ public class PersistedJpaSearchFirstPageBundleProvider extends PersistedJpaBundl
private Search mySearch;
private PlatformTransactionManager myTxManager;
public PersistedJpaSearchFirstPageBundleProvider(Search theSearch, IDao theDao, SearchTask theSearchTask, ISearchBuilder theSearchBuilder, PlatformTransactionManager theTxManager, RequestDetails theRequest) {
super(theRequest, theSearch.getUuid(), theDao);
// TODO KHS too many collaborators. This should be a prototype bean
public PersistedJpaSearchFirstPageBundleProvider(Search theSearch, IDao theDao, SearchBuilderFactory theSearchBuilderFactory, SearchTask theSearchTask, ISearchBuilder theSearchBuilder, PlatformTransactionManager theTxManager, RequestDetails theRequest) {
super(theRequest, theSearch.getUuid(), theDao, theSearchBuilderFactory);
setSearchEntity(theSearch);
mySearchTask = theSearchTask;
mySearchBuilder = theSearchBuilder;

View File

@ -121,6 +121,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private DaoRegistry myDaoRegistry;
@Autowired
private IPagingProvider myPagingProvider;
@Autowired
private SearchBuilderFactory mySearchBuilderFactory;
private int mySyncSize = DEFAULT_SYNC_SIZE;
/**
@ -280,13 +282,13 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
}
@Override
public IBundleProvider registerSearch(final IDao theCallingDao, final SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective, RequestDetails theRequestDetails) {
public IBundleProvider registerSearch(final IFhirResourceDao theCallingDao, final SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective, RequestDetails theRequestDetails) {
final String searchUuid = UUID.randomUUID().toString();
ourLog.debug("Registering new search {}", searchUuid);
Class<? extends IBaseResource> resourceTypeClass = myContext.getResourceDefinition(theResourceType).getImplementingClass();
final ISearchBuilder sb = theCallingDao.newSearchBuilder(theResourceType, resourceTypeClass);
final ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(theCallingDao, theResourceType, resourceTypeClass);
sb.setFetchSize(mySyncSize);
final Integer loadSynchronousUpTo = getLoadSynchronousUpToOrNull(theCacheControlDirective);
@ -368,7 +370,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
myIdToSearchTask.put(search.getUuid(), task);
myExecutor.submit(task);
PersistedJpaSearchFirstPageBundleProvider retVal = new PersistedJpaSearchFirstPageBundleProvider(search, theCallingDao, task, theSb, myManagedTxManager, theRequestDetails);
PersistedJpaSearchFirstPageBundleProvider retVal = new PersistedJpaSearchFirstPageBundleProvider(search, theCallingDao, mySearchBuilderFactory, task, theSb, myManagedTxManager, theRequestDetails);
populateBundleProvider(retVal);
ourLog.debug("Search initial phase completed in {}ms", w.getMillis());
@ -406,7 +408,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
mySearchCacheSvc.updateSearchLastReturned(searchToUse, new Date());
PersistedJpaBundleProvider retVal = new PersistedJpaBundleProvider(theRequestDetails, searchToUse.getUuid(), theCallingDao);
PersistedJpaBundleProvider retVal = new PersistedJpaBundleProvider(theRequestDetails, searchToUse.getUuid(), theCallingDao, mySearchBuilderFactory);
retVal.setCacheHit(true);
populateBundleProvider(retVal);
@ -649,7 +651,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private ISearchBuilder newSearchBuilder() {
Class<? extends IBaseResource> resourceTypeClass = myContext.getResourceDefinition(myResourceType).getImplementingClass();
ISearchBuilder sb = myCallingDao.newSearchBuilder(myResourceType, resourceTypeClass);
ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(myCallingDao, myResourceType, resourceTypeClass);
return sb;
}

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.search;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.junit.Before;
@ -15,13 +16,15 @@ import static org.mockito.Mockito.verifyNoInteractions;
public class PersistedJpaBundleProviderTest {
private PersistedJpaBundleProvider myPersistedJpaBundleProvider;
private IDao myDao;
private SearchBuilderFactory mySearchBuilderFactory;
@Before
public void init() {
RequestDetails request = mock(RequestDetails.class);
String searchUuid = "this is not a hat";
myDao = mock(IDao.class);
myPersistedJpaBundleProvider = new PersistedJpaBundleProvider(request, searchUuid, myDao);
mySearchBuilderFactory = mock(SearchBuilderFactory.class);
myPersistedJpaBundleProvider = new PersistedJpaBundleProvider(request, searchUuid, myDao, mySearchBuilderFactory);
}
@Test
@ -31,5 +34,6 @@ public class PersistedJpaBundleProviderTest {
myPersistedJpaBundleProvider.setSearchEntity(searchEntity);
myPersistedJpaBundleProvider.doSearchOrEverything(0, 1);
verifyNoInteractions(myDao);
verifyNoInteractions(mySearchBuilderFactory);
}
}

View File

@ -60,7 +60,7 @@ public class SearchCoordinatorSvcImplTest {
private EntityManager myEntityManager;
private int myExpectedNumberOfSearchBuildersCreated = 2;
@Mock
private ISearchBuilder mySearchBuilder;
private SearchBuilder mySearchBuilder;
@Mock
private ISearchCacheSvc mySearchCacheSvc;
@Mock
@ -73,11 +73,14 @@ public class SearchCoordinatorSvcImplTest {
private DaoRegistry myDaoRegistry;
@Mock
private IInterceptorBroadcaster myInterceptorBroadcaster;
@Mock
private SearchBuilderFactory mySearchBuilderFactory;
@After
public void after() {
System.clearProperty(SearchCoordinatorSvcImpl.UNIT_TEST_CAPTURE_STACK);
verify(myCallingDao, atMost(myExpectedNumberOfSearchBuildersCreated)).newSearchBuilder(any(), any());
verify(mySearchBuilderFactory, atMost(myExpectedNumberOfSearchBuildersCreated)).newSearchBuilder(any(), any(), any());
}
@Before
@ -98,7 +101,7 @@ public class SearchCoordinatorSvcImplTest {
DaoConfig daoConfig = new DaoConfig();
mySvc.setDaoConfigForUnitTest(daoConfig);
when(myCallingDao.newSearchBuilder(any(), any())).thenReturn(mySearchBuilder);
when(mySearchBuilderFactory.newSearchBuilder(any(), any(), any())).thenReturn(mySearchBuilder);
when(myTxManager.getTransaction(any())).thenReturn(mock(TransactionStatus.class));
@ -380,7 +383,7 @@ public class SearchCoordinatorSvcImplTest {
* Now call from a new bundle provider. This simulates a separate HTTP
* client request coming in.
*/
provider = new PersistedJpaBundleProvider(null, result.getUuid(), myCallingDao);
provider = new PersistedJpaBundleProvider(null, result.getUuid(), myCallingDao, mySearchBuilderFactory);
resources = provider.getResources(10, 20);
assertEquals(10, resources.size());
assertEquals("20", resources.get(0).getIdElement().getValueAsString());
@ -458,13 +461,13 @@ public class SearchCoordinatorSvcImplTest {
* Now call from a new bundle provider. This simulates a separate HTTP
* client request coming in.
*/
provider = new PersistedJpaBundleProvider(null, uuid, myCallingDao);
provider = new PersistedJpaBundleProvider(null, uuid, myCallingDao, mySearchBuilderFactory);
resources = provider.getResources(10, 20);
assertEquals(10, resources.size());
assertEquals("20", resources.get(0).getIdElement().getValueAsString());
assertEquals("29", resources.get(9).getIdElement().getValueAsString());
provider = new PersistedJpaBundleProvider(null, uuid, myCallingDao);
provider = new PersistedJpaBundleProvider(null, uuid, myCallingDao, mySearchBuilderFactory);
resources = provider.getResources(20, 40);
assertEquals(20, resources.size());
assertEquals("30", resources.get(0).getIdElement().getValueAsString());