package ca.uhn.fhir.jpa.dao;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import org.apache.commons.io.IOUtils;
import org.hibernate.search.jpa.Search;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Before;
import org.mockito.Mockito;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.rest.method.IRequestOperationCallback;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.TestUtil;
public abstract class BaseJpaTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaTest.class);
protected ServletRequestDetails mySrd;
protected ArrayList<IServerInterceptor> myServerInterceptorList;
protected IRequestOperationCallback myRequestOperationCallback = mock(IRequestOperationCallback.class);
@Before
public void beforeCreateSrd() {
mySrd = mock(ServletRequestDetails.class, Mockito.RETURNS_DEEP_STUBS);
when(mySrd.getRequestOperationCallback()).thenReturn(myRequestOperationCallback);
myServerInterceptorList = new ArrayList<IServerInterceptor>();
when(mySrd.getServer().getInterceptors()).thenReturn(myServerInterceptorList);
when(mySrd.getUserData()).thenReturn(new HashMap<Object, Object>());
}
@SuppressWarnings({ "rawtypes" })
protected List toList(IBundleProvider theSearch) {
return theSearch.getResources(0, theSearch.size());
}
protected org.hl7.fhir.dstu3.model.Bundle toBundle(IBundleProvider theSearch) {
org.hl7.fhir.dstu3.model.Bundle bundle = new org.hl7.fhir.dstu3.model.Bundle();
for (IBaseResource next : theSearch.getResources(0, theSearch.size())) {
bundle.addEntry().setResource((Resource) next);
}
return bundle;
}
protected abstract FhirContext getContext();
protected List<String> toUnqualifiedVersionlessIdValues(IBaseBundle theFound) {
List<String> retVal = new ArrayList<String>();
List<IBaseResource> res = BundleUtil.toListOfResources(getContext(), theFound);
int size = res.size();
ourLog.info("Found {} results", size);
for (IBaseResource next : res) {
retVal.add(next.getIdElement().toUnqualifiedVersionless().getValue());
}
return retVal;
}
protected List<String> toUnqualifiedIdValues(IBaseBundle theFound) {
List<String> retVal = new ArrayList<String>();
List<IBaseResource> res = BundleUtil.toListOfResources(getContext(), theFound);
int size = res.size();
ourLog.info("Found {} results", size);
for (IBaseResource next : res) {
retVal.add(next.getIdElement().toUnqualified().getValue());
}
return retVal;
}
protected List<IIdType> toUnqualifiedVersionlessIds(Bundle theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
for (Entry next : theFound.getEntry()) {
// if (next.getResource()!= null) {
retVal.add(next.getResource().getId().toUnqualifiedVersionless());
// }
}
return retVal;
}
protected List<IIdType> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
int size = theFound.size();
ourLog.info("Found {} results", size);
List<IBaseResource> resources = theFound.getResources(0, size);
for (IBaseResource next : resources) {
retVal.add((IIdType) next.getIdElement().toUnqualifiedVersionless());
}
return retVal;
}
protected List<IIdType> toUnqualifiedVersionlessIds(List<IBaseResource> theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
for (IBaseResource next : theFound) {
retVal.add((IIdType) next.getIdElement().toUnqualifiedVersionless());
}
return retVal;
}
protected List<IIdType> toUnqualifiedVersionlessIds(org.hl7.fhir.dstu3.model.Bundle theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
for (BundleEntryComponent next : theFound.getEntry()) {
// if (next.getResource()!= null) {
retVal.add(next.getResource().getIdElement().toUnqualifiedVersionless());
// }
}
return retVal;
}
protected List<String> toUnqualifiedVersionlessIdValues(IBundleProvider theFound) {
List<String> retVal = new ArrayList<String>();
int size = theFound.size();
ourLog.info("Found {} results", size);
List<IBaseResource> resources = theFound.getResources(0, size);
for (IBaseResource next : resources) {
retVal.add(next.getIdElement().toUnqualifiedVersionless().getValue());
}
return retVal;
}
protected List<String> toUnqualifiedIdValues(IBundleProvider theFound) {
List<String> retVal = new ArrayList<String>();
int size = theFound.size();
ourLog.info("Found {} results", size);
List<IBaseResource> resources = theFound.getResources(0, size);
for (IBaseResource next : resources) {
retVal.add(next.getIdElement().toUnqualified().getValue());
}
return retVal;
}
protected String[] toValues(IIdType... theValues) {
ArrayList<String> retVal = new ArrayList<String>();
for (IIdType next : theValues) {
retVal.add(next.getValue());
}
return retVal.toArray(new String[retVal.size()]);
}
@AfterClass
public static void afterClassClearContext() throws Exception {
TestUtil.clearAllStaticFieldsForUnitTest();
}
@AfterClass
public static void afterClassShutdownDerby() throws SQLException {
// DriverManager.getConnection("jdbc:derby:;shutdown=true");
// try {
// DriverManager.getConnection("jdbc:derby:memory:myUnitTestDB;drop=true");
// } catch (SQLNonTransientConnectionException e) {
// // expected.. for some reason....
// }
}
public static String loadClasspath(String resource) throws IOException {
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream(resource);
if (bundleRes == null) {
throw new NullPointerException("Can not load " + resource);
}
String bundleStr = IOUtils.toString(bundleRes);
return bundleStr;
}
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager, ISearchParamPresenceSvc theSearchParamPresenceSvc, ISearchCoordinatorSvc theSearchCoordinatorSvc) {
theSearchCoordinatorSvc.cancelAllActiveSearches();
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("UPDATE " + ResourceHistoryTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
entityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + SearchParamPresent.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SearchParam.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SubscriptionFlaggedResource.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SubscriptionFlaggedResource.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamQuantity.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamString.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamToken.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamUri.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamCoords.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceLink.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SearchResult.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SearchInclude.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermConceptParentChildLink.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + TermConcept.class.getSimpleName() + " d").executeUpdate();
for (TermCodeSystem next : entityManager.createQuery("SELECT c FROM " + TermCodeSystem.class.getName() + " c", TermCodeSystem.class).getResultList()) {
next.setCurrentVersion(null);
entityManager.merge(next);
}
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + TermCodeSystemVersion.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermCodeSystem.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + SubscriptionTable.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceHistoryTag.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceTag.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TagDefinition.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceHistoryTable.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceTable.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + Search.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
theSearchParamPresenceSvc.flushCachesForUnitTest();
}
public static Set<String> toCodes(Set<TermConcept> theConcepts) {
HashSet<String> retVal = new HashSet<String>();
for (TermConcept next : theConcepts) {
retVal.add(next.getCode());
}
return retVal;
}
public static Set<String> toCodes(List<VersionIndependentConcept> theConcepts) {
HashSet<String> retVal = new HashSet<String>();
for (VersionIndependentConcept next : theConcepts) {
retVal.add(next.getCode());
}
return retVal;
}
}