Replace phloc with ph for #775 (#930)

* Replace phloc with ph

* Enable schematron tests

* Make HAPI-FHIR ph-schematron on OSGI

* Work on getting tests passing

* Another test fix

* Fix up transaction handling for DSTU2

* Add changelog

* Avoid double transaction

* Dont use readonly

* One more test fix

* Update to snapshow build

* Resolve a circular dependency

* Try to fix tests

* Solve recurring NPE in DSTU2 tests

* Fix one more test

* Test fix

* More test threading fixes

* One more attempt to get tests passing

* Refactoring for tests

* Refactoring for tests
This commit is contained in:
James Agnew 2018-05-14 17:38:40 -04:00 committed by GitHub
parent 3a03d4ff63
commit a3ff08d9ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 1699 additions and 1434 deletions

View File

@ -181,8 +181,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>

View File

@ -60,7 +60,7 @@ public class FhirServerConfig extends BaseJavaConfigDstu3 {
@Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = entityManagerFactory();
LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource());
retVal.setJpaProperties(jpaProperties());

View File

@ -11,7 +11,7 @@
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>3.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-jpaserver-dynamic</artifactId>
@ -198,8 +198,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>

View File

@ -100,8 +100,8 @@
<artifactId>javax.mail-api</artifactId>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
@ -140,6 +140,7 @@
<ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
<ignoredResource>javac.bat</ignoredResource>
<ignoredResource>about.html</ignoredResource>
<ignoredResource>changelog.xml</ignoredResource>
</ignoredResourcePatterns>
</configuration>
</plugin>

View File

@ -45,27 +45,14 @@
<!-- Only required for Schematron Validator Support -->
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<optional>true</optional>
<exclusions><!--
<exclusion>
<artifactId>Saxon-HE</artifactId>
<groupId>net.sf.saxon</groupId>
</exclusion>-->
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<!-- Guava brings in a newer replacement for this dependency called com.google.code.findbugs:jsr305 -->
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId>

View File

@ -42,9 +42,9 @@ import ca.uhn.fhir.validation.schematron.SchematronProvider;
*/
public class FhirValidator {
private static final String I18N_KEY_NO_PHLOC_ERROR = FhirValidator.class.getName() + ".noPhlocError";
private static final String I18N_KEY_NO_PH_ERROR = FhirValidator.class.getName() + ".noPhError";
private static volatile Boolean ourPhlocPresentOnClasspath;
private static volatile Boolean ourPhPresentOnClasspath;
private final FhirContext myContext;
private List<IValidatorModule> myValidators = new ArrayList<IValidatorModule>();
@ -54,8 +54,8 @@ public class FhirValidator {
public FhirValidator(FhirContext theFhirContext) {
myContext = theFhirContext;
if (ourPhlocPresentOnClasspath == null) {
ourPhlocPresentOnClasspath = SchematronProvider.isSchematronAvailable(theFhirContext);
if (ourPhPresentOnClasspath == null) {
ourPhPresentOnClasspath = SchematronProvider.isSchematronAvailable(theFhirContext);
}
}
@ -96,9 +96,10 @@ public class FhirValidator {
* Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
*/
public synchronized boolean isValidateAgainstStandardSchematron() {
if (!ourPhlocPresentOnClasspath) {
return false; // No need to ask since we dont have Phloc. Also Class.forname will complain
// about missing phloc import.
if (!ourPhPresentOnClasspath) {
// No need to ask since we dont have Ph-Schematron. Also Class.forname will complain
// about missing ph-schematron import.
return false;
}
Class<? extends IValidatorModule> cls = SchematronProvider.getSchematronValidatorClass();
return haveValidatorOfType(cls);
@ -135,8 +136,11 @@ public class FhirValidator {
* @return Returns a referens to <code>this<code> for method chaining
*/
public synchronized FhirValidator setValidateAgainstStandardSchematron(boolean theValidateAgainstStandardSchematron) {
if (theValidateAgainstStandardSchematron && !ourPhlocPresentOnClasspath) {
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(I18N_KEY_NO_PHLOC_ERROR));
if (theValidateAgainstStandardSchematron && !ourPhPresentOnClasspath) {
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(I18N_KEY_NO_PH_ERROR));
}
if (!theValidateAgainstStandardSchematron && !ourPhPresentOnClasspath) {
return this;
}
Class<? extends IValidatorModule> cls = SchematronProvider.getSchematronValidatorClass();
IValidatorModule instance = SchematronProvider.getSchematronValidatorInstance(myContext);
@ -163,7 +167,7 @@ public class FhirValidator {
private void applyDefaultValidators() {
if (myValidators.isEmpty()) {
setValidateAgainstStandardSchema(true);
if (ourPhlocPresentOnClasspath) {
if (ourPhPresentOnClasspath) {
setValidateAgainstStandardSchematron(true);
}
}

View File

@ -20,28 +20,28 @@ package ca.uhn.fhir.validation.schematron;
* #L%
*/
import java.io.InputStream;
import java.io.StringReader;
import java.util.*;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.oclc.purl.dsdl.svrl.SchematronOutputType;
import com.phloc.commons.error.IResourceError;
import com.phloc.commons.error.IResourceErrorGroup;
import com.phloc.schematron.ISchematronResource;
import com.phloc.schematron.SchematronHelper;
import com.phloc.schematron.xslt.SchematronResourceSCH;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.validation.*;
import com.helger.commons.error.IError;
import com.helger.commons.error.list.IErrorList;
import com.helger.schematron.ISchematronResource;
import com.helger.schematron.SchematronHelper;
import com.helger.schematron.xslt.SchematronResourceSCH;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.oclc.purl.dsdl.svrl.SchematronOutputType;
import javax.xml.transform.stream.StreamSource;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* This class is only used using reflection from {@link SchematronProvider} in order
@ -81,27 +81,21 @@ public class SchematronBaseValidator implements IValidatorModule {
return;
}
IResourceErrorGroup errors = SchematronHelper.convertToResourceErrorGroup(results, theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName());
IErrorList errors = SchematronHelper.convertToErrorList(results, theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName());
if (errors.getAllErrors().containsOnlySuccess()) {
return;
}
for (IResourceError next : errors.getAllErrors().getAllResourceErrors()) {
for (IError next : errors) {
ResultSeverityEnum severity;
switch (next.getErrorLevel()) {
case ERROR:
if (next.isFailure()) {
severity = ResultSeverityEnum.ERROR;
break;
case FATAL_ERROR:
} else if (next.isError()) {
severity = ResultSeverityEnum.FATAL;
break;
case WARN:
} else if (next.isNoError()) {
severity = ResultSeverityEnum.WARNING;
break;
case INFO:
case SUCCESS:
default:
} else {
continue;
}
@ -109,9 +103,9 @@ public class SchematronBaseValidator implements IValidatorModule {
SingleValidationMessage message = new SingleValidationMessage();
message.setMessage(details);
message.setLocationLine(next.getLocation().getLineNumber());
message.setLocationCol(next.getLocation().getColumnNumber());
message.setLocationString(next.getLocation().getAsString());
message.setLocationLine(next.getErrorLocation().getLineNumber());
message.setLocationCol(next.getErrorLocation().getColumnNumber());
message.setLocationString(next.getErrorLocation().getAsString());
message.setSeverity(severity);
theCtx.addValidationMessage(message);
}

View File

@ -30,16 +30,16 @@ import ca.uhn.fhir.validation.IValidatorModule;
public class SchematronProvider {
private static final String I18N_KEY_NO_PHLOC_WARNING = FhirValidator.class.getName() + ".noPhlocWarningOnStartup";
private static final String I18N_KEY_NO_PH_WARNING = FhirValidator.class.getName() + ".noPhWarningOnStartup";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirValidator.class);
@CoverageIgnore
public static boolean isSchematronAvailable(FhirContext theFhirContext) {
try {
Class.forName("com.phloc.schematron.ISchematronResource");
Class.forName("com.helger.schematron.ISchematronResource");
return true;
} catch (ClassNotFoundException e) {
ourLog.info(theFhirContext.getLocalizer().getMessage(I18N_KEY_NO_PHLOC_WARNING));
ourLog.info(theFhirContext.getLocalizer().getMessage(I18N_KEY_NO_PH_WARNING));
return false;
}
}

View File

@ -51,8 +51,8 @@ ca.uhn.fhir.rest.server.RestfulServer.unknownMethod=Invalid request: The FHIR en
ca.uhn.fhir.rest.server.RestfulServer.rootRequest=This is the base URL of FHIR server. Unable to handle this request, as it does not contain a resource type or operation name.
ca.uhn.fhir.rest.server.RestfulServer.rootRequest.multitenant=This is the base URL of a multitenant FHIR server. Unable to handle this request, as it does not contain a tenant ID.
ca.uhn.fhir.validation.ValidationContext.unableToDetermineEncoding=Unable to determine encoding (e.g. XML / JSON) on validation input. Is this a valid FHIR resource body?
ca.uhn.fhir.validation.FhirValidator.noPhlocWarningOnStartup=Phloc-schematron library not found on classpath, will not attempt to perform schematron validation
ca.uhn.fhir.validation.FhirValidator.noPhlocError=Phloc-schematron library not found on classpath, can not enable perform schematron validation
ca.uhn.fhir.validation.FhirValidator.noPhWarningOnStartup=Ph-schematron library not found on classpath, will not attempt to perform schematron validation
ca.uhn.fhir.validation.FhirValidator.noPhError=Ph-schematron library not found on classpath, can not enable perform schematron validation
ca.uhn.fhir.validation.ValidationResult.noIssuesDetected=No issues detected during validation
# JPA Messages

View File

@ -173,8 +173,8 @@
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>
@ -183,8 +183,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
</dependency>
<!--
@ -196,14 +196,11 @@
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>

View File

@ -24,7 +24,7 @@ import ca.uhn.fhir.util.VersionUtil;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import com.phloc.commons.io.file.FileUtils;
import com.helger.commons.io.file.FileHelper;
import org.apache.commons.cli.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils;
@ -60,7 +60,7 @@ public abstract class BaseApp {
System.out.println("------------------------------------------------------------");
System.out.println("\ud83d\udd25 " + ansi().bold() + " " + provideProductName() + ansi().boldOff() + " " + provideProductVersion() + " - Command Line Tool");
System.out.println("------------------------------------------------------------");
System.out.println("Max configured JVM memory (Xmx): " + FileUtils.getFileSizeDisplay(Runtime.getRuntime().maxMemory(), 1));
System.out.println("Max configured JVM memory (Xmx): " + FileHelper.getFileSizeDisplay(Runtime.getRuntime().maxMemory(), 1));
System.out.println("Detected Java version: " + System.getProperty("java.version"));
System.out.println("------------------------------------------------------------");
}
@ -233,10 +233,10 @@ public abstract class BaseApp {
} else {
System.exit(1);
}
} catch (Exception e) {
ourLog.error("Error during execution: ", e);
} catch (Throwable t) {
ourLog.error("Error during execution: ", t);
if ("true".equals(System.getProperty("test"))) {
throw new CommandFailureException("Error: " + e.toString(), e);
throw new CommandFailureException("Error: " + t.toString(), t);
} else {
System.exit(1);
}

View File

@ -30,7 +30,7 @@ public class CommandFailureException extends Error {
super(theMessage);
}
public CommandFailureException(String theString, Exception theCause) {
public CommandFailureException(String theString, Throwable theCause) {
super(theString, theCause);
}

View File

@ -27,8 +27,8 @@ import ca.uhn.fhir.parser.LenientErrorHandler;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.SingleValidationMessage;
import ca.uhn.fhir.validation.ValidationResult;
import com.helger.commons.io.file.FileHelper;
import com.google.common.base.Charsets;
import com.phloc.commons.io.file.FileUtils;
import org.apache.commons.cli.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.text.WordUtils;
@ -80,6 +80,7 @@ public class ValidateCommand extends BaseCommand {
addOptionalOption(retVal, "x", "xsd", false, "Validate using Schemas");
addOptionalOption(retVal, "s", "sch", false, "Validate using Schematrons");
addOptionalOption(retVal, "e", "encoding","encoding", "File encoding (default is UTF-8)");
return retVal;
}
@ -119,7 +120,7 @@ public class ValidateCommand extends BaseCommand {
} catch (IOException e) {
throw new CommandFailureException(e);
}
ourLog.info("Fully read - Size is {}", FileUtils.getFileSizeDisplay(contents.length()));
ourLog.info("Fully read - Size is {}", FileHelper.getFileSizeDisplay(contents.length()));
}
ca.uhn.fhir.rest.api.EncodingEnum enc = ca.uhn.fhir.rest.api.EncodingEnum.detectEncodingNoDefault(defaultString(contents));

View File

@ -132,8 +132,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>

View File

@ -217,8 +217,8 @@
<artifactId>thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>
@ -227,8 +227,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>

View File

@ -78,8 +78,8 @@
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>
@ -88,8 +88,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>

View File

@ -123,11 +123,6 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.ttddyy</groupId>
<artifactId>datasource-proxy</artifactId>
@ -146,8 +141,8 @@
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
@ -157,8 +152,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>
@ -468,6 +463,11 @@
<artifactId>greenmail-spring</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
@ -566,19 +566,9 @@
as JDK9 no longer includes them by default
-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb_api_version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb_core_version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb_core_version}</version>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb_runtime_version}</version>
</dependency>
</dependencies>
</plugin>

View File

@ -73,7 +73,10 @@ import org.hl7.fhir.r4.model.BaseResource;
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.Reference;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
@ -100,7 +103,7 @@ import static org.apache.commons.lang3.StringUtils.*;
@SuppressWarnings("WeakerAccess")
@Repository
public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao, ApplicationContextAware {
public static final long INDEX_STATUS_INDEXED = 1L;
public static final long INDEX_STATUS_INDEXING_FAILED = 2L;
@ -186,9 +189,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
@Autowired
private PlatformTransactionManager myPlatformTransactionManager;
@Autowired
private List<IFhirResourceDao<?>> myResourceDaos;
private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> myResourceTypeToDao;
@Autowired
private ISearchDao mySearchDao;
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
@ -200,6 +200,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
private ISearchResultDao mySearchResultDao;
@Autowired
private IResourceIndexedCompositeStringUniqueDao myResourceIndexedCompositeStringUniqueDao;
private ApplicationContext myApplicationContext;
private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> myResourceTypeToDao;
protected void clearRequestAsProcessingSubRequest(ServletRequestDetails theRequestDetails) {
if (theRequestDetails != null) {
@ -695,6 +697,29 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return retVal;
}
@SuppressWarnings("unchecked")
public <R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType) {
if (myResourceTypeToDao == null) {
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<>();
Map<String, IFhirResourceDao> daos = myApplicationContext.getBeansOfType(IFhirResourceDao.class, false, false);
for (IFhirResourceDao<?> next : daos.values()) {
theResourceTypeToDao.put(next.getResourceType(), next);
}
if (this instanceof IFhirResourceDao<?>) {
IFhirResourceDao<?> thiz = (IFhirResourceDao<?>) this;
theResourceTypeToDao.put(thiz.getResourceType(), thiz);
}
myResourceTypeToDao = theResourceTypeToDao;
}
IFhirResourceDao<R> dao = (IFhirResourceDao<R>) myResourceTypeToDao.get(theType);
return dao;
}
protected Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource);
}
@ -896,6 +921,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return myConfig;
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
public void setConfig(DaoConfig theConfig) {
myConfig = theConfig;
}
@ -922,26 +952,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
}
}
@SuppressWarnings("unchecked")
public <R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType) {
if (myResourceTypeToDao == null) {
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<>();
for (IFhirResourceDao<?> next : myResourceDaos) {
theResourceTypeToDao.put(next.getResourceType(), next);
}
if (this instanceof IFhirResourceDao<?>) {
IFhirResourceDao<?> thiz = (IFhirResourceDao<?>) this;
theResourceTypeToDao.put(thiz.getResourceType(), thiz);
}
myResourceTypeToDao = theResourceTypeToDao;
}
IFhirResourceDao<R> dao = (IFhirResourceDao<R>) myResourceTypeToDao.get(theType);
return dao;
}
public IResourceIndexedCompositeStringUniqueDao getResourceIndexedCompositeStringUniqueDao() {
return myResourceIndexedCompositeStringUniqueDao;
}

View File

@ -159,7 +159,7 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
return doExpunge(null, null, null, theExpungeOptions);
}
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
@Transactional(propagation = Propagation.REQUIRED)
@Override
public Map<String, Long> getResourceCounts() {
Map<String, Long> retVal = new HashMap<>();
@ -172,7 +172,7 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
return retVal;
}
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
@Transactional(propagation = Propagation.SUPPORTS)
@Nullable
@Override
public Map<String, Long> getResourceCountsFromCache() {
@ -265,7 +265,7 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
}
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Transactional(propagation = Propagation.NEVER)
public Integer performReindexingPass(final Integer theCount) {
if (!myReindexLock.tryLock()) {
return null;

View File

@ -32,7 +32,10 @@ import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.PostConstruct;
@ -40,7 +43,7 @@ import java.util.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implements ISearchParamRegistry {
public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implements ISearchParamRegistry, ApplicationContextAware {
private static final int MAX_MANAGED_PARAM_COUNT = 10000;
private static final Logger ourLog = LoggerFactory.getLogger(BaseSearchParamRegistry.class);
@ -49,12 +52,12 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
private volatile Map<String, Map<Set<String>, List<JpaRuntimeSearchParam>>> myActiveParamNamesToUniqueSearchParams = Collections.emptyMap();
@Autowired
private FhirContext myCtx;
@Autowired
private Collection<IFhirResourceDao<?>> myDaos;
private Collection<IFhirResourceDao<?>> myResourceDaos;
private volatile Map<String, Map<String, RuntimeSearchParam>> myActiveSearchParams;
@Autowired
private DaoConfig myDaoConfig;
private volatile long myLastRefresh;
private ApplicationContext myApplicationContext;
public BaseSearchParamRegistry() {
super();
@ -212,7 +215,13 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
public void postConstruct() {
Map<String, Map<String, RuntimeSearchParam>> resourceNameToSearchParams = new HashMap<>();
for (IFhirResourceDao<?> nextDao : myDaos) {
myResourceDaos = new ArrayList<>();
Map<String, IFhirResourceDao> daos = myApplicationContext.getBeansOfType(IFhirResourceDao.class, false, false);
for (IFhirResourceDao next : daos.values()) {
myResourceDaos.add(next);
}
for (IFhirResourceDao<?> nextDao : myResourceDaos) {
RuntimeResourceDefinition nextResDef = myCtx.getResourceDefinition(nextDao.getResourceType());
String nextResourceName = nextResDef.getName();
HashMap<String, RuntimeSearchParam> nameToParam = new HashMap<>();
@ -321,6 +330,11 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
refreshCacheIfNecessary();
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
protected abstract RuntimeSearchParam toRuntimeSp(SP theNextSp);

View File

@ -33,6 +33,8 @@ import ca.uhn.fhir.model.primitive.CodeDt;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
@ -58,6 +60,7 @@ public class FhirResourceDaoSearchParameterDstu2 extends FhirResourceDaoDstu2<Se
*/
@Override
@Scheduled(fixedDelay = DateUtils.MILLIS_PER_MINUTE)
@Transactional(propagation = Propagation.NEVER)
public void performReindexingPass() {
if (getConfig().isSchedulingDisabled()) {
return;

View File

@ -68,6 +68,7 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.TypedQuery;
@ -103,15 +104,20 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
Bundle subRequestBundle = new Bundle();
subRequestBundle.setType(BundleTypeEnum.TRANSACTION);
subRequestBundle.addEntry(nextRequestEntry);
Bundle subResponseBundle = transaction((ServletRequestDetails) theRequestDetails, subRequestBundle, "Batch sub-request");
return subResponseBundle;
return transaction((ServletRequestDetails) theRequestDetails, subRequestBundle, "Batch sub-request");
}
};
BaseServerResponseException caughtEx;
try {
Bundle nextResponseBundle = txTemplate.execute(callback);
Bundle nextResponseBundle;
if (nextRequestEntry.getRequest().getMethodElement().getValueAsEnum() == HTTPVerbEnum.GET) {
// Don't process GETs in a transaction because they'll
// create their own
nextResponseBundle = callback.doInTransaction(null);
} else {
nextResponseBundle = txTemplate.execute(callback);
}
caughtEx = null;
Entry subResponseEntry = nextResponseBundle.getEntry().get(0);
@ -156,13 +162,17 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
return batch(theRequestDetails, theRequest);
}
if (transactionType == null) {
String message = "Transactiion Bundle did not specify valid Bundle.type, assuming " + BundleTypeEnum.TRANSACTION.getCode();
ourLog.warn(message);
transactionType = BundleTypeEnum.TRANSACTION;
return doTransaction(theRequestDetails, theRequest, theActionName, transactionType);
}
if (transactionType != BundleTypeEnum.TRANSACTION) {
throw new InvalidRequestException("Unable to process transaction where incoming Bundle.type = " + transactionType.getCode());
private Bundle doTransaction(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, BundleTypeEnum theTransactionType) {
if (theTransactionType == null) {
String message = "Transaction Bundle did not specify valid Bundle.type, assuming " + BundleTypeEnum.TRANSACTION.getCode();
ourLog.warn(message);
theTransactionType = BundleTypeEnum.TRANSACTION;
}
if (theTransactionType != BundleTypeEnum.TRANSACTION) {
throw new InvalidRequestException("Unable to process transaction where incoming Bundle.type = " + theTransactionType.getCode());
}
ourLog.info("Beginning {} with {} resources", theActionName, theRequest.getEntry().size());
@ -186,7 +196,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
*/
Bundle response = new Bundle();
List<Entry> getEntries = new ArrayList<Entry>();
IdentityHashMap<Entry, Integer> originalRequestOrder = new IdentityHashMap<Bundle.Entry, Integer>();
IdentityHashMap<Entry, Integer> originalRequestOrder = new IdentityHashMap<Entry, Integer>();
for (int i = 0; i < theRequest.getEntry().size(); i++) {
originalRequestOrder.put(theRequest.getEntry().get(i), i);
response.addEntry();
@ -203,225 +213,13 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
Set<ResourceTable> updatedEntities = new HashSet<>();
/*
* Loop through the request and process any entries of type
* PUT, POST or DELETE
* Handle: GET/PUT/POST
*/
for (int i = 0; i < theRequest.getEntry().size(); i++) {
if (i % 100 == 0) {
ourLog.debug("Processed {} non-GET entries out of {}", i, theRequest.getEntry().size());
}
Entry nextReqEntry = theRequest.getEntry().get(i);
IResource res = nextReqEntry.getResource();
IdDt nextResourceId = null;
if (res != null) {
nextResourceId = res.getId();
if (!nextResourceId.hasIdPart()) {
if (isNotBlank(nextReqEntry.getFullUrl())) {
nextResourceId = new IdDt(nextReqEntry.getFullUrl());
}
}
if (nextResourceId.hasIdPart() && nextResourceId.getIdPart().matches("[a-zA-Z]+\\:.*") && !isPlaceholder(nextResourceId)) {
throw new InvalidRequestException("Invalid placeholder ID found: " + nextResourceId.getIdPart() + " - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'");
}
if (nextResourceId.hasIdPart() && !nextResourceId.hasResourceType() && !isPlaceholder(nextResourceId)) {
nextResourceId = new IdDt(toResourceName(res.getClass()), nextResourceId.getIdPart());
res.setId(nextResourceId);
}
/*
* Ensure that the bundle doesn't have any duplicates, since this causes all kinds of weirdness
*/
if (isPlaceholder(nextResourceId)) {
if (!allIds.add(nextResourceId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextResourceId));
}
} else if (nextResourceId.hasResourceType() && nextResourceId.hasIdPart()) {
IdDt nextId = nextResourceId.toUnqualifiedVersionless();
if (!allIds.add(nextId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextId));
}
}
}
HTTPVerbEnum verb = nextReqEntry.getRequest().getMethodElement().getValueAsEnum();
if (verb == null) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionEntryHasInvalidVerb", nextReqEntry.getRequest().getMethod()));
}
String resourceType = res != null ? getContext().getResourceDefinition(res).getName() : null;
Entry nextRespEntry = response.getEntry().get(originalRequestOrder.get(nextReqEntry));
switch (verb) {
case POST: {
// CREATE
@SuppressWarnings("rawtypes")
IFhirResourceDao resourceDao = getDaoOrThrowException(res.getClass());
res.setId((String) null);
DaoMethodOutcome outcome;
outcome = resourceDao.create(res, nextReqEntry.getRequest().getIfNoneExist(), false, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(idSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res);
entriesToProcess.put(nextRespEntry, outcome.getEntity());
if (outcome.getCreated() == false) {
nonUpdatedEntities.add(outcome.getEntity());
}
break;
}
case DELETE: {
// DELETE
String url = extractTransactionUrlOrThrowException(nextReqEntry, verb);
UrlParts parts = UrlUtil.parseUrl(url);
ca.uhn.fhir.jpa.dao.IFhirResourceDao<? extends IBaseResource> dao = toDao(parts, verb.getCode(), url);
int status = Constants.STATUS_HTTP_204_NO_CONTENT;
if (parts.getResourceId() != null) {
DaoMethodOutcome outcome = dao.delete(new IdDt(parts.getResourceType(), parts.getResourceId()), deleteConflicts, theRequestDetails);
if (outcome.getEntity() != null) {
deletedResources.add(outcome.getId().toUnqualifiedVersionless());
entriesToProcess.put(nextRespEntry, outcome.getEntity());
}
} else {
DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(parts.getResourceType() + '?' + parts.getParams(), deleteConflicts, theRequestDetails);
List<ResourceTable> allDeleted = deleteOutcome.getDeletedEntities();
for (ResourceTable deleted : allDeleted) {
deletedResources.add(deleted.getIdDt().toUnqualifiedVersionless());
}
if (allDeleted.isEmpty()) {
status = Constants.STATUS_HTTP_404_NOT_FOUND;
}
}
nextRespEntry.getResponse().setStatus(toStatusString(status));
break;
}
case PUT: {
// UPDATE
@SuppressWarnings("rawtypes")
IFhirResourceDao resourceDao = getDaoOrThrowException(res.getClass());
DaoMethodOutcome outcome;
String url = extractTransactionUrlOrThrowException(nextReqEntry, verb);
UrlParts parts = UrlUtil.parseUrl(url);
if (isNotBlank(parts.getResourceId())) {
res.setId(new IdDt(parts.getResourceType(), parts.getResourceId()));
outcome = resourceDao.update(res, null, false, theRequestDetails);
} else {
res.setId((String) null);
outcome = resourceDao.update(res, parts.getResourceType() + '?' + parts.getParams(), false, theRequestDetails);
}
if (outcome.getCreated() == Boolean.FALSE) {
updatedEntities.add(outcome.getEntity());
}
handleTransactionCreateOrUpdateOutcome(idSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res);
entriesToProcess.put(nextRespEntry, outcome.getEntity());
break;
}
case GET:
break;
}
}
/*
* Make sure that there are no conflicts from deletions. E.g. we can't delete something
* if something else has a reference to it.. Unless the thing that has a reference to it
* was also deleted as a part of this transaction, which is why we check this now at the
* end.
*/
deleteConflicts.removeIf(next -> deletedResources.contains(next.getTargetId().toVersionless()));
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
/*
* Perform ID substitutions and then index each resource we have saved
*/
FhirTerser terser = getContext().newTerser();
for (DaoMethodOutcome nextOutcome : idToPersistedOutcome.values()) {
IResource nextResource = (IResource) nextOutcome.getResource();
if (nextResource == null) {
continue;
}
// References
List<BaseResourceReferenceDt> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt nextRef : allRefs) {
IdDt nextId = nextRef.getReference();
if (!nextId.hasIdPart()) {
continue;
}
if (idSubstitutions.containsKey(nextId)) {
IdDt newId = idSubstitutions.get(nextId);
ourLog.debug(" * Replacing resource ref {} with {}", nextId, newId);
nextRef.setReference(newId);
} else {
ourLog.debug(" * Reference [{}] does not exist in bundle", nextId);
}
}
// URIs
List<UriDt> allUris = terser.getAllPopulatedChildElementsOfType(nextResource, UriDt.class);
for (UriDt nextRef : allUris) {
if (nextRef instanceof IIdType) {
continue; // No substitution on the resource ID itself!
}
IdDt nextUriString = new IdDt(nextRef.getValueAsString());
if (idSubstitutions.containsKey(nextUriString)) {
IdDt newId = idSubstitutions.get(nextUriString);
ourLog.debug(" * Replacing resource ref {} with {}", nextUriString, newId);
nextRef.setValue(newId.getValue());
} else {
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
}
}
InstantDt deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get(nextResource);
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
if (updatedEntities.contains(nextOutcome.getEntity())) {
updateInternal(theRequestDetails, nextResource, true, false, theRequestDetails, nextOutcome.getEntity(), nextResource.getIdElement(), nextOutcome.getPreviousResource());
} else if (!nonUpdatedEntities.contains(nextOutcome.getEntity())) {
updateEntity(theRequestDetails, nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, true, false, updateTime, false, true);
}
}
myEntityManager.flush();
/*
* Double check we didn't allow any duplicates we shouldn't have
*/
for (Entry nextEntry : theRequest.getEntry()) {
if (nextEntry.getRequest().getMethodElement().getValueAsEnum() == HTTPVerbEnum.POST) {
String matchUrl = nextEntry.getRequest().getIfNoneExist();
if (isNotBlank(matchUrl)) {
IFhirResourceDao<?> resourceDao = getDao(nextEntry.getResource().getClass());
Set<Long> val = resourceDao.processMatchUrl(matchUrl);
if (val.size() > 1) {
throw new InvalidRequestException(
"Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
}
}
}
}
for (IdDt next : allIds) {
IdDt replacement = idSubstitutions.get(next);
if (replacement == null) {
continue;
}
if (replacement.equals(next)) {
continue;
}
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
}
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
txTemplate.execute(t->{
handleTransactionWriteOperations(theRequestDetails, theRequest, theActionName, updateTime, allIds, idSubstitutions, idToPersistedOutcome, response, originalRequestOrder, deletedResources, deleteConflicts, entriesToProcess, nonUpdatedEntities, updatedEntities);
return null;
});
/*
* Loop through the request and process any entries of type GET
@ -447,7 +245,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
for (NameValuePair next : parameters) {
paramValues.put(next.getName(), next.getValue());
}
for (java.util.Map.Entry<String, Collection<String>> nextParamEntry : paramValues.asMap().entrySet()) {
for (Map.Entry<String, Collection<String>> nextParamEntry : paramValues.asMap().entrySet()) {
String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]);
requestDetails.addParameter(nextParamEntry.getKey(), nextValue);
}
@ -490,10 +288,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
}
ourLog.info("Flushing context after {}", theActionName);
myEntityManager.flush();
for (java.util.Map.Entry<Entry, ResourceTable> nextEntry : entriesToProcess.entrySet()) {
for (Map.Entry<Entry, ResourceTable> nextEntry : entriesToProcess.entrySet()) {
nextEntry.getKey().getResponse().setLocation(nextEntry.getValue().getIdDt().toUnqualified().getValue());
nextEntry.getKey().getResponse().setEtag(nextEntry.getValue().getIdDt().getVersionIdPart());
}
@ -507,6 +302,229 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
return response;
}
private void handleTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date theUpdateTime, Set<IdDt> theAllIds, Map<IdDt, IdDt> theIdSubstitutions, Map<IdDt, DaoMethodOutcome> theIdToPersistedOutcome, Bundle theResponse, IdentityHashMap<Entry, Integer> theOriginalRequestOrder, List<IIdType> theDeletedResources, List<DeleteConflict> theDeleteConflicts, Map<Entry, ResourceTable> theEntriesToProcess, Set<ResourceTable> theNonUpdatedEntities, Set<ResourceTable> theUpdatedEntities) {
/*
* Loop through the request and process any entries of type
* PUT, POST or DELETE
*/
for (int i = 0; i < theRequest.getEntry().size(); i++) {
if (i % 100 == 0) {
ourLog.debug("Processed {} non-GET entries out of {}", i, theRequest.getEntry().size());
}
Entry nextReqEntry = theRequest.getEntry().get(i);
IResource res = nextReqEntry.getResource();
IdDt nextResourceId = null;
if (res != null) {
nextResourceId = res.getId();
if (!nextResourceId.hasIdPart()) {
if (isNotBlank(nextReqEntry.getFullUrl())) {
nextResourceId = new IdDt(nextReqEntry.getFullUrl());
}
}
if (nextResourceId.hasIdPart() && nextResourceId.getIdPart().matches("[a-zA-Z]+\\:.*") && !isPlaceholder(nextResourceId)) {
throw new InvalidRequestException("Invalid placeholder ID found: " + nextResourceId.getIdPart() + " - Must be of the form 'urn:uuid:[uuid]' or 'urn:oid:[oid]'");
}
if (nextResourceId.hasIdPart() && !nextResourceId.hasResourceType() && !isPlaceholder(nextResourceId)) {
nextResourceId = new IdDt(toResourceName(res.getClass()), nextResourceId.getIdPart());
res.setId(nextResourceId);
}
/*
* Ensure that the bundle doesn't have any duplicates, since this causes all kinds of weirdness
*/
if (isPlaceholder(nextResourceId)) {
if (!theAllIds.add(nextResourceId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextResourceId));
}
} else if (nextResourceId.hasResourceType() && nextResourceId.hasIdPart()) {
IdDt nextId = nextResourceId.toUnqualifiedVersionless();
if (!theAllIds.add(nextId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextId));
}
}
}
HTTPVerbEnum verb = nextReqEntry.getRequest().getMethodElement().getValueAsEnum();
if (verb == null) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionEntryHasInvalidVerb", nextReqEntry.getRequest().getMethod()));
}
String resourceType = res != null ? getContext().getResourceDefinition(res).getName() : null;
Entry nextRespEntry = theResponse.getEntry().get(theOriginalRequestOrder.get(nextReqEntry));
switch (verb) {
case POST: {
// CREATE
@SuppressWarnings("rawtypes")
IFhirResourceDao resourceDao = getDaoOrThrowException(res.getClass());
res.setId((String) null);
DaoMethodOutcome outcome;
outcome = resourceDao.create(res, nextReqEntry.getRequest().getIfNoneExist(), false, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res);
theEntriesToProcess.put(nextRespEntry, outcome.getEntity());
if (outcome.getCreated() == false) {
theNonUpdatedEntities.add(outcome.getEntity());
}
break;
}
case DELETE: {
// DELETE
String url = extractTransactionUrlOrThrowException(nextReqEntry, verb);
UrlParts parts = UrlUtil.parseUrl(url);
IFhirResourceDao<? extends IBaseResource> dao = toDao(parts, verb.getCode(), url);
int status = Constants.STATUS_HTTP_204_NO_CONTENT;
if (parts.getResourceId() != null) {
DaoMethodOutcome outcome = dao.delete(new IdDt(parts.getResourceType(), parts.getResourceId()), theDeleteConflicts, theRequestDetails);
if (outcome.getEntity() != null) {
theDeletedResources.add(outcome.getId().toUnqualifiedVersionless());
theEntriesToProcess.put(nextRespEntry, outcome.getEntity());
}
} else {
DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(parts.getResourceType() + '?' + parts.getParams(), theDeleteConflicts, theRequestDetails);
List<ResourceTable> allDeleted = deleteOutcome.getDeletedEntities();
for (ResourceTable deleted : allDeleted) {
theDeletedResources.add(deleted.getIdDt().toUnqualifiedVersionless());
}
if (allDeleted.isEmpty()) {
status = Constants.STATUS_HTTP_404_NOT_FOUND;
}
}
nextRespEntry.getResponse().setStatus(toStatusString(status));
break;
}
case PUT: {
// UPDATE
@SuppressWarnings("rawtypes")
IFhirResourceDao resourceDao = getDaoOrThrowException(res.getClass());
DaoMethodOutcome outcome;
String url = extractTransactionUrlOrThrowException(nextReqEntry, verb);
UrlParts parts = UrlUtil.parseUrl(url);
if (isNotBlank(parts.getResourceId())) {
res.setId(new IdDt(parts.getResourceType(), parts.getResourceId()));
outcome = resourceDao.update(res, null, false, theRequestDetails);
} else {
res.setId((String) null);
outcome = resourceDao.update(res, parts.getResourceType() + '?' + parts.getParams(), false, theRequestDetails);
}
if (outcome.getCreated() == Boolean.FALSE) {
theUpdatedEntities.add(outcome.getEntity());
}
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res);
theEntriesToProcess.put(nextRespEntry, outcome.getEntity());
break;
}
case GET:
break;
}
}
/*
* Make sure that there are no conflicts from deletions. E.g. we can't delete something
* if something else has a reference to it.. Unless the thing that has a reference to it
* was also deleted as a part of this transaction, which is why we check this now at the
* end.
*/
theDeleteConflicts.removeIf(next -> theDeletedResources.contains(next.getTargetId().toVersionless()));
validateDeleteConflictsEmptyOrThrowException(theDeleteConflicts);
/*
* Perform ID substitutions and then index each resource we have saved
*/
FhirTerser terser = getContext().newTerser();
for (DaoMethodOutcome nextOutcome : theIdToPersistedOutcome.values()) {
IResource nextResource = (IResource) nextOutcome.getResource();
if (nextResource == null) {
continue;
}
// References
List<BaseResourceReferenceDt> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt nextRef : allRefs) {
IdDt nextId = nextRef.getReference();
if (!nextId.hasIdPart()) {
continue;
}
if (theIdSubstitutions.containsKey(nextId)) {
IdDt newId = theIdSubstitutions.get(nextId);
ourLog.debug(" * Replacing resource ref {} with {}", nextId, newId);
nextRef.setReference(newId);
} else {
ourLog.debug(" * Reference [{}] does not exist in bundle", nextId);
}
}
// URIs
List<UriDt> allUris = terser.getAllPopulatedChildElementsOfType(nextResource, UriDt.class);
for (UriDt nextRef : allUris) {
if (nextRef instanceof IIdType) {
continue; // No substitution on the resource ID itself!
}
IdDt nextUriString = new IdDt(nextRef.getValueAsString());
if (theIdSubstitutions.containsKey(nextUriString)) {
IdDt newId = theIdSubstitutions.get(nextUriString);
ourLog.debug(" * Replacing resource ref {} with {}", nextUriString, newId);
nextRef.setValue(newId.getValue());
} else {
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
}
}
InstantDt deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get(nextResource);
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
if (theUpdatedEntities.contains(nextOutcome.getEntity())) {
updateInternal(theRequestDetails, nextResource, true, false, theRequestDetails, nextOutcome.getEntity(), nextResource.getIdElement(), nextOutcome.getPreviousResource());
} else if (!theNonUpdatedEntities.contains(nextOutcome.getEntity())) {
updateEntity(theRequestDetails, nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, true, false, theUpdateTime, false, true);
}
}
myEntityManager.flush();
/*
* Double check we didn't allow any duplicates we shouldn't have
*/
for (Entry nextEntry : theRequest.getEntry()) {
if (nextEntry.getRequest().getMethodElement().getValueAsEnum() == HTTPVerbEnum.POST) {
String matchUrl = nextEntry.getRequest().getIfNoneExist();
if (isNotBlank(matchUrl)) {
IFhirResourceDao<?> resourceDao = getDao(nextEntry.getResource().getClass());
Set<Long> val = resourceDao.processMatchUrl(matchUrl);
if (val.size() > 1) {
throw new InvalidRequestException(
"Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
}
}
}
}
for (IdDt next : theAllIds) {
IdDt replacement = theIdSubstitutions.get(next);
if (replacement == null) {
continue;
}
if (replacement.equals(next)) {
continue;
}
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
}
}
private String extractTransactionUrlOrThrowException(Entry nextEntry, HTTPVerbEnum verb) {
String url = nextEntry.getRequest().getUrl();
if (isBlank(url)) {
@ -595,7 +613,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
return retVal;
}
@Transactional(propagation = Propagation.REQUIRED)
@Transactional(propagation = Propagation.NEVER)
@Override
public Bundle transaction(RequestDetails theRequestDetails, Bundle theRequest) {
if (theRequestDetails != null) {

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.dao;
* #L%
*/
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.Constants;
@ -41,6 +42,7 @@ import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hl7.fhir.dstu3.model.BaseResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
@ -50,12 +52,15 @@ import java.util.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class FulltextSearchSvcImpl extends BaseHapiFhirDao<IBaseResource> implements IFulltextSearchSvc {
public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FulltextSearchSvcImpl.class);
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager myEntityManager;
@Autowired
protected IForcedIdDao myForcedIdDao;
/**
* Constructor
*/

View File

@ -112,8 +112,6 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
TagList getAllResourceTags(RequestDetails theRequestDetails);
<R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType);
Class<T> getResourceType();
TagList getTags(IIdType theResourceId, RequestDetails theRequestDetails);

View File

@ -25,8 +25,6 @@ import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nullable;
import java.util.Date;
@ -40,12 +38,13 @@ public interface IFhirSystemDao<T, MT> extends IDao {
ExpungeOutcome expunge(ExpungeOptions theExpungeOptions);
@SuppressWarnings("unchecked")
<R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType);
Map<String, Long> getResourceCounts();
/**
*Returns a cached count of resources using a cache that regularly
* Returns a cached count of resources using a cache that regularly
* refreshes in the background. This method will never
*/
@Nullable

View File

@ -14,6 +14,8 @@ import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.dstu3.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@ -63,6 +65,7 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3<Se
*/
@Override
@Scheduled(fixedDelay = DateUtils.MILLIS_PER_MINUTE)
@Transactional(propagation = Propagation.NEVER)
public void performReindexingPass() {
if (getConfig().isSchedulingDisabled()) {
return;

View File

@ -11,9 +11,12 @@ import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;
import java.util.Collections;
@ -42,34 +45,25 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
*/
@Transactional(value = TxType.REQUIRED)
public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3 {
public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3, ApplicationContextAware {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaValidationSupportDstu3.class);
@Autowired
@Qualifier("myStructureDefinitionDaoDstu3")
private IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
@Autowired
@Qualifier("myValueSetDaoDstu3")
private IFhirResourceDao<ValueSet> myValueSetDao;
@Autowired
@Qualifier("myQuestionnaireDaoDstu3")
private IFhirResourceDao<Questionnaire> myQuestionnaireDao;
@Autowired
@Qualifier("myCodeSystemDaoDstu3")
private IFhirResourceDao<CodeSystem> myCodeSystemDao;
@Autowired
private FhirContext myDstu3Ctx;
private ApplicationContext myApplicationContext;
/**
* Constructor
*/
public JpaValidationSupportDstu3() {
super();
}
@Override
@Transactional(value = TxType.SUPPORTS)
public ValueSetExpansionComponent expandValueSet(FhirContext theCtx, ConceptSetComponent theInclude) {
@ -168,6 +162,19 @@ public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3 {
return false;
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
@PostConstruct
public void start() {
myStructureDefinitionDao = myApplicationContext.getBean("myStructureDefinitionDaoDstu3", IFhirResourceDao.class);
myValueSetDao = myApplicationContext.getBean("myValueSetDaoDstu3", IFhirResourceDao.class);
myQuestionnaireDao = myApplicationContext.getBean("myQuestionnaireDaoDstu3", IFhirResourceDao.class);
myCodeSystemDao = myApplicationContext.getBean("myCodeSystemDaoDstu3", IFhirResourceDao.class);
}
@Override
@Transactional(value = TxType.SUPPORTS)
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {

View File

@ -13,6 +13,8 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@ -57,6 +59,7 @@ public class FhirResourceDaoSearchParameterR4 extends FhirResourceDaoR4<SearchPa
*/
@Override
@Scheduled(fixedDelay = DateUtils.MILLIS_PER_MINUTE)
@Transactional(propagation = Propagation.NEVER)
public void performReindexingPass() {
if (getConfig().isSchedulingDisabled()) {
return;

View File

@ -11,9 +11,12 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;
import java.util.Collections;
@ -40,29 +43,22 @@ import java.util.List;
*/
@Transactional(value = TxType.REQUIRED)
public class JpaValidationSupportR4 implements IJpaValidationSupportR4 {
public class JpaValidationSupportR4 implements IJpaValidationSupportR4, ApplicationContextAware {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaValidationSupportR4.class);
@Autowired
@Qualifier("myStructureDefinitionDaoR4")
private IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
@Autowired
@Qualifier("myValueSetDaoR4")
private IFhirResourceDao<ValueSet> myValueSetDao;
@Autowired
@Qualifier("myQuestionnaireDaoR4")
private IFhirResourceDao<Questionnaire> myQuestionnaireDao;
@Autowired
@Qualifier("myCodeSystemDaoR4")
private IFhirResourceDao<CodeSystem> myCodeSystemDao;
@Autowired
private FhirContext myR4Ctx;
private ApplicationContext myApplicationContext;
/**
* Constructor
*/
public JpaValidationSupportR4() {
super();
}
@ -163,6 +159,19 @@ public class JpaValidationSupportR4 implements IJpaValidationSupportR4 {
return false;
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
@PostConstruct
public void start() {
myStructureDefinitionDao = myApplicationContext.getBean("myStructureDefinitionDaoR4", IFhirResourceDao.class);
myValueSetDao = myApplicationContext.getBean("myValueSetDaoR4", IFhirResourceDao.class);
myQuestionnaireDao = myApplicationContext.getBean("myQuestionnaireDaoR4", IFhirResourceDao.class);
myCodeSystemDao = myApplicationContext.getBean("myCodeSystemDaoR4", IFhirResourceDao.class);
}
@Override
@Transactional(value = TxType.SUPPORTS)
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {

View File

@ -77,7 +77,7 @@ public class StaleSearchDeletingSvcImpl implements IStaleSearchDeletingSvc {
}
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Transactional(propagation = Propagation.NEVER)
public void pollForStaleSearchesAndDeleteThem() {
if (!myDaoConfig.isExpireSearchResults()) {
return;
@ -127,7 +127,7 @@ public class StaleSearchDeletingSvcImpl implements IStaleSearchDeletingSvc {
}
@Scheduled(fixedDelay = DEFAULT_CUTOFF_SLACK)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Transactional(propagation = Propagation.NEVER)
@Override
public synchronized void schedulePollForStaleSearches() {
if (!myDaoConfig.isSchedulingDisabled()) {

View File

@ -67,7 +67,7 @@ public abstract class BaseSubscriptionDeliverySubscriber extends BaseSubscriptio
// can have placeholder IDs in them.
IIdType payloadId = msg.getPayloadId(getContext());
Class type = getContext().getResourceDefinition(payloadId.getResourceType()).getImplementingClass();
IFhirResourceDao dao = getSubscriptionDao().getDao(type);
IFhirResourceDao dao = getSubscriptionInterceptor().getDao(type);
IBaseResource loadedPayload;
try {
loadedPayload = dao.read(payloadId);

View File

@ -28,7 +28,6 @@ import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.provider.ServletSubRequestDetails;
import ca.uhn.fhir.jpa.util.JpaConstants;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
@ -37,6 +36,7 @@ import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.interceptor.ServerOperationInterceptorAdapter;
import ca.uhn.fhir.util.StopWatch;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
@ -99,6 +99,7 @@ public abstract class BaseSubscriptionInterceptor<S extends IBaseResource> exten
@Autowired
@Qualifier(BaseConfig.TASK_EXECUTOR_NAME)
private AsyncTaskExecutor myAsyncTaskExecutor;
private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> myResourceTypeToDao;
/**
* Constructor
@ -243,6 +244,26 @@ public abstract class BaseSubscriptionInterceptor<S extends IBaseResource> exten
public abstract Subscription.SubscriptionChannelType getChannelType();
@SuppressWarnings("unchecked")
public <R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType) {
if (myResourceTypeToDao == null) {
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<>();
for (IFhirResourceDao<?> next : myResourceDaos) {
theResourceTypeToDao.put(next.getResourceType(), next);
}
if (this instanceof IFhirResourceDao<?>) {
IFhirResourceDao<?> thiz = (IFhirResourceDao<?>) this;
theResourceTypeToDao.put(thiz.getResourceType(), thiz);
}
myResourceTypeToDao = theResourceTypeToDao;
}
IFhirResourceDao<R> dao = (IFhirResourceDao<R>) myResourceTypeToDao.get(theType);
return dao;
}
public SubscribableChannel getDeliveryChannel() {
return myDeliveryChannel;
}

View File

@ -140,7 +140,7 @@ public class SubscriptionCheckingSubscriber extends BaseSubscriptionSubscriber {
RequestDetails req = new ServletSubRequestDetails();
req.setSubRequest(true);
IFhirResourceDao<? extends IBaseResource> responseDao = getSubscriptionDao().getDao(responseResourceDef.getImplementingClass());
IFhirResourceDao<? extends IBaseResource> responseDao = getSubscriptionInterceptor().getDao(responseResourceDef.getImplementingClass());
responseCriteriaUrl.setLoadSynchronousUpTo(1);
IBundleProvider responseResults = responseDao.search(responseCriteriaUrl, req);

View File

@ -123,7 +123,7 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
IBaseResource payloadResource = theMsg.getPayload(getContext());
if (theSubscription.getRestHookDetails().isDeliverLatestVersion()) {
IFhirResourceDao dao = getSubscriptionDao().getDao(payloadResource.getClass());
IFhirResourceDao dao = getSubscriptionInterceptor().getDao(payloadResource.getClass());
try {
payloadResource = dao.read(payloadResource.getIdElement().toVersionless());
} catch (ResourceGoneException e) {

View File

@ -31,7 +31,6 @@ import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.ObjectUtil;
import ca.uhn.fhir.util.StopWatch;
@ -56,7 +55,10 @@ import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ValueSet;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.annotation.Scheduled;
@ -80,7 +82,7 @@ import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc {
public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc, ApplicationContextAware {
public static final int DEFAULT_FETCH_SIZE = 250;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiTerminologySvcImpl.class);
@ -123,14 +125,11 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
private boolean myProcessDeferred = true;
@Autowired
private PlatformTransactionManager myTransactionMgr;
@Autowired(required = false)
private IFhirResourceDaoCodeSystem<?, ?, ?> myCodeSystemResourceDao;
private Cache<TranslationQuery, List<TermConceptMapGroupElementTarget>> myTranslationCache;
private Cache<TranslationQuery, List<TermConceptMapGroupElement>> myTranslationWithReverseCache;
private int myFetchSize = DEFAULT_FETCH_SIZE;
private ApplicationContext myApplicationContext;
private void addCodeIfNotAlreadyAdded(String theCodeSystem, ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, TermConcept theConcept) {
if (theAddedCodes.add(theConcept.getCode())) {
@ -207,6 +206,32 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
.build();
}
/**
* This method is present only for unit tests, do not call from client code
*/
@VisibleForTesting
public void clearDeferred() {
myDeferredValueSets.clear();
myDeferredConceptMaps.clear();
myDeferredConcepts.clear();
}
/**
* This method is present only for unit tests, do not call from client code
*/
@VisibleForTesting
public void clearTranslationCache() {
myTranslationCache.invalidateAll();
}
/**
* This method is present only for unit tests, do not call from client code
*/
@VisibleForTesting()
public void clearTranslationWithReverseCache() {
myTranslationWithReverseCache.invalidateAll();
}
protected abstract IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource);
protected abstract void createOrUpdateConceptMap(ConceptMap theNextConceptMap);
@ -788,11 +813,21 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
@Override
public void setProcessDeferred(boolean theProcessDeferred) {
myProcessDeferred = theProcessDeferred;
}
@PostConstruct
public void start() {
myCodeSystemResourceDao = myApplicationContext.getBean(IFhirResourceDaoCodeSystem.class);
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void storeNewCodeSystemVersion(Long theCodeSystemResourcePid, String theSystemUri, String theSystemName, TermCodeSystemVersion theCodeSystemVersion) {
@ -1258,32 +1293,6 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
ourLastResultsFromTranslationWithReverseCache = false;
}
/**
* This method is present only for unit tests, do not call from client code
*/
@VisibleForTesting
public void clearTranslationCache() {
myTranslationCache.invalidateAll();
}
/**
* This method is present only for unit tests, do not call from client code
*/
@VisibleForTesting
public void clearDeferred() {
myDeferredValueSets.clear();
myDeferredConceptMaps.clear();
myDeferredConcepts.clear();
}
/**
* This method is present only for unit tests, do not call from client code
*/
@VisibleForTesting()
public void clearTranslationWithReverseCache() {
myTranslationWithReverseCache.invalidateAll();
}
/**
* This method is present only for unit tests, do not call from client code
*/

View File

@ -252,6 +252,7 @@ public class ConnectionWrapper implements Connection {
@Override
public void setReadOnly(boolean theReadOnly) throws SQLException {
ourLog.info("Setting connection as readonly");
myWrap.setReadOnly(theReadOnly);
}

View File

@ -4,8 +4,11 @@ import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import net.ttddyy.dsproxy.listener.ThreadQueryCountHolder;
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
@ -15,11 +18,35 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
@Configuration
@EnableTransactionManagement()
public class TestDstu2Config extends BaseJavaConfigDstu2 {
private static final Logger ourLog = LoggerFactory.getLogger(TestDstu2Config.class);
private static int ourMaxThreads;
static {
/*
* We use a randomized number of maximum threads in order to try
* and catch any potential deadlocks caused by database connection
* starvation
*/
ourMaxThreads = (int) (Math.random() * 6.0) + 1;
}
private Exception myLastStackTrace;
private String myLastStackTraceThreadName;
@Bean(name="maxDatabaseThreadsForTest")
public Integer getMaxThread(){
return ourMaxThreads;
}
@Bean()
public DaoConfig daoConfig() {
@ -28,21 +55,73 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
@Bean()
public DataSource dataSource() {
BasicDataSource retVal = new BasicDataSource();
BasicDataSource retVal = new BasicDataSource() {
@Override
public Connection getConnection() throws SQLException {
ConnectionWrapper retVal;
try {
retVal = new ConnectionWrapper(super.getConnection());
} catch (Exception e) {
ourLog.error("Exceeded maximum wait for connection", e);
logGetConnectionStackTrace();
// if ("true".equals(System.getStringProperty("ci"))) {
fail("Exceeded maximum wait for connection: " + e.toString());
// }
// System.exit(1);
retVal = null;
}
try {
throw new Exception();
} catch (Exception e) {
myLastStackTrace = e;
myLastStackTraceThreadName = Thread.currentThread().getName();
}
return retVal;
}
private void logGetConnectionStackTrace() {
StringBuilder b = new StringBuilder();
b.append("Last connection request stack trace:");
for (StackTraceElement next : myLastStackTrace.getStackTrace()) {
b.append("\n ");
b.append(next.getClassName());
b.append(".");
b.append(next.getMethodName());
b.append("(");
b.append(next.getFileName());
b.append(":");
b.append(next.getLineNumber());
b.append(")");
}
ourLog.info(b.toString());
ourLog.info("Last connection thread: {}", myLastStackTraceThreadName);
}
};
retVal.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
retVal.setUrl("jdbc:derby:memory:myUnitTestDBDstu2;create=true");
retVal.setMaxWaitMillis(10000);
retVal.setUsername("");
retVal.setPassword("");
return retVal;
}
@Bean()
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager retVal = new JpaTransactionManager();
retVal.setEntityManagerFactory(entityManagerFactory);
return retVal;
retVal.setMaxTotal(ourMaxThreads);
DataSource dataSource = ProxyDataSourceBuilder
.create(retVal)
// .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL")
.logSlowQueryBySlf4j(10, TimeUnit.SECONDS)
.countQuery(new ThreadQueryCountHolder())
.build();
return dataSource;
}
@Override
@Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
@ -60,7 +139,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
extraProperties.put("hibernate.dialect", "ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect");
extraProperties.put("hibernate.search.model_mapping", LuceneSearchMappingFactory.class.getName());
extraProperties.put("hibernate.search.default.directory_provider", "ram");
extraProperties.put("hibernate.search.lucene_version","LUCENE_CURRENT");
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");
return extraProperties;
}
@ -79,4 +158,11 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
return requestValidator;
}
@Bean()
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager retVal = new JpaTransactionManager();
retVal.setEntityManagerFactory(entityManagerFactory);
return retVal;
}
}

View File

@ -20,6 +20,10 @@ import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.jdbc.Work;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.instance.model.api.IBaseBundle;
@ -30,6 +34,8 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Rule;
import org.mockito.Mockito;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
@ -38,8 +44,11 @@ import org.springframework.transaction.support.TransactionTemplate;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import static ca.uhn.fhir.util.TestUtil.randomizeLocale;
import static org.junit.Assert.*;
@ -64,7 +73,7 @@ public abstract class BaseJpaTest {
protected IRequestOperationCallback myRequestOperationCallback = mock(IRequestOperationCallback.class);
@After
public final void afterPerformCleanup() {
public void afterPerformCleanup() {
BaseHapiFhirResourceDao.setDisableIncrementOnUpdateForUnitTest(false);
}
@ -78,6 +87,32 @@ public abstract class BaseJpaTest {
when(mySrd.getHeaders(eq(JpaConstants.HEADER_META_SNAPSHOT_MODE))).thenReturn(new ArrayList<>());
}
@After
public void afterValidateNoTransaction() {
PlatformTransactionManager txManager = getTxManager();
if (txManager != null) {
JpaTransactionManager hibernateTxManager = (JpaTransactionManager) txManager;
SessionFactory sessionFactory = (SessionFactory) hibernateTxManager.getEntityManagerFactory();
AtomicBoolean isReadOnly = new AtomicBoolean();
Session currentSession;
try {
currentSession = sessionFactory.getCurrentSession();
} catch (HibernateException e) {
currentSession = null;
}
if (currentSession != null) {
currentSession.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
isReadOnly.set(connection.isReadOnly());
}
});
assertFalse(isReadOnly.get());
}
}
}
@Before
public void beforeRandomizeLocale() {
randomizeLocale();

View File

@ -1,10 +1,9 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil;
import com.phloc.commons.compare.ReverseComparator;
import org.apache.commons.collections4.comparators.ReverseComparator;
import org.apache.commons.dbcp2.BasicDataSource;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;

View File

@ -44,11 +44,7 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.AopTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.EntityManager;
import java.io.IOException;

View File

@ -49,6 +49,7 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
protected static SubscriptionRestHookInterceptor ourRestHookSubscriptionInterceptor;
protected static DatabaseBackedPagingProvider ourPagingProvider;
protected static PlatformTransactionManager ourTxManager;
protected static Integer ourConnectionPoolSize;
public BaseResourceProviderDstu2Test() {
super();
@ -84,6 +85,7 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
ourRestServer.setServerConformanceProvider(confProvider);
ourPagingProvider = myAppCtx.getBean(DatabaseBackedPagingProvider.class);
ourConnectionPoolSize = myAppCtx.getBean("maxDatabaseThreadsForTest", Integer.class);
ourRestServer.setPagingProvider(ourPagingProvider);
Server server = new Server(ourPort);

View File

@ -1,41 +1,58 @@
package ca.uhn.fhir.jpa.provider;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.*;
import org.apache.http.entity.*;
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.*;
import org.junit.Test;
import org.springframework.test.util.AopTestUtils;
import com.google.common.base.Charsets;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.dstu2.composite.*;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.*;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.valueset.*;
import ca.uhn.fhir.model.primitive.*;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.util.*;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil;
import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
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.*;
import org.springframework.test.util.AopTestUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
@ -208,7 +225,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
*/
@Test
public void testCreateAndUpdateBinary() throws ClientProtocolException, Exception {
byte[] arr = { 1, 21, 74, 123, -44 };
byte[] arr = {1, 21, 74, 123, -44};
Binary binary = new Binary();
binary.setContent(arr);
binary.setContentType("dansk");
@ -934,7 +951,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
List<IIdType> actual;
StringAndListParam param;
ourLog.info("Pt1:{} Pt2:{} Obs1:{} Obs2:{} Obs3:{}", new Object[] { ptId1.getIdPart(), ptId2.getIdPart(), obsId1.getIdPart(), obsId2.getIdPart(), obsId3.getIdPart() });
ourLog.info("Pt1:{} Pt2:{} Obs1:{} Obs2:{} Obs3:{}", new Object[] {ptId1.getIdPart(), ptId2.getIdPart(), obsId1.getIdPart(), obsId2.getIdPart(), obsId3.getIdPart()});
param = new StringAndListParam();
param.addAnd(new StringOrListParam().addOr(new StringParam("obsvalue1")));
@ -1471,6 +1488,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
}
}
@Test
public void testPagingOverEverythingSet() throws InterruptedException {
Patient p = new Patient();
@ -1488,6 +1506,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
mySearchCoordinatorSvcRaw.setSyncSizeForUnitTests(10);
mySearchCoordinatorSvcRaw.setNeverUseLocalSearchForUnitTests(true);
StopWatch sw = new StopWatch();
ca.uhn.fhir.model.dstu2.resource.Bundle response = ourClient
.operation()
.onInstance(new IdDt(pid))
@ -1498,7 +1517,9 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
.execute();
assertEquals(10, response.getEntry().size());
assertEquals(null, response.getTotalElement().getValueAsString());
if (ourConnectionPoolSize > 1) {
assertEquals("Total should be null but was " + response.getTotalElement().getValueAsString() + " in " + sw.toString(), null, response.getTotalElement().getValueAsString());
}
assertThat(response.getLink("next").getUrl(), not(emptyString()));
// Load page 2
@ -1993,7 +2014,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
Bundle found = ourClient
.search()
.forResource(Patient.class)
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("urn:system:rpdstu2","testSearchWithInclude02"))
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("urn:system:rpdstu2", "testSearchWithInclude02"))
.include(Patient.INCLUDE_ORGANIZATION)
.prettyPrint()
.returnBundle(Bundle.class)
@ -2295,7 +2316,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
CloseableHttpResponse resp = ourHttpClient.execute(post);
try {
assertEquals(200, resp.getStatusLine().getStatusCode());
String output= IOUtils.toString(resp.getEntity().getContent());
String output = IOUtils.toString(resp.getEntity().getContent());
ourLog.info(output);
} finally {
resp.close();
@ -2387,7 +2408,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
response.close();
}
pt.addName().addFamily(methodName+"2");
pt.addName().addFamily(methodName + "2");
resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPut put = new HttpPut(ourServerBase + "/Patient?name=" + methodName);
put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));

View File

@ -11,14 +11,12 @@ import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.r4.model.UriType;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.util.AopTestUtils;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
@ -102,7 +100,6 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
.addTarget()
.setCode("34567");
runInTransaction(() -> {
try {
runInTransaction(() -> {
myConceptMapDao.create(conceptMap);
@ -111,7 +108,6 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
} catch (UnprocessableEntityException e) {
assertEquals("ConceptMap has no value for ConceptMap.url", e.getMessage());
}
});
}

View File

@ -187,8 +187,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>

View File

@ -138,8 +138,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>

View File

@ -55,8 +55,8 @@
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>
@ -65,8 +65,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
</dependency>
<dependency>

View File

@ -72,8 +72,8 @@
<artifactId>thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>
@ -82,8 +82,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
</dependency>
<dependency>
@ -197,8 +197,8 @@
com.ctc.wstx.api;version="4.4";resolution:=optional,
com.ctc.wstx.*;version="4.4";resolution:=optional,
com.google.*;resolution:=optional;-remove-attribute:=version,
com.phloc.commons;resolution:=optional;-remove-attribute:=version,
com.phloc.*;resolution:=optional;-remove-attribute:=version,
com.helger.commons;resolution:=optional;-remove-attribute:=version,
com.helger.*;resolution:=optional;-remove-attribute:=version,
javassist;-remove-attribute:=version,
javax.*;-remove-attribute:=version,
net.sf.saxon;resolution:=optional,

View File

@ -68,13 +68,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>

View File

@ -130,22 +130,6 @@
<artifactId>thymeleaf</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<scope>test</scope>
<exclusions><!--
<exclusion>
<artifactId>Saxon-HE</artifactId>
<groupId>net.sf.saxon</groupId>
</exclusion>-->
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<scope>test</scope>
</dependency>
<!-- UNIT TEST DEPENDENCIES -->
@ -208,6 +192,16 @@
<artifactId>spring-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<reporting>

View File

@ -11,6 +11,7 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import com.helger.commons.io.stream.StringInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.http.*;
@ -29,7 +30,6 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import com.google.common.base.Charsets;
import com.phloc.commons.io.streams.StringInputStream;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
@ -83,7 +83,7 @@ public class GenericClientDstu2_1Test {
return body;
}
private ArgumentCaptor<HttpUriRequest> prepareClientForSearchResponse() throws IOException, ClientProtocolException {
private ArgumentCaptor<HttpUriRequest> prepareClientForSearchResponse() throws IOException {
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
@ -92,7 +92,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -111,7 +111,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -149,7 +149,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -187,7 +187,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -225,7 +225,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -264,7 +264,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -303,7 +303,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -330,7 +330,7 @@ public class GenericClientDstu2_1Test {
}
@Test
public void testPatchInvalid() throws Exception {
public void testPatchInvalid() {
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
try {
@ -354,7 +354,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -398,7 +398,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -441,7 +441,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -505,7 +505,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -537,14 +537,14 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
if (myAnswerCount++ == 0) {
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
} else {
@ -586,14 +586,14 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
myAnswerCount++;
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8"));
}
@ -625,7 +625,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -652,7 +652,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -697,7 +697,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -737,7 +737,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -773,7 +773,7 @@ public class GenericClientDstu2_1Test {
private int myCount = 0;
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
final String respString;
if (myCount == 1 || myCount == 2) {
ourLog.info("Encoding patient");
@ -822,7 +822,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
final String respString;
if (myAnswerCount >= 1) {
ourLog.info("Encoding patient");
@ -872,7 +872,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
final String respString;
if (myAnswerCount >= 1) {
ourLog.info("Encoding patient");
@ -912,7 +912,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public StringInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public StringInputStream answer(InvocationOnMock theInvocation) {
return new StringInputStream("HELLO", Charsets.UTF_8);
}
});
@ -937,7 +937,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public StringInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public StringInputStream answer(InvocationOnMock theInvocation) {
return new StringInputStream("not implemented", Charsets.UTF_8);
}
});
@ -968,7 +968,7 @@ public class GenericClientDstu2_1Test {
.forResource(Patient.class)
.where(Patient.FAMILY.matches().value((String) null))
.and(Patient.BIRTHDATE.exactly().day((Date) null))
.and(Patient.GENDER.exactly().code((String) null))
.and(Patient.GENDER.exactly().code(null))
.and(Patient.ORGANIZATION.hasId((String) null))
.returnBundle(Bundle.class)
.execute();
@ -1019,7 +1019,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8"));
}
});
@ -1064,7 +1064,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8"));
}
});
@ -1121,7 +1121,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(null);
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1152,7 +1152,7 @@ public class GenericClientDstu2_1Test {
// when(myHttpResponse.getEntity().getContentType()).thenReturn(null);
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1179,7 +1179,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1286,7 +1286,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1405,7 +1405,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1497,7 +1497,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1564,7 +1564,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1601,7 +1601,7 @@ public class GenericClientDstu2_1Test {
}
@Test
public void testTransactionWithInvalidBody() throws Exception {
public void testTransactionWithInvalidBody() {
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
// Transaction
@ -1652,7 +1652,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1691,14 +1691,14 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
if (myAnswerCount++ == 0) {
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
} else {
@ -1739,14 +1739,14 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
myAnswerCount++;
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8"));
}
@ -1784,7 +1784,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1821,7 +1821,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1842,7 +1842,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1870,14 +1870,14 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] {};
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
}
});
@ -1910,7 +1910,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1948,7 +1948,7 @@ public class GenericClientDstu2_1Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});

View File

@ -103,13 +103,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope><!-- <exclusions> <exclusion> <artifactId>Saxon-HE</artifactId> <groupId>net.sf.saxon</groupId> </exclusion> </exclusions> -->
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>

View File

@ -28,7 +28,7 @@ import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.PortUtil;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil;
import com.phloc.commons.collections.iterate.ArrayEnumeration;
import com.helger.collection.iterate.ArrayEnumeration;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
@ -130,7 +130,7 @@ public class ResponseHighlightingInterceptorTest {
when(req.getHeaders(Constants.HEADER_ACCEPT)).thenAnswer(new Answer<Enumeration<String>>() {
@Override
public Enumeration<String> answer(InvocationOnMock theInvocation) throws Throwable {
return new ArrayEnumeration<String>("text/html,application/xhtml+xml,application/xml;q=0.9");
return new ArrayEnumeration<>("text/html,application/xhtml+xml,application/xml;q=0.9");
}
});
when(req.getHeader(Constants.HEADER_ORIGIN)).thenAnswer(new Answer<String>() {

View File

@ -217,13 +217,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>

View File

@ -11,6 +11,7 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import com.helger.commons.io.stream.StringInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.http.*;
@ -29,7 +30,6 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import com.google.common.base.Charsets;
import com.phloc.commons.io.streams.StringInputStream;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;

View File

@ -122,8 +122,8 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
@ -133,8 +133,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>

View File

@ -125,13 +125,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>
@ -192,11 +192,6 @@
<artifactId>spring-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<reporting>

View File

@ -17,6 +17,7 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import com.helger.commons.io.stream.StringInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.http.*;
@ -36,7 +37,6 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import com.google.common.base.Charsets;
import com.phloc.commons.io.streams.StringInputStream;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
@ -93,7 +93,7 @@ public class GenericClientR4Test {
return body;
}
private ArgumentCaptor<HttpUriRequest> prepareClientForSearchResponse() throws IOException, ClientProtocolException {
private ArgumentCaptor<HttpUriRequest> prepareClientForSearchResponse() throws IOException {
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
@ -102,7 +102,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -143,7 +143,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -187,7 +187,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -234,7 +234,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -278,7 +278,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -322,7 +322,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -366,7 +366,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -408,7 +408,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -472,7 +472,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -504,14 +504,14 @@ public class GenericClientR4Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
if (myAnswerCount++ == 0) {
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
} else {
@ -553,14 +553,14 @@ public class GenericClientR4Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
myAnswerCount++;
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8"));
}
@ -592,7 +592,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -619,7 +619,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -664,7 +664,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -704,7 +704,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -740,7 +740,7 @@ public class GenericClientR4Test {
private int myCount = 0;
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
final String respString;
if (myCount == 1 || myCount == 2) {
ourLog.info("Encoding patient");
@ -788,7 +788,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
final String respString;
if (myAnswerCount >= 1) {
ourLog.info("Encoding patient");
@ -828,7 +828,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public StringInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public StringInputStream answer(InvocationOnMock theInvocation) {
return new StringInputStream("HELLO", Charsets.UTF_8);
}
});
@ -853,7 +853,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public StringInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public StringInputStream answer(InvocationOnMock theInvocation) {
return new StringInputStream("not implemented", Charsets.UTF_8);
}
});
@ -884,7 +884,7 @@ public class GenericClientR4Test {
.forResource(Patient.class)
.where(Patient.FAMILY.matches().value((String) null))
.and(Patient.BIRTHDATE.exactly().day((Date) null))
.and(Patient.GENDER.exactly().code((String) null))
.and(Patient.GENDER.exactly().code(null))
.and(Patient.ORGANIZATION.hasId((String) null))
.returnBundle(Bundle.class)
.execute();
@ -915,7 +915,7 @@ public class GenericClientR4Test {
}
@Test
public void testPatchInvalid() throws Exception {
public void testPatchInvalid() {
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
try {
@ -941,7 +941,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -980,7 +980,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1019,7 +1019,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1057,7 +1057,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1095,7 +1095,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1133,7 +1133,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1180,7 +1180,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8"));
}
});
@ -1225,7 +1225,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8"));
}
});
@ -1282,7 +1282,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(null);
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1313,7 +1313,7 @@ public class GenericClientR4Test {
// when(myHttpResponse.getEntity().getContentType()).thenReturn(null);
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1331,7 +1331,7 @@ public class GenericClientR4Test {
}
@Test
public void testRevIncludeRecursive() throws ClientProtocolException, IOException {
public void testRevIncludeRecursive() throws IOException {
ArgumentCaptor<HttpUriRequest> capt = prepareClientForSearchResponse();
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
@ -1361,7 +1361,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1468,7 +1468,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1578,7 +1578,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1670,7 +1670,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1756,7 +1756,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});
@ -1793,7 +1793,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1830,7 +1830,7 @@ public class GenericClientR4Test {
}
@Test
public void testTransactionWithInvalidBody() throws Exception {
public void testTransactionWithInvalidBody() {
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
// Transaction
@ -1881,7 +1881,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -1920,14 +1920,14 @@ public class GenericClientR4Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
if (myAnswerCount++ == 0) {
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
} else {
@ -1968,14 +1968,14 @@ public class GenericClientR4Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
myAnswerCount++;
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8"));
}
@ -2013,7 +2013,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -2050,7 +2050,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -2071,7 +2071,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -2099,14 +2099,14 @@ public class GenericClientR4Test {
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
@Override
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
public Header[] answer(InvocationOnMock theInvocation) {
return new Header[] {};
}
});
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
}
});
@ -2139,7 +2139,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
@ -2177,7 +2177,7 @@ public class GenericClientR4Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
public ReaderInputStream answer(InvocationOnMock theInvocation) {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});

View File

@ -65,8 +65,8 @@
Schematron resource validation. Otherwise, they may be omitted.
-->
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<exclusions>
<exclusion>
<artifactId>Saxon-HE</artifactId>
@ -75,8 +75,8 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<version>4.3.3</version>
</dependency>

View File

@ -173,13 +173,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -89,9 +89,14 @@
<bundle dependency='true'>
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/${servicemix_xmlresolver_version}
</bundle>
<bundle dependency="true">mvn:org.apache.aries.spifly/org.apache.aries.spifly.dynamic.bundle/${aries_spifly_version}</bundle>
<bundle dependency='true'>mvn:com.google.code.findbugs/jsr305/${jsr305_version}</bundle>
<bundle>mvn:com.phloc/phloc-schematron/${phloc_schematron_version}</bundle>
<bundle>mvn:com.phloc/phloc-commons/${phloc_commons_version}</bundle>
<bundle dependency='true'>mvn:com.helger/ph-commons/${ph_commons_version}</bundle>
<bundle dependency='true'>mvn:com.helger/ph-collection/${ph_commons_version}</bundle>
<bundle dependency='true'>mvn:com.helger/ph-xml/${ph_commons_version}</bundle>
<bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jaxb-impl/${jaxb_bundle_version}</bundle>
<bundle dependency='true'>mvn:com.helger/ph-jaxb/${ph_commons_version}</bundle>
<bundle dependency='true'>mvn:com.helger/ph-schematron/${ph_schematron_version}</bundle>
</feature>
<feature name='hapi-fhir-validation' version='${project.version}' start-level='50'>

View File

@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@ -98,6 +98,7 @@
<version>${project.version}</version>
</dependency>
<!-- karaf test -->
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
@ -122,6 +123,12 @@
<version>${apache_karaf_version}</version>
<scope>test</scope>
<type>tar.gz</type>
<exclusions>
<exclusion>
<groupId>org.ops4j.pax.logging</groupId>
<artifactId>pax-logging-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>

View File

@ -0,0 +1,7 @@
package ca.uhn.fhir.tests.integration.karaf;
public class ValidationConstants {
public static final boolean SCHEMATRON_ENABLED = true;
}

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.tests.integration.karaf.ValidationConstants;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.SchemaBaseValidator;
import ca.uhn.fhir.validation.ValidationFailureException;
@ -85,7 +86,7 @@ public class Dstu2ResourceValidatorDstu2Test {
private FhirValidator createFhirValidator() {
FhirValidator val = ourCtx.newValidator();
val.setValidateAgainstStandardSchema(true);
val.setValidateAgainstStandardSchematron(true);
val.setValidateAgainstStandardSchematron(ValidationConstants.SCHEMATRON_ENABLED);
return val;
}
@ -156,7 +157,9 @@ public class Dstu2ResourceValidatorDstu2Test {
FhirValidator val = ourCtx.newValidator();
val.setValidateAgainstStandardSchema(true);
val.setValidateAgainstStandardSchematron(false);
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
val.validate(p);
@ -246,7 +249,9 @@ public class Dstu2ResourceValidatorDstu2Test {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
ValidationResult result = val.validateWithResult(messageString);
@ -299,7 +304,9 @@ public class Dstu2ResourceValidatorDstu2Test {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
ValidationResult result = val.validateWithResult(messageString);

View File

@ -6,19 +6,12 @@ import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.tests.integration.karaf.ValidationConstants;
import ca.uhn.fhir.validation.*;
import ca.uhn.fhir.validation.schematron.SchematronBaseValidator;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.dstu3.conformance.ProfileUtilities;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
@ -33,14 +26,10 @@ import java.util.Arrays;
import java.util.Date;
import java.util.List;
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_VALIDATION_DSTU3;
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.CoreOptions.when;
import static org.ops4j.pax.exam.CoreOptions.*;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
/**
@ -145,7 +134,9 @@ public class ResourceValidatorDstu3FeatureTest {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult output = val.validateWithResult(p);
@ -162,7 +153,9 @@ public class ResourceValidatorDstu3FeatureTest {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult output = val.validateWithResult(p);
@ -232,7 +225,9 @@ public class ResourceValidatorDstu3FeatureTest {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(q);
@ -273,7 +268,9 @@ public class ResourceValidatorDstu3FeatureTest {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(encoded);
@ -321,7 +318,9 @@ public class ResourceValidatorDstu3FeatureTest {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(messageString);
@ -374,7 +373,9 @@ public class ResourceValidatorDstu3FeatureTest {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
if (ValidationConstants.SCHEMATRON_ENABLED) {
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
}
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(messageString);

72
pom.xml
View File

@ -51,7 +51,20 @@
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!--
Snapshots should generally not be needed
<repository>
<id>oss-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
-->
</repositories>
<description>
@ -444,16 +457,17 @@
<!-- Dependency Versions -->
<apache_karaf_version>4.1.4</apache_karaf_version>
<aries_spifly_version>1.0.10</aries_spifly_version>
<caffeine_version>2.6.2</caffeine_version>
<commons_codec_version>1.10</commons_codec_version>
<commons_io_version>2.5</commons_io_version>
<commons_lang3_version>3.6</commons_lang3_version>
<derby_version>10.14.1.0</derby_version>
<derby_version>10.14.2.0</derby_version>
<error_prone_annotations_version>2.0.18</error_prone_annotations_version>
<guava_version>23.0</guava_version>
<gson_version>2.8.1</gson_version>
<jaxb_api_version>2.3.0</jaxb_api_version>
<jaxb_core_version>2.3.0</jaxb_core_version>
<jaxb_runtime_version>2.3.0</jaxb_runtime_version>
<jersey_version>2.25.1</jersey_version>
<jetty_version>9.4.8.v20171121</jetty_version>
<jsr305_version>3.0.2</jsr305_version>
@ -464,11 +478,12 @@
<hibernate_search_version>5.7.1.Final</hibernate_search_version>
<httpcore_version>4.4.6</httpcore_version>
<httpclient_version>4.5.3</httpclient_version>
<jaxb_bundle_version>2.2.11_1</jaxb_bundle_version>
<lucene_version>5.5.4</lucene_version>
<maven_assembly_plugin_version>2.5.3</maven_assembly_plugin_version>
<maven_license_plugin_version>1.8</maven_license_plugin_version>
<phloc_schematron_version>2.7.1</phloc_schematron_version>
<phloc_commons_version>4.4.11</phloc_commons_version>
<ph_schematron_version>5.0.4</ph_schematron_version>
<ph_commons_version>9.1.1</ph_commons_version>
<servicemix_saxon_version>9.5.1-5_1</servicemix_saxon_version>
<servicemix_xmlresolver_version>1.2_5</servicemix_xmlresolver_version>
<spring_version>5.0.3.RELEASE</spring_version>
@ -572,14 +587,14 @@
<version>23.0</version>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<version>${phloc_schematron_version}</version>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<version>${ph_schematron_version}</version>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<version>${phloc_commons_version}</version>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<version>${ph_commons_version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
@ -601,6 +616,11 @@
<artifactId>commons-codec</artifactId>
<version>${commons_codec_version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
@ -658,16 +678,6 @@
<artifactId>gson</artifactId>
<version>${gson_version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>${jaxb_core_version}</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>${jaxb_core_version}</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
@ -952,6 +962,11 @@
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb_runtime_version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
@ -1182,6 +1197,11 @@
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
@ -1251,7 +1271,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<version>2.20</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@ -1278,7 +1298,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<version>2.21.0</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<runOrder>random</runOrder>
@ -1509,14 +1529,20 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-java</id>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
<configuration>
<rules>
<requireMavenVersion>
<version>3.5</version>
</requireMavenVersion>
<requireJavaVersion>
<version>[1.8,)</version>
<message>
@ -1525,8 +1551,6 @@
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>

View File

@ -162,6 +162,11 @@
an unspecified error was thrown by the JPA server. An HTTP 409
(Conflict) with an informative error message is now thrown.
</action>
<action type="fix">
A bug in the JPA server's DSTU2 transaction processing routine caused it
to occasionally consume two database connections, which could lead to deadlocks
under heavy load. This has been fixed.
</action>
</release>
<release version="3.3.0" date="2018-03-29">
<action type="add">

View File

@ -33,6 +33,17 @@
<img src="./images/hapi-fhir-cli.png" alt="Basic screen shot" style="margin-left: 40px;"/>
</subsection>
<subsection name="Download and Installation - Mac/OSX">
<p>
hapi-fhir-cli is available as a <a href="https://brew.sh/">Homebrew</a> package
for Mac. It can be installed using the following command:
</p>
<code>brew install hapi-fhir-cli</code>
</subsection>
<subsection name="Troubleshooting">
<p>
<b>Note on Java version support:</b> The HAPI library is designed to

View File

@ -142,7 +142,7 @@
<p>
In order to use HAPI's Schematron support, a libaray called
<a href="https://code.google.com/p/phloc-schematron/">Phloc-Schematron</a>
<a href="https://github.com/phax/ph-schematron">Ph-Schematron</a>
is used, so this library must be added to your classpath (or Maven POM file, Gradle
file, etc.)
Note that this library is specified as an optional dependency

View File

@ -541,13 +541,14 @@ System.setProperty("javax.xml.stream.XMLEventFactory", "com.ctc.wstx.stax.WstxEv
</subsection>
<subsection name="Phloc-Schematron">
<subsection name="Ph-Schematron">
<p>
If you are using the
<a href="./doc_validation.html">Schematron Validatioon</a>
module, you will also need to include the Phloc library on your
classpath.
module, you will also need to include the Ph-Schematron library on your
classpath. (Note that prior to HAPI FHIR 3.4.0 we used Phloc-Schamtron
instead, but that lirary has been discontinued)
</p>
<p>
If you are using Maven, this library is not added by default (it is
@ -556,16 +557,15 @@ System.setProperty("javax.xml.stream.XMLEventFactory", "com.ctc.wstx.stax.WstxEv
dependencies to your project POM.xml
</p>
<source><![CDATA[<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-schematron</artifactId>
<version>${phloc_schematron_version}</version>
<groupId>com.helger</groupId>
<artifactId>ph-schematron</artifactId>
<version>${ph_schematron_version}</version>
</dependency>
<dependency>
<groupId>com.phloc</groupId>
<artifactId>phloc-commons</artifactId>
<version>${phloc_commons_version}</version>
<groupId>com.helger</groupId>
<artifactId>ph-commons</artifactId>
<version>${ph_commons_version}</version>
</dependency>]]></source>
</subsection>

View File

@ -26,7 +26,7 @@ public class ValidatorTest {
assertEquals("This parser is for FHIR version DSTU2 - Can not encode a structure for version DSTU3", e.getMessage());
}
// Phloc is not onthe classpath
// Ph-Schematron is not onthe classpath
assertTrue(val.isValidateAgainstStandardSchema());
assertFalse(val.isValidateAgainstStandardSchematron());
@ -34,7 +34,7 @@ public class ValidatorTest {
val.setValidateAgainstStandardSchematron(true);
fail();
} catch (IllegalArgumentException e) {
assertEquals("Phloc-schematron library not found on classpath, can not enable perform schematron validation", e.getMessage());
assertEquals("Ph-schematron library not found on classpath, can not enable perform schematron validation", e.getMessage());
}
}