diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementCompositeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementCompositeDefinition.java index 7015e0e6425..04960d0ef19 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementCompositeDefinition.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementCompositeDefinition.java @@ -99,7 +99,11 @@ public abstract class BaseRuntimeElementCompositeDefinition ext if (childOrder != null) { forcedOrder = new HashMap(); for (int i = 0; i < childOrder.names().length; i++) { - forcedOrder.put(childOrder.names()[i], i); + String nextName = childOrder.names()[i]; + if (nextName.endsWith("[x]")) { + nextName = nextName.substring(0, nextName.length() - 3); + } + forcedOrder.put(nextName, i); } } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/BaseParamWithPrefix.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/BaseParamWithPrefix.java index 37a5c4b0ef1..e3745f39d17 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/BaseParamWithPrefix.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/BaseParamWithPrefix.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.param; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -44,8 +44,13 @@ public abstract class BaseParamWithPrefix extends BaseParam String extractPrefixAndReturnRest(String theString) { int offset = 0; while (true) { - if (theString.length() == offset || Character.isDigit(theString.charAt(offset))) { + if (theString.length() == offset) { break; + } else { + char nextChar = theString.charAt(offset); + if (nextChar == '-' || Character.isDigit(nextChar)) { + break; + } } offset++; } @@ -60,7 +65,7 @@ public abstract class BaseParamWithPrefix extends BaseParam } /** - * @deprecated Use {@link #getPrefix() instead} + * @deprecated Use {@link #getPrefix()} instead */ @Deprecated public QuantityCompararatorEnum getComparator() { @@ -68,7 +73,7 @@ public abstract class BaseParamWithPrefix extends BaseParam if (prefix == null) { return null; } - + return QuantityCompararatorEnum.forCode(prefix.getDstu1Value()); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java index 07238019a2f..c4a4b30f442 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.util; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -41,24 +41,6 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; */ public class OperationOutcomeUtil { -// /** -// * Add an issue to an OperationOutcome -// * -// * @param theCtx -// * The fhir context -// * @param theOperationOutcome -// * The OO resource to add to -// * @param theSeverity -// * The severity (e.g. "error") -// * @param theDetails -// * The details string -// * @param theCode -// */ -// public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails, String theCode) { -// IBase issue = createIssue(theCtx, theOperationOutcome); -// populateDetails(theCtx, issue, theSeverity, theDetails, null, theCode); -// } - /** * Add an issue to an OperationOutcome * @@ -67,10 +49,10 @@ public class OperationOutcomeUtil { * @param theOperationOutcome * The OO resource to add to * @param theSeverity - * The severity (e.g. "error") + * The severity (fatal | error | warning | information) * @param theDetails * The details string - * @param theCode + * @param theCode */ public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails, String theLocation, String theCode) { IBase issue = createIssue(theCtx, theOperationOutcome); @@ -150,7 +132,7 @@ public class OperationOutcomeUtil { BaseRuntimeChildDefinition detailsChild; if (theCtx.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) { detailsChild = issueElement.getChildByName("diagnostics"); - + BaseRuntimeChildDefinition codeChild = issueElement.getChildByName("code"); IPrimitiveType codeElem = (IPrimitiveType) codeChild.getChildByName("code").newInstance(codeChild.getInstanceConstructorArguments()); codeElem.setValueAsString(theCode); @@ -158,7 +140,7 @@ public class OperationOutcomeUtil { } else { detailsChild = issueElement.getChildByName("details"); } - + BaseRuntimeElementDefinition stringDef = detailsChild.getChildByName(detailsChild.getElementName()); BaseRuntimeChildDefinition severityChild = issueElement.getChildByName("severity"); BaseRuntimeChildDefinition locationChild = issueElement.getChildByName("location"); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java index a57994fab72..3269b1924fd 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java @@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.Validate; import ca.uhn.fhir.context.ConfigurationException; -import ca.uhn.fhir.model.api.IFhirVersion; +import ca.uhn.fhir.context.support.IContextValidationSupport; import javassist.Modifier; public class ReflectionUtil { @@ -153,20 +153,35 @@ public class ReflectionUtil { } public static Object newInstanceOfFhirServerType(String theType) { + String errorMessage = "Unable to instantiate server framework. Please make sure that hapi-fhir-server library is on your classpath!"; + String wantedType = "ca.uhn.fhir.rest.api.server.IFhirVersionServer"; + Object fhirServerVersion = newInstanceOfType(theType, errorMessage, wantedType); + return fhirServerVersion; + } + + @SuppressWarnings("unchecked") + public static ca.uhn.fhir.context.support.IContextValidationSupport newInstanceOfFhirProfileValidationSupport( + String theType) { + String errorMessage = "Unable to instantiate validation support! Please make sure that hapi-fhir-validation and the appropriate structures JAR are on your classpath!"; + String wantedType = "ca.uhn.fhir.context.support.IContextValidationSupport"; + Object fhirServerVersion = newInstanceOfType(theType, errorMessage, wantedType); + return (IContextValidationSupport) fhirServerVersion; + } + + private static Object newInstanceOfType(String theType, String errorMessage, String wantedType) { Object fhirServerVersion = ourFhirServerVersions.get(theType); if (fhirServerVersion == null) { try { Class type = Class.forName(theType); - Class serverType = Class.forName("ca.uhn.fhir.rest.api.server.IFhirVersionServer"); + Class serverType = Class.forName(wantedType); Validate.isTrue(serverType.isAssignableFrom(type)); fhirServerVersion = type.newInstance(); } catch (Exception e) { - throw new ConfigurationException("Unable to instantiate server framework. Please make sure that hapi-fhir-server library is on your classpath!", e); + throw new ConfigurationException(errorMessage, e); } - + ourFhirServerVersions.put(theType, fhirServerVersion); } - return fhirServerVersion; } diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java b/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java index 2e70ad9ad9e..7e89d0d816f 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java +++ b/hapi-fhir-cli/hapi-fhir-cli-app/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java @@ -21,6 +21,7 @@ import org.springframework.web.context.ContextLoader; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.demo.ContextHolder; import ca.uhn.fhir.jpa.demo.FhirServerConfig; import ca.uhn.fhir.jpa.demo.FhirServerConfigDstu3; @@ -30,6 +31,7 @@ public class RunServerCommand extends BaseCommand { private static final String OPTION_DISABLE_REFERENTIAL_INTEGRITY = "disable-referential-integrity"; private static final String OPTION_LOWMEM = "lowmem"; private static final String OPTION_ALLOW_EXTERNAL_REFS = "allow-external-refs"; + private static final String OPTION_REUSE_SEARCH_RESULTS_MILLIS = "reuse-search-results-milliseconds"; private static final int DEFAULT_PORT = 8080; private static final String OPTION_P = "p"; @@ -51,6 +53,10 @@ public class RunServerCommand extends BaseCommand { options.addOption(null, OPTION_LOWMEM, false, "If this flag is set, the server will operate in low memory mode (some features disabled)"); options.addOption(null, OPTION_ALLOW_EXTERNAL_REFS, false, "If this flag is set, the server will allow resources to be persisted contaning external resource references"); options.addOption(null, OPTION_DISABLE_REFERENTIAL_INTEGRITY, false, "If this flag is set, the server will not enforce referential integrity"); + + Long defaultReuseSearchResults = DaoConfig.DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS; + String defaultReuseSearchResultsStr = defaultReuseSearchResults == null ? "off" : String.valueOf(defaultReuseSearchResults); + options.addOption(null, OPTION_REUSE_SEARCH_RESULTS_MILLIS, true, "The time in milliseconds within which the same results will be returned for multiple identical searches, or \"off\" (default is " + defaultReuseSearchResultsStr + ")"); return options; } @@ -58,7 +64,7 @@ public class RunServerCommand extends BaseCommand { try { return Integer.parseInt(theCommandLine.getOptionValue(opt, Integer.toString(defaultPort))); } catch (NumberFormatException e) { - throw new ParseException("Invalid value '" + theCommandLine.getOptionValue(opt) + " (must be numeric)"); + throw new ParseException("Invalid value '" + theCommandLine.getOptionValue(opt) + "' (must be numeric)"); } } @@ -81,6 +87,25 @@ public class RunServerCommand extends BaseCommand { ContextHolder.setDisableReferentialIntegrity(true); } + String reuseSearchResults = theCommandLine.getOptionValue(OPTION_REUSE_SEARCH_RESULTS_MILLIS); + if (reuseSearchResults != null) { + if (reuseSearchResults.equals("off")) { + ourLog.info("Server is configured to not reuse search results"); + ContextHolder.setReuseCachedSearchResultsForMillis(null); + } else { + try { + long reuseSearchResultsMillis = Long.parseLong(reuseSearchResults); + if (reuseSearchResultsMillis < 0) { + throw new NumberFormatException("expected a positive integer"); + } + ourLog.info("Server is configured to reuse search results for " + String.valueOf(reuseSearchResultsMillis) + " milliseconds"); + ContextHolder.setReuseCachedSearchResultsForMillis(reuseSearchResultsMillis); + } catch (NumberFormatException e) { + throw new ParseException("Invalid value '" + reuseSearchResults + "' (must be a positive integer)"); + } + } + } + ContextHolder.setCtx(getSpecVersionContext(theCommandLine)); ourLog.info("Preparing HAPI FHIR JPA server on port {}", myPort); diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java index 5675424db19..345b3259c9d 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java @@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.demo; import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.Validate; +import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.context.FhirContext; public class ContextHolder { @@ -11,6 +12,11 @@ public class ContextHolder { private static FhirContext ourCtx; private static boolean ourDisableReferentialIntegrity; private static String ourPath; + private static Long ourReuseSearchResultsMillis; + + static { + ourReuseSearchResultsMillis = DaoConfig.DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS; + } public static FhirContext getCtx() { Validate.notNull(ourPath, "Context not set"); @@ -53,4 +59,11 @@ public class ContextHolder { ourDisableReferentialIntegrity = theDisableReferentialIntegrity; } + public static void setReuseCachedSearchResultsForMillis(Long reuseSearchResultsMillis) { + ourReuseSearchResultsMillis = reuseSearchResultsMillis; + } + + public static Long getReuseCachedSearchResultsForMillis() { + return ourReuseSearchResultsMillis; + } } diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java index d2c3d9c83dd..ca979a3bbfd 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java @@ -150,7 +150,7 @@ public class JpaServerDemo extends RestfulServer { daoConfig.setAllowExternalReferences(ContextHolder.isAllowExternalRefs()); daoConfig.setEnforceReferentialIntegrityOnDelete(!ContextHolder.isDisableReferentialIntegrity()); daoConfig.setEnforceReferentialIntegrityOnWrite(!ContextHolder.isDisableReferentialIntegrity()); - + daoConfig.setReuseCachedSearchResultsForMillis(ContextHolder.getReuseCachedSearchResultsForMillis()); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java index 7c85bee83ef..dfdbf518ca1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java @@ -1,7 +1,7 @@ package ca.uhn.fhir.jpa.config.r4; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport; import org.hl7.fhir.r4.utils.IResourceValidator.BestPracticeWarningLevel; /* diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java index b9b1cb53bd7..700f7b5eee1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java @@ -105,6 +105,7 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2{ + public class IncludesIterator extends BaseIterator implements Iterator{ private Iterator myCurrentIterator; private int myCurrentOffset; @@ -2055,7 +2056,7 @@ public class SearchBuilder implements ISearchBuilder { } } - private final class QueryIterator implements Iterator { + private final class QueryIterator extends BaseIterator implements Iterator { private boolean myFirst = true; private IncludesIterator myIncludesIterator; @@ -2175,7 +2176,7 @@ public class SearchBuilder implements ISearchBuilder { } } - public class ScrollableResultsIterator implements Iterator { + public class ScrollableResultsIterator extends BaseIterator implements Iterator { private Long myNext; private ScrollableResults myScroll; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java index 3d334deeda4..51c96c17f0e 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ISearchDao.java @@ -3,6 +3,9 @@ package ca.uhn.fhir.jpa.dao.data; import java.util.Collection; import java.util.Date; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; + /* * #%L * HAPI FHIR JPA Server @@ -36,7 +39,7 @@ public interface ISearchDao extends JpaRepository { public Search findByUuid(@Param("uuid") String theUuid); @Query("SELECT s.myId FROM Search s WHERE s.mySearchLastReturned < :cutoff") - public Collection findWhereLastReturnedBefore(@Param("cutoff") Date theCutoff); + public Slice findWhereLastReturnedBefore(@Param("cutoff") Date theCutoff, Pageable thePage); // @Query("SELECT s FROM Search s WHERE s.myCreated < :cutoff") // public Collection findWhereCreatedBefore(@Param("cutoff") Date theCutoff); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java index 5742f78eb1d..85e00fcabfa 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java @@ -60,7 +60,7 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3() { @Override public Integer doInTransaction(TransactionStatus theStatus) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSubscriptionDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSubscriptionDstu3.java index 13fa39c5c74..2fe2d88aabb 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSubscriptionDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSubscriptionDstu3.java @@ -104,6 +104,8 @@ public class FhirResourceDaoSubscriptionDstu3 extends FhirResourceDaoDstu3 { for (final BundleEntryComponent nextRequestEntry : theRequest.getEntry()) { + BaseServerResponseExceptionHolder caughtEx = new BaseServerResponseExceptionHolder(); + TransactionCallback callback = new TransactionCallback() { @Override public Bundle doInTransaction(TransactionStatus theStatus) { @@ -97,13 +102,12 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { } }; - BaseServerResponseException caughtEx; try { - Bundle nextResponseBundle = txTemplate.execute(callback); - caughtEx = null; + Bundle nextResponseBundle = callback.doInTransaction(null); BundleEntryComponent subResponseEntry = nextResponseBundle.getEntry().get(0); resp.addEntry(subResponseEntry); + /* * If the individual entry didn't have a resource in its response, bring the sub-transaction's OperationOutcome across so the client can see it */ @@ -112,21 +116,19 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { } } catch (BaseServerResponseException e) { - caughtEx = e; + caughtEx.setException(e); } catch (Throwable t) { ourLog.error("Failure during BATCH sub transaction processing", t); - caughtEx = new InternalErrorException(t); + caughtEx.setException(new InternalErrorException(t)); } - if (caughtEx != null) { + if (caughtEx.getException() != null) { BundleEntryComponent nextEntry = resp.addEntry(); - OperationOutcome oo = new OperationOutcome(); - oo.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics(caughtEx.getMessage()); - nextEntry.setResource(oo); + populateEntryWithOperationOutcome(caughtEx.getException(), nextEntry); BundleEntryResponseComponent nextEntryResp = nextEntry.getResponse(); - nextEntryResp.setStatus(toStatusString(caughtEx.getStatusCode())); + nextEntryResp.setStatus(toStatusString(caughtEx.getException().getStatusCode())); } } @@ -137,8 +139,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { return resp; } - @SuppressWarnings("unchecked") - private Bundle doTransaction(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName) { + private Bundle doTransaction(final ServletRequestDetails theRequestDetails, final Bundle theRequest, final String theActionName) { BundleType transactionType = theRequest.getTypeElement().getValue(); if (transactionType == BundleType.BATCH) { return batch(theRequestDetails, theRequest); @@ -156,11 +157,11 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { ourLog.info("Beginning {} with {} resources", theActionName, theRequest.getEntry().size()); long start = System.currentTimeMillis(); - Date updateTime = new Date(); + final Date updateTime = new Date(); - Set allIds = new LinkedHashSet(); - Map idSubstitutions = new HashMap(); - Map idToPersistedOutcome = new HashMap(); + final Set allIds = new LinkedHashSet(); + final Map idSubstitutions = new HashMap(); + final Map idToPersistedOutcome = new HashMap(); // Do all entries have a verb? for (int i = 0; i < theRequest.getEntry().size(); i++) { @@ -181,9 +182,9 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { * are saved in a two-phase way in order to deal with interdependencies, and * we want the GET processing to use the final indexing state */ - Bundle response = new Bundle(); + final Bundle response = new Bundle(); List getEntries = new ArrayList(); - IdentityHashMap originalRequestOrder = new IdentityHashMap(); + final IdentityHashMap originalRequestOrder = new IdentityHashMap(); for (int i = 0; i < theRequest.getEntry().size(); i++) { originalRequestOrder.put(theRequest.getEntry().get(i), i); response.addEntry(); @@ -192,20 +193,13 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { } } - Set deletedResources = new HashSet(); - List deleteConflicts = new ArrayList(); - Map entriesToProcess = new IdentityHashMap(); - Set nonUpdatedEntities = new HashSet(); - Map> conditionalRequestUrls = new HashMap>(); - - List entries = new ArrayList(theRequest.getEntry()); - /* * See FhirSystemDaoDstu3Test#testTransactionWithPlaceholderIdInMatchUrl * Basically if the resource has a match URL that references a placeholder, * we try to handle the resource with the placeholder first. */ Set placeholderIds = new HashSet(); + final List entries = theRequest.getEntry(); for (BundleEntryComponent nextEntry : entries) { if (isNotBlank(nextEntry.getFullUrl()) && nextEntry.getFullUrl().startsWith(IdType.URN_PREFIX)) { placeholderIds.add(nextEntry.getFullUrl()); @@ -213,17 +207,124 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { } Collections.sort(entries, new TransactionSorter(placeholderIds)); + /* + * All of the write operations in the transaction (PUT, POST, etc.. basically anything + * except GET) are performed in their own database transaction before we do the reads. + * We do this because the reads (specifically the searches) often spawn their own + * secondary database transaction and if we allow that within the primary + * database transaction we can end up with deadlocks if the server is under + * heavy load with lots of concurrent transactions using all available + * database connections. + */ + TransactionTemplate txManager = new TransactionTemplate(myTxManager); + Map entriesToProcess = txManager.execute(new TransactionCallback>() { + @Override + public Map doInTransaction(TransactionStatus status) { + return doTransactionWriteOperations(theRequestDetails, theRequest, theActionName, updateTime, allIds, idSubstitutions, idToPersistedOutcome, response, originalRequestOrder, entries); + } + }); + for (Entry nextEntry : entriesToProcess.entrySet()) { + String responseLocation = nextEntry.getValue().getIdDt().toUnqualified().getValue(); + String responseEtag = nextEntry.getValue().getIdDt().getVersionIdPart(); + nextEntry.getKey().getResponse().setLocation(responseLocation); + nextEntry.getKey().getResponse().setEtag(responseEtag); + } + + /* + * Loop through the request and process any entries of type GET + */ + for (int i = 0; i < getEntries.size(); i++) { + BundleEntryComponent nextReqEntry = getEntries.get(i); + Integer originalOrder = originalRequestOrder.get(nextReqEntry); + BundleEntryComponent nextRespEntry = response.getEntry().get(originalOrder); + + ServletSubRequestDetails requestDetails = new ServletSubRequestDetails(); + requestDetails.setServletRequest(theRequestDetails.getServletRequest()); + requestDetails.setRequestType(RequestTypeEnum.GET); + requestDetails.setServer(theRequestDetails.getServer()); + + String url = extractTransactionUrlOrThrowException(nextReqEntry, HTTPVerb.GET); + + int qIndex = url.indexOf('?'); + ArrayListMultimap paramValues = ArrayListMultimap.create(); + requestDetails.setParameters(new HashMap()); + if (qIndex != -1) { + String params = url.substring(qIndex); + List parameters = translateMatchUrl(params); + for (NameValuePair next : parameters) { + paramValues.put(next.getName(), next.getValue()); + } + for (java.util.Map.Entry> nextParamEntry : paramValues.asMap().entrySet()) { + String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]); + requestDetails.getParameters().put(nextParamEntry.getKey(), nextValue); + } + url = url.substring(0, qIndex); + } + + requestDetails.setRequestPath(url); + requestDetails.setFhirServerBase(theRequestDetails.getFhirServerBase()); + + theRequestDetails.getServer().populateRequestDetailsFromRequestPath(requestDetails, url); + BaseMethodBinding method = theRequestDetails.getServer().determineResourceMethod(requestDetails, url); + if (method == null) { + throw new IllegalArgumentException("Unable to handle GET " + url); + } + + if (isNotBlank(nextReqEntry.getRequest().getIfMatch())) { + requestDetails.addHeader(Constants.HEADER_IF_MATCH, nextReqEntry.getRequest().getIfMatch()); + } + if (isNotBlank(nextReqEntry.getRequest().getIfNoneExist())) { + requestDetails.addHeader(Constants.HEADER_IF_NONE_EXIST, nextReqEntry.getRequest().getIfNoneExist()); + } + if (isNotBlank(nextReqEntry.getRequest().getIfNoneMatch())) { + requestDetails.addHeader(Constants.HEADER_IF_NONE_MATCH, nextReqEntry.getRequest().getIfNoneMatch()); + } + + Validate.isTrue(method instanceof BaseResourceReturningMethodBinding, "Unable to handle GET {}", url); + try { + IBaseResource resource = ((BaseResourceReturningMethodBinding) method).doInvokeServer(theRequestDetails.getServer(), requestDetails); + if (paramValues.containsKey(Constants.PARAM_SUMMARY) || paramValues.containsKey(Constants.PARAM_CONTENT)) { + resource = filterNestedBundle(requestDetails, resource); + } + nextRespEntry.setResource((Resource) resource); + nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_200_OK)); + } catch (NotModifiedException e) { + nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED)); + } catch (BaseServerResponseException e) { + ourLog.info("Failure processing transaction GET {}: {}", url, e.toString()); + nextRespEntry.getResponse().setStatus(toStatusString(e.getStatusCode())); + populateEntryWithOperationOutcome(e, nextRespEntry); + } + + } + + long delay = System.currentTimeMillis() - start; + ourLog.info(theActionName + " completed in {}ms", new Object[] { delay }); + + response.setType(BundleType.TRANSACTIONRESPONSE); + return response; + } + + @SuppressWarnings("unchecked") + private Map doTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date updateTime, Set allIds, + Map idSubstitutions, Map idToPersistedOutcome, Bundle response, IdentityHashMap originalRequestOrder, List theEntries) { + Set deletedResources = new HashSet(); + List deleteConflicts = new ArrayList(); + Map entriesToProcess = new IdentityHashMap(); + Set nonUpdatedEntities = new HashSet(); + Map> conditionalRequestUrls = new HashMap>(); + /* * Loop through the request and process any entries of type * PUT, POST or DELETE */ - for (int i = 0; i < entries.size(); i++) { + for (int i = 0; i < theEntries.size(); i++) { if (i % 100 == 0) { - ourLog.info("Processed {} non-GET entries out of {}", i, entries.size()); + ourLog.info("Processed {} non-GET entries out of {}", i, theEntries.size()); } - BundleEntryComponent nextReqEntry = entries.get(i); + BundleEntryComponent nextReqEntry = theEntries.get(i); Resource res = nextReqEntry.getResource(); IdType nextResourceId = null; if (res != null) { @@ -435,86 +536,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { } ourLog.info("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement); } - - /* - * Loop through the request and process any entries of type GET - */ - for (int i = 0; i < getEntries.size(); i++) { - BundleEntryComponent nextReqEntry = getEntries.get(i); - Integer originalOrder = originalRequestOrder.get(nextReqEntry); - BundleEntryComponent nextRespEntry = response.getEntry().get(originalOrder); - - ServletSubRequestDetails requestDetails = new ServletSubRequestDetails(); - requestDetails.setServletRequest(theRequestDetails.getServletRequest()); - requestDetails.setRequestType(RequestTypeEnum.GET); - requestDetails.setServer(theRequestDetails.getServer()); - - String url = extractTransactionUrlOrThrowException(nextReqEntry, HTTPVerb.GET); - - int qIndex = url.indexOf('?'); - ArrayListMultimap paramValues = ArrayListMultimap.create(); - requestDetails.setParameters(new HashMap()); - if (qIndex != -1) { - String params = url.substring(qIndex); - List parameters = translateMatchUrl(params); - for (NameValuePair next : parameters) { - paramValues.put(next.getName(), next.getValue()); - } - for (java.util.Map.Entry> nextParamEntry : paramValues.asMap().entrySet()) { - String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]); - requestDetails.getParameters().put(nextParamEntry.getKey(), nextValue); - } - url = url.substring(0, qIndex); - } - - requestDetails.setRequestPath(url); - requestDetails.setFhirServerBase(theRequestDetails.getFhirServerBase()); - - theRequestDetails.getServer().populateRequestDetailsFromRequestPath(requestDetails, url); - BaseMethodBinding method = theRequestDetails.getServer().determineResourceMethod(requestDetails, url); - if (method == null) { - throw new IllegalArgumentException("Unable to handle GET " + url); - } - - if (isNotBlank(nextReqEntry.getRequest().getIfMatch())) { - requestDetails.addHeader(Constants.HEADER_IF_MATCH, nextReqEntry.getRequest().getIfMatch()); - } - if (isNotBlank(nextReqEntry.getRequest().getIfNoneExist())) { - requestDetails.addHeader(Constants.HEADER_IF_NONE_EXIST, nextReqEntry.getRequest().getIfNoneExist()); - } - if (isNotBlank(nextReqEntry.getRequest().getIfNoneMatch())) { - requestDetails.addHeader(Constants.HEADER_IF_NONE_MATCH, nextReqEntry.getRequest().getIfNoneMatch()); - } - - if (method instanceof BaseResourceReturningMethodBinding) { - try { - IBaseResource resource = ((BaseResourceReturningMethodBinding) method).doInvokeServer(theRequestDetails.getServer(), requestDetails); - if (paramValues.containsKey(Constants.PARAM_SUMMARY) || paramValues.containsKey(Constants.PARAM_CONTENT)) { - resource = filterNestedBundle(requestDetails, resource); - } - nextRespEntry.setResource((Resource) resource); - nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_200_OK)); - } catch (NotModifiedException e) { - nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED)); - } - } else { - throw new IllegalArgumentException("Unable to handle GET " + url); - } - - } - - for (Entry nextEntry : entriesToProcess.entrySet()) { - String responseLocation = nextEntry.getValue().getIdDt().toUnqualified().getValue(); - String responseEtag = nextEntry.getValue().getIdDt().getVersionIdPart(); - nextEntry.getKey().getResponse().setLocation(responseLocation); - nextEntry.getKey().getResponse().setEtag(responseEtag); - } - - long delay = System.currentTimeMillis() - start; - ourLog.info(theActionName + " completed in {}ms", new Object[] { delay }); - - response.setType(BundleType.TRANSACTIONRESPONSE); - return response; + return entriesToProcess; } private String extractTransactionUrlOrThrowException(BundleEntryComponent nextEntry, HTTPVerb verb) { @@ -562,20 +584,10 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { return retVal; } - private String performIdSubstitutionsInMatchUrl(Map theIdSubstitutions, String theMatchUrl) { - String matchUrl = theMatchUrl; - if (isNotBlank(matchUrl)) { - for (Entry nextSubstitutionEntry : theIdSubstitutions.entrySet()) { - IdType nextTemporaryId = nextSubstitutionEntry.getKey(); - IdType nextReplacementId = nextSubstitutionEntry.getValue(); - String nextTemporaryIdPart = nextTemporaryId.getIdPart(); - String nextReplacementIdPart = nextReplacementId.getValueAsString(); - if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) { - matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart); - } - } - } - return matchUrl; + private void populateEntryWithOperationOutcome(BaseServerResponseException caughtEx, BundleEntryComponent nextEntry) { + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics(caughtEx.getMessage()); + nextEntry.getResponse().setOutcome(oo); } private ca.uhn.fhir.jpa.dao.IFhirResourceDao toDao(UrlParts theParts, String theVerb, String theUrl) { @@ -621,7 +633,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { return retVal; } - @Transactional(propagation = Propagation.REQUIRED) + @Transactional(propagation = Propagation.NEVER) @Override public Bundle transaction(RequestDetails theRequestDetails, Bundle theRequest) { if (theRequestDetails != null) { @@ -633,6 +645,26 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { return transaction((ServletRequestDetails) theRequestDetails, theRequest, actionName); } + + + private String performIdSubstitutionsInMatchUrl(Map theIdSubstitutions, String theMatchUrl) { + String matchUrl = theMatchUrl; + if (isNotBlank(matchUrl)) { + for (Entry nextSubstitutionEntry : theIdSubstitutions.entrySet()) { + IdType nextTemporaryId = nextSubstitutionEntry.getKey(); + IdType nextReplacementId = nextSubstitutionEntry.getValue(); + String nextTemporaryIdPart = nextTemporaryId.getIdPart(); + String nextReplacementIdPart = nextReplacementId.getValueAsString(); + if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) { + matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart); + } + } + } + return matchUrl; + } + + + private Bundle transaction(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName) { super.markRequestAsProcessingSubRequest(theRequestDetails); try { @@ -690,6 +722,20 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode)); } + private static class BaseServerResponseExceptionHolder + { + private BaseServerResponseException myException; + + public BaseServerResponseException getException() { + return myException; + } + + public void setException(BaseServerResponseException myException) { + this.myException = myException; + } + } + + //@formatter:off /** * Transaction Order, per the spec: * @@ -698,6 +744,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao { * Process any PUT interactions * Process any GET interactions */ + //@formatter:off public class TransactionSorter implements Comparator { private Set myPlaceholderIds; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java index 31eef51712e..21c8565a1e2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoCodeSystemR4.java @@ -24,8 +24,8 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.util.*; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport.CodeValidationResult; -import org.hl7.fhir.r4.hapi.validation.ValidationSupportChain; +import org.hl7.fhir.r4.hapi.ctx.ValidationSupportChain; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport.CodeValidationResult; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode; import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java index 2caea41526a..61c2d6ab803 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoValueSetR4.java @@ -27,8 +27,8 @@ import java.util.Collections; import java.util.List; import org.apache.commons.codec.binary.StringUtils; -import org.hl7.fhir.r4.hapi.validation.HapiWorkerContext; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport; +import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.Enumerations.PublicationStatus; import org.hl7.fhir.r4.model.ValueSet.*; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4.java index 1a71cab2d47..8c51cd6b050 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirSystemDaoR4.java @@ -19,13 +19,16 @@ package ca.uhn.fhir.jpa.dao.r4; * limitations under the License. * #L% */ -import static org.apache.commons.lang3.StringUtils.*; +import static org.apache.commons.lang3.StringUtils.defaultString; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.util.*; import java.util.Map.Entry; import javax.persistence.TypedQuery; +import org.apache.commons.lang3.Validate; import org.apache.http.NameValuePair; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.Bundle.*; @@ -85,6 +88,8 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { for (final BundleEntryComponent nextRequestEntry : theRequest.getEntry()) { + BaseServerResponseExceptionHolder caughtEx = new BaseServerResponseExceptionHolder(); + TransactionCallback callback = new TransactionCallback() { @Override public Bundle doInTransaction(TransactionStatus theStatus) { @@ -97,13 +102,12 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { } }; - BaseServerResponseException caughtEx; try { - Bundle nextResponseBundle = txTemplate.execute(callback); - caughtEx = null; + Bundle nextResponseBundle = callback.doInTransaction(null); BundleEntryComponent subResponseEntry = nextResponseBundle.getEntry().get(0); resp.addEntry(subResponseEntry); + /* * If the individual entry didn't have a resource in its response, bring the sub-transaction's OperationOutcome across so the client can see it */ @@ -112,21 +116,19 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { } } catch (BaseServerResponseException e) { - caughtEx = e; + caughtEx.setException(e); } catch (Throwable t) { ourLog.error("Failure during BATCH sub transaction processing", t); - caughtEx = new InternalErrorException(t); + caughtEx.setException(new InternalErrorException(t)); } - if (caughtEx != null) { + if (caughtEx.getException() != null) { BundleEntryComponent nextEntry = resp.addEntry(); - OperationOutcome oo = new OperationOutcome(); - oo.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics(caughtEx.getMessage()); - nextEntry.setResource(oo); + populateEntryWithOperationOutcome(caughtEx.getException(), nextEntry); BundleEntryResponseComponent nextEntryResp = nextEntry.getResponse(); - nextEntryResp.setStatus(toStatusString(caughtEx.getStatusCode())); + nextEntryResp.setStatus(toStatusString(caughtEx.getException().getStatusCode())); } } @@ -137,8 +139,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { return resp; } - @SuppressWarnings("unchecked") - private Bundle doTransaction(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName) { + private Bundle doTransaction(final ServletRequestDetails theRequestDetails, final Bundle theRequest, final String theActionName) { BundleType transactionType = theRequest.getTypeElement().getValue(); if (transactionType == BundleType.BATCH) { return batch(theRequestDetails, theRequest); @@ -156,11 +157,11 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { ourLog.info("Beginning {} with {} resources", theActionName, theRequest.getEntry().size()); long start = System.currentTimeMillis(); - Date updateTime = new Date(); + final Date updateTime = new Date(); - Set allIds = new LinkedHashSet(); - Map idSubstitutions = new HashMap(); - Map idToPersistedOutcome = new HashMap(); + final Set allIds = new LinkedHashSet(); + final Map idSubstitutions = new HashMap(); + final Map idToPersistedOutcome = new HashMap(); // Do all entries have a verb? for (int i = 0; i < theRequest.getEntry().size(); i++) { @@ -181,9 +182,9 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { * are saved in a two-phase way in order to deal with interdependencies, and * we want the GET processing to use the final indexing state */ - Bundle response = new Bundle(); + final Bundle response = new Bundle(); List getEntries = new ArrayList(); - IdentityHashMap originalRequestOrder = new IdentityHashMap(); + final IdentityHashMap originalRequestOrder = new IdentityHashMap(); for (int i = 0; i < theRequest.getEntry().size(); i++) { originalRequestOrder.put(theRequest.getEntry().get(i), i); response.addEntry(); @@ -192,20 +193,13 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { } } - Set deletedResources = new HashSet(); - List deleteConflicts = new ArrayList(); - Map entriesToProcess = new IdentityHashMap(); - Set nonUpdatedEntities = new HashSet(); - Map> conditionalRequestUrls = new HashMap>(); - - List entries = new ArrayList(theRequest.getEntry()); - /* * See FhirSystemDaoDstu3Test#testTransactionWithPlaceholderIdInMatchUrl * Basically if the resource has a match URL that references a placeholder, * we try to handle the resource with the placeholder first. */ Set placeholderIds = new HashSet(); + final List entries = theRequest.getEntry(); for (BundleEntryComponent nextEntry : entries) { if (isNotBlank(nextEntry.getFullUrl()) && nextEntry.getFullUrl().startsWith(IdType.URN_PREFIX)) { placeholderIds.add(nextEntry.getFullUrl()); @@ -213,17 +207,124 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { } Collections.sort(entries, new TransactionSorter(placeholderIds)); + /* + * All of the write operations in the transaction (PUT, POST, etc.. basically anything + * except GET) are performed in their own database transaction before we do the reads. + * We do this because the reads (specifically the searches) often spawn their own + * secondary database transaction and if we allow that within the primary + * database transaction we can end up with deadlocks if the server is under + * heavy load with lots of concurrent transactions using all available + * database connections. + */ + TransactionTemplate txManager = new TransactionTemplate(myTxManager); + Map entriesToProcess = txManager.execute(new TransactionCallback>() { + @Override + public Map doInTransaction(TransactionStatus status) { + return doTransactionWriteOperations(theRequestDetails, theRequest, theActionName, updateTime, allIds, idSubstitutions, idToPersistedOutcome, response, originalRequestOrder, entries); + } + }); + for (Entry nextEntry : entriesToProcess.entrySet()) { + String responseLocation = nextEntry.getValue().getIdDt().toUnqualified().getValue(); + String responseEtag = nextEntry.getValue().getIdDt().getVersionIdPart(); + nextEntry.getKey().getResponse().setLocation(responseLocation); + nextEntry.getKey().getResponse().setEtag(responseEtag); + } + + /* + * Loop through the request and process any entries of type GET + */ + for (int i = 0; i < getEntries.size(); i++) { + BundleEntryComponent nextReqEntry = getEntries.get(i); + Integer originalOrder = originalRequestOrder.get(nextReqEntry); + BundleEntryComponent nextRespEntry = response.getEntry().get(originalOrder); + + ServletSubRequestDetails requestDetails = new ServletSubRequestDetails(); + requestDetails.setServletRequest(theRequestDetails.getServletRequest()); + requestDetails.setRequestType(RequestTypeEnum.GET); + requestDetails.setServer(theRequestDetails.getServer()); + + String url = extractTransactionUrlOrThrowException(nextReqEntry, HTTPVerb.GET); + + int qIndex = url.indexOf('?'); + ArrayListMultimap paramValues = ArrayListMultimap.create(); + requestDetails.setParameters(new HashMap()); + if (qIndex != -1) { + String params = url.substring(qIndex); + List parameters = translateMatchUrl(params); + for (NameValuePair next : parameters) { + paramValues.put(next.getName(), next.getValue()); + } + for (java.util.Map.Entry> nextParamEntry : paramValues.asMap().entrySet()) { + String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]); + requestDetails.getParameters().put(nextParamEntry.getKey(), nextValue); + } + url = url.substring(0, qIndex); + } + + requestDetails.setRequestPath(url); + requestDetails.setFhirServerBase(theRequestDetails.getFhirServerBase()); + + theRequestDetails.getServer().populateRequestDetailsFromRequestPath(requestDetails, url); + BaseMethodBinding method = theRequestDetails.getServer().determineResourceMethod(requestDetails, url); + if (method == null) { + throw new IllegalArgumentException("Unable to handle GET " + url); + } + + if (isNotBlank(nextReqEntry.getRequest().getIfMatch())) { + requestDetails.addHeader(Constants.HEADER_IF_MATCH, nextReqEntry.getRequest().getIfMatch()); + } + if (isNotBlank(nextReqEntry.getRequest().getIfNoneExist())) { + requestDetails.addHeader(Constants.HEADER_IF_NONE_EXIST, nextReqEntry.getRequest().getIfNoneExist()); + } + if (isNotBlank(nextReqEntry.getRequest().getIfNoneMatch())) { + requestDetails.addHeader(Constants.HEADER_IF_NONE_MATCH, nextReqEntry.getRequest().getIfNoneMatch()); + } + + Validate.isTrue(method instanceof BaseResourceReturningMethodBinding, "Unable to handle GET {}", url); + try { + IBaseResource resource = ((BaseResourceReturningMethodBinding) method).doInvokeServer(theRequestDetails.getServer(), requestDetails); + if (paramValues.containsKey(Constants.PARAM_SUMMARY) || paramValues.containsKey(Constants.PARAM_CONTENT)) { + resource = filterNestedBundle(requestDetails, resource); + } + nextRespEntry.setResource((Resource) resource); + nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_200_OK)); + } catch (NotModifiedException e) { + nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED)); + } catch (BaseServerResponseException e) { + ourLog.info("Failure processing transaction GET {}: {}", url, e.toString()); + nextRespEntry.getResponse().setStatus(toStatusString(e.getStatusCode())); + populateEntryWithOperationOutcome(e, nextRespEntry); + } + + } + + long delay = System.currentTimeMillis() - start; + ourLog.info(theActionName + " completed in {}ms", new Object[] { delay }); + + response.setType(BundleType.TRANSACTIONRESPONSE); + return response; + } + + @SuppressWarnings("unchecked") + private Map doTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date updateTime, Set allIds, + Map idSubstitutions, Map idToPersistedOutcome, Bundle response, IdentityHashMap originalRequestOrder, List theEntries) { + Set deletedResources = new HashSet(); + List deleteConflicts = new ArrayList(); + Map entriesToProcess = new IdentityHashMap(); + Set nonUpdatedEntities = new HashSet(); + Map> conditionalRequestUrls = new HashMap>(); + /* * Loop through the request and process any entries of type * PUT, POST or DELETE */ - for (int i = 0; i < entries.size(); i++) { + for (int i = 0; i < theEntries.size(); i++) { if (i % 100 == 0) { - ourLog.info("Processed {} non-GET entries out of {}", i, entries.size()); + ourLog.info("Processed {} non-GET entries out of {}", i, theEntries.size()); } - BundleEntryComponent nextReqEntry = entries.get(i); + BundleEntryComponent nextReqEntry = theEntries.get(i); Resource res = nextReqEntry.getResource(); IdType nextResourceId = null; if (res != null) { @@ -435,86 +536,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { } ourLog.info("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement); } - - /* - * Loop through the request and process any entries of type GET - */ - for (int i = 0; i < getEntries.size(); i++) { - BundleEntryComponent nextReqEntry = getEntries.get(i); - Integer originalOrder = originalRequestOrder.get(nextReqEntry); - BundleEntryComponent nextRespEntry = response.getEntry().get(originalOrder); - - ServletSubRequestDetails requestDetails = new ServletSubRequestDetails(); - requestDetails.setServletRequest(theRequestDetails.getServletRequest()); - requestDetails.setRequestType(RequestTypeEnum.GET); - requestDetails.setServer(theRequestDetails.getServer()); - - String url = extractTransactionUrlOrThrowException(nextReqEntry, HTTPVerb.GET); - - int qIndex = url.indexOf('?'); - ArrayListMultimap paramValues = ArrayListMultimap.create(); - requestDetails.setParameters(new HashMap()); - if (qIndex != -1) { - String params = url.substring(qIndex); - List parameters = translateMatchUrl(params); - for (NameValuePair next : parameters) { - paramValues.put(next.getName(), next.getValue()); - } - for (java.util.Map.Entry> nextParamEntry : paramValues.asMap().entrySet()) { - String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]); - requestDetails.getParameters().put(nextParamEntry.getKey(), nextValue); - } - url = url.substring(0, qIndex); - } - - requestDetails.setRequestPath(url); - requestDetails.setFhirServerBase(theRequestDetails.getFhirServerBase()); - - theRequestDetails.getServer().populateRequestDetailsFromRequestPath(requestDetails, url); - BaseMethodBinding method = theRequestDetails.getServer().determineResourceMethod(requestDetails, url); - if (method == null) { - throw new IllegalArgumentException("Unable to handle GET " + url); - } - - if (isNotBlank(nextReqEntry.getRequest().getIfMatch())) { - requestDetails.addHeader(Constants.HEADER_IF_MATCH, nextReqEntry.getRequest().getIfMatch()); - } - if (isNotBlank(nextReqEntry.getRequest().getIfNoneExist())) { - requestDetails.addHeader(Constants.HEADER_IF_NONE_EXIST, nextReqEntry.getRequest().getIfNoneExist()); - } - if (isNotBlank(nextReqEntry.getRequest().getIfNoneMatch())) { - requestDetails.addHeader(Constants.HEADER_IF_NONE_MATCH, nextReqEntry.getRequest().getIfNoneMatch()); - } - - if (method instanceof BaseResourceReturningMethodBinding) { - try { - IBaseResource resource = ((BaseResourceReturningMethodBinding) method).doInvokeServer(theRequestDetails.getServer(), requestDetails); - if (paramValues.containsKey(Constants.PARAM_SUMMARY) || paramValues.containsKey(Constants.PARAM_CONTENT)) { - resource = filterNestedBundle(requestDetails, resource); - } - nextRespEntry.setResource((Resource) resource); - nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_200_OK)); - } catch (NotModifiedException e) { - nextRespEntry.getResponse().setStatus(toStatusString(Constants.STATUS_HTTP_304_NOT_MODIFIED)); - } - } else { - throw new IllegalArgumentException("Unable to handle GET " + url); - } - - } - - for (Entry nextEntry : entriesToProcess.entrySet()) { - String responseLocation = nextEntry.getValue().getIdDt().toUnqualified().getValue(); - String responseEtag = nextEntry.getValue().getIdDt().getVersionIdPart(); - nextEntry.getKey().getResponse().setLocation(responseLocation); - nextEntry.getKey().getResponse().setEtag(responseEtag); - } - - long delay = System.currentTimeMillis() - start; - ourLog.info(theActionName + " completed in {}ms", new Object[] { delay }); - - response.setType(BundleType.TRANSACTIONRESPONSE); - return response; + return entriesToProcess; } private String extractTransactionUrlOrThrowException(BundleEntryComponent nextEntry, HTTPVerb verb) { @@ -562,20 +584,10 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { return retVal; } - private String performIdSubstitutionsInMatchUrl(Map theIdSubstitutions, String theMatchUrl) { - String matchUrl = theMatchUrl; - if (isNotBlank(matchUrl)) { - for (Entry nextSubstitutionEntry : theIdSubstitutions.entrySet()) { - IdType nextTemporaryId = nextSubstitutionEntry.getKey(); - IdType nextReplacementId = nextSubstitutionEntry.getValue(); - String nextTemporaryIdPart = nextTemporaryId.getIdPart(); - String nextReplacementIdPart = nextReplacementId.getValueAsString(); - if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) { - matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart); - } - } - } - return matchUrl; + private void populateEntryWithOperationOutcome(BaseServerResponseException caughtEx, BundleEntryComponent nextEntry) { + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics(caughtEx.getMessage()); + nextEntry.getResponse().setOutcome(oo); } private ca.uhn.fhir.jpa.dao.IFhirResourceDao toDao(UrlParts theParts, String theVerb, String theUrl) { @@ -621,7 +633,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { return retVal; } - @Transactional(propagation = Propagation.REQUIRED) + @Transactional(propagation = Propagation.NEVER) @Override public Bundle transaction(RequestDetails theRequestDetails, Bundle theRequest) { if (theRequestDetails != null) { @@ -633,6 +645,26 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { return transaction((ServletRequestDetails) theRequestDetails, theRequest, actionName); } + + + private String performIdSubstitutionsInMatchUrl(Map theIdSubstitutions, String theMatchUrl) { + String matchUrl = theMatchUrl; + if (isNotBlank(matchUrl)) { + for (Entry nextSubstitutionEntry : theIdSubstitutions.entrySet()) { + IdType nextTemporaryId = nextSubstitutionEntry.getKey(); + IdType nextReplacementId = nextSubstitutionEntry.getValue(); + String nextTemporaryIdPart = nextTemporaryId.getIdPart(); + String nextReplacementIdPart = nextReplacementId.getValueAsString(); + if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) { + matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart); + } + } + } + return matchUrl; + } + + + private Bundle transaction(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName) { super.markRequestAsProcessingSubRequest(theRequestDetails); try { @@ -690,6 +722,20 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode)); } + private static class BaseServerResponseExceptionHolder + { + private BaseServerResponseException myException; + + public BaseServerResponseException getException() { + return myException; + } + + public void setException(BaseServerResponseException myException) { + this.myException = myException; + } + } + + //@formatter:off /** * Transaction Order, per the spec: * @@ -698,6 +744,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao { * Process any PUT interactions * Process any GET interactions */ + //@formatter:off public class TransactionSorter implements Comparator { private Set myPlaceholderIds; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/IJpaValidationSupportR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/IJpaValidationSupportR4.java index 01c3ef428f2..6447a9b8301 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/IJpaValidationSupportR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/IJpaValidationSupportR4.java @@ -1,6 +1,6 @@ package ca.uhn.fhir.jpa.dao.r4; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; /* * #%L diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java index e529d5f5181..b4ccb824a13 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4.java @@ -31,7 +31,7 @@ import javax.measure.unit.Unit; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.hl7.fhir.r4.context.IWorkerContext; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestSecurityComponent; import org.hl7.fhir.r4.model.Enumeration; @@ -55,7 +55,7 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamExtractorR4.class); @Autowired - private org.hl7.fhir.r4.hapi.validation.IValidationSupport myValidationSupport; + private org.hl7.fhir.r4.hapi.ctx.IValidationSupport myValidationSupport; /** * Constructor @@ -686,7 +686,7 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements */ @Override protected List extractValues(String thePaths, IBaseResource theResource) { - IWorkerContext worker = new org.hl7.fhir.r4.hapi.validation.HapiWorkerContext(getContext(), myValidationSupport); + IWorkerContext worker = new org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext(getContext(), myValidationSupport); FHIRPathEngine fp = new FHIRPathEngine(worker); List values = new ArrayList(); @@ -732,7 +732,7 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements } @VisibleForTesting - void setValidationSupportForTesting(org.hl7.fhir.r4.hapi.validation.IValidationSupport theValidationSupport) { + void setValidationSupportForTesting(org.hl7.fhir.r4.hapi.ctx.IValidationSupport theValidationSupport) { myValidationSupport = theValidationSupport; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SearchResult.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SearchResult.java index 02302e89db4..e0b3a163fac 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SearchResult.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SearchResult.java @@ -34,12 +34,10 @@ import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -//@formatter:off @Entity @Table(name = "HFJ_SEARCH_RESULT", uniqueConstraints= { @UniqueConstraint(name="IDX_SEARCHRES_ORDER", columnNames= {"SEARCH_PID", "SEARCH_ORDER"}) }) -//@formatter:on public class SearchResult implements Serializable { private static final long serialVersionUID = 1L; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu2Interceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu2Interceptor.java index a0b21153ee0..419b72465d7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu2Interceptor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu2Interceptor.java @@ -79,7 +79,12 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti * @param theOperation */ private void checkSubscriptions(IIdType idType, String resourceType, RestOperationTypeEnum theOperation) { - for (Subscription subscription : myRestHookSubscriptions) { + //avoid a ConcurrentModificationException by copying to an array + for (Object object : myRestHookSubscriptions.toArray()) { + if (object == null) { + continue; + } + Subscription subscription = (Subscription) object; // see if the criteria matches the created object ourLog.info("Checking subscription {} for {} with criteria {}", subscription.getIdElement().getIdPart(), resourceType, subscription.getCriteria()); @@ -117,6 +122,8 @@ public class RestHookSubscriptionDstu2Interceptor extends BaseRestHookSubscripti } } + + /** * Creates an HTTP Post for a subscription */ diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu3Interceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu3Interceptor.java index 964d75de41c..b1495dcb2b6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu3Interceptor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/RestHookSubscriptionDstu3Interceptor.java @@ -76,7 +76,13 @@ public class RestHookSubscriptionDstu3Interceptor extends BaseRestHookSubscripti * @param theOperation */ private void checkSubscriptions(IIdType idType, String resourceType, RestOperationTypeEnum theOperation) { - for (Subscription subscription : myRestHookSubscriptions) { + //avoid a ConcurrentModificationException by copying to an array + for (Object object : myRestHookSubscriptions.toArray()) { + //for (Subscription subscription : myRestHookSubscriptions) { + if (object == null) { + continue; + } + Subscription subscription = (Subscription) object; // see if the criteria matches the created object ourLog.info("Checking subscription {} for {} with criteria {}", subscription.getIdElement().getIdPart(), resourceType, subscription.getCriteria()); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java index bdbd10a79a7..7bb742485d4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java @@ -27,8 +27,7 @@ import javax.persistence.criteria.*; import org.hl7.fhir.instance.model.api.IBaseResource; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.transaction.support.*; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.dao.IDao; @@ -103,16 +102,23 @@ public class PersistedJpaBundleProvider implements IBundleProvider { return retVal; } - protected List doSearchOrEverythingInTransaction(final int theFromIndex, final int theToIndex) { - ISearchBuilder sb = myDao.newSearchBuilder(); + protected List doSearchOrEverything(final int theFromIndex, final int theToIndex) { + final ISearchBuilder sb = myDao.newSearchBuilder(); String resourceName = mySearchEntity.getResourceType(); Class resourceType = myContext.getResourceDefinition(resourceName).getImplementingClass(); sb.setType(resourceType, resourceName); - List pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex); + final List pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex); - return toResourceList(sb, pidsSubList); + TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager); + template.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED); + return template.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus theStatus) { + return toResourceList(sb, pidsSubList); + } + }); } private void ensureDependenciesInjected() { @@ -165,22 +171,26 @@ public class PersistedJpaBundleProvider implements IBundleProvider { TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager); - return template.execute(new TransactionCallback>() { + template.execute(new TransactionCallbackWithoutResult() { @Override - public List doInTransaction(TransactionStatus theStatus) { + protected void doInTransactionWithoutResult(TransactionStatus theStatus) { ensureSearchEntityLoaded(); - - switch (mySearchEntity.getSearchType()) { - case HISTORY: - return doHistoryInTransaction(theFromIndex, theToIndex); - case SEARCH: - case EVERYTHING: - default: - return doSearchOrEverythingInTransaction(theFromIndex, theToIndex); - } } - }); + + switch (mySearchEntity.getSearchType()) { + case HISTORY: + return template.execute(new TransactionCallback>() { + @Override + public List doInTransaction(TransactionStatus theStatus) { + return doHistoryInTransaction(theFromIndex, theToIndex); + } + }); + case SEARCH: + case EVERYTHING: + default: + return doSearchOrEverything(theFromIndex, theToIndex); + } } public String getUuid() { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java index 168ae29e25b..e2e9cb30da6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java @@ -23,8 +23,6 @@ import java.util.*; import java.util.concurrent.*; import javax.persistence.EntityManager; -import javax.transaction.Transactional; -import javax.transaction.Transactional.TxType; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.Validate; @@ -35,6 +33,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.*; import org.springframework.scheduling.concurrent.CustomizableThreadFactory; import org.springframework.transaction.*; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.*; import com.google.common.annotations.VisibleForTesting; @@ -78,13 +78,13 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { private int mySyncSize = DEFAULT_SYNC_SIZE; -// @Autowired -// private DataSource myDataSource; -// @PostConstruct -// public void start() { -// JpaTransactionManager txManager = (JpaTransactionManager) myManagedTxManager; -// } - + // @Autowired + // private DataSource myDataSource; + // @PostConstruct + // public void start() { + // JpaTransactionManager txManager = (JpaTransactionManager) myManagedTxManager; + // } + /** * Constructor */ @@ -106,7 +106,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { } @Override - @Transactional(value = TxType.NOT_SUPPORTED) + @Transactional(propagation = Propagation.NEVER) public List getResources(final String theUuid, int theFrom, int theTo) { if (myNeverUseLocalSearchForUnitTests == false) { SearchTask task = myIdToSearchTask.get(theUuid); @@ -116,7 +116,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { } TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); + txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); Search search; StopWatch sw = new StopWatch(); @@ -186,9 +186,9 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { } @Override - public IBundleProvider registerSearch(final IDao theCallingDao, SearchParameterMap theParams, String theResourceType) { + public IBundleProvider registerSearch(final IDao theCallingDao, final SearchParameterMap theParams, String theResourceType) { StopWatch w = new StopWatch(); - String searchUuid = UUID.randomUUID().toString(); + final String searchUuid = UUID.randomUUID().toString(); Class resourceTypeClass = myContext.getResourceDefinition(theResourceType).getImplementingClass(); final ISearchBuilder sb = theCallingDao.newSearchBuilder(); @@ -196,36 +196,37 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { if (theParams.isLoadSynchronous()) { - // Load the results synchronously - final List pids = new ArrayList(); - - Iterator resultIter = sb.createQuery(theParams, searchUuid); - while (resultIter.hasNext()) { - pids.add(resultIter.next()); - if (theParams.getLoadSynchronousUpTo() != null && pids.size() >= theParams.getLoadSynchronousUpTo()) { - break; - } - } - - /* - * For synchronous queries, we load all the includes right away - * since we're returning a static bundle with all the results - * pre-loaded. This is ok because syncronous requests are not - * expected to be paged - * - * On the other hand for async queries we load includes/revincludes - * individually for pages as we return them to clients - */ - final Set includedPids = new HashSet(); - includedPids.addAll(sb.loadReverseIncludes(theCallingDao, myContext, myEntityManager, pids, theParams.getRevIncludes(), true, theParams.getLastUpdated())); - includedPids.addAll(sb.loadReverseIncludes(theCallingDao, myContext, myEntityManager, pids, theParams.getIncludes(), false, theParams.getLastUpdated())); - // Execute the query and make sure we return distinct results TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager); txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED); return txTemplate.execute(new TransactionCallback() { @Override public SimpleBundleProvider doInTransaction(TransactionStatus theStatus) { + + // Load the results synchronously + final List pids = new ArrayList(); + + Iterator resultIter = sb.createQuery(theParams, searchUuid); + while (resultIter.hasNext()) { + pids.add(resultIter.next()); + if (theParams.getLoadSynchronousUpTo() != null && pids.size() >= theParams.getLoadSynchronousUpTo()) { + break; + } + } + + /* + * For synchronous queries, we load all the includes right away + * since we're returning a static bundle with all the results + * pre-loaded. This is ok because syncronous requests are not + * expected to be paged + * + * On the other hand for async queries we load includes/revincludes + * individually for pages as we return them to clients + */ + final Set includedPids = new HashSet(); + includedPids.addAll(sb.loadReverseIncludes(theCallingDao, myContext, myEntityManager, pids, theParams.getRevIncludes(), true, theParams.getLastUpdated())); + includedPids.addAll(sb.loadReverseIncludes(theCallingDao, myContext, myEntityManager, pids, theParams.getIncludes(), false, theParams.getLastUpdated())); + List resources = new ArrayList(); sb.loadResourcesByPid(pids, resources, includedPids, false, myEntityManager, myContext, theCallingDao); return new SimpleBundleProvider(resources); @@ -441,7 +442,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { try { saveSearch(); - + TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager); txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW); txTemplate.execute(new TransactionCallbackWithoutResult() { @@ -454,7 +455,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { ourLog.info("Completed search for {} resources in {}ms", mySyncedPids.size(), sw.getMillis()); } catch (Throwable t) { - + /* * Don't print a stack trace for client errors.. that's just noisy */ @@ -465,8 +466,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { logged = true; ourLog.warn("Failed during search due to invalid request: {}", t.toString()); } - } - + } + if (!logged) { ourLog.error("Failed during search loading after {}ms", sw.getMillis(), t); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java index dff4f46fa67..9c5a2c56be7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/StaleSearchDeletingSvcImpl.java @@ -1,6 +1,6 @@ package ca.uhn.fhir.jpa.search; -/* +/*- * #%L * HAPI FHIR JPA Server * %% @@ -10,7 +10,7 @@ package ca.uhn.fhir.jpa.search; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,25 +20,24 @@ package ca.uhn.fhir.jpa.search; * #L% */ -import java.util.Collection; import java.util.Date; import org.apache.commons.lang3.time.DateUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import com.google.common.annotations.VisibleForTesting; import ca.uhn.fhir.jpa.dao.DaoConfig; -import ca.uhn.fhir.jpa.dao.data.ISearchDao; -import ca.uhn.fhir.jpa.dao.data.ISearchIncludeDao; -import ca.uhn.fhir.jpa.dao.data.ISearchResultDao; +import ca.uhn.fhir.jpa.dao.data.*; import ca.uhn.fhir.jpa.entity.Search; /** @@ -47,7 +46,6 @@ import ca.uhn.fhir.jpa.entity.Search; public class StaleSearchDeletingSvcImpl implements IStaleSearchDeletingSvc { public static final long DEFAULT_CUTOFF_SLACK = 10 * DateUtils.MILLIS_PER_SECOND; private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StaleSearchDeletingSvcImpl.class); - /* * We give a bit of extra leeway just to avoid race conditions where a query result @@ -71,41 +69,48 @@ public class StaleSearchDeletingSvcImpl implements IStaleSearchDeletingSvc { @Autowired private PlatformTransactionManager myTransactionManager; - protected void deleteSearch(final Long theSearchPid) { - TransactionTemplate tt = new TransactionTemplate(myTransactionManager); - tt.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus theArg0) { - Search searchToDelete = mySearchDao.findOne(theSearchPid); - ourLog.info("Deleting search {}/{} - Created[{}] -- Last returned[{}]", searchToDelete.getId(), searchToDelete.getUuid(), searchToDelete.getCreated(), searchToDelete.getSearchLastReturned()); - mySearchIncludeDao.deleteForSearch(searchToDelete.getId()); - mySearchResultDao.deleteForSearch(searchToDelete.getId()); - mySearchDao.delete(searchToDelete); - } - }); + private void deleteSearch(final Long theSearchPid) { + Search searchToDelete = mySearchDao.findOne(theSearchPid); + ourLog.info("Deleting search {}/{} - Created[{}] -- Last returned[{}]", searchToDelete.getId(), searchToDelete.getUuid(), searchToDelete.getCreated(), searchToDelete.getSearchLastReturned()); + mySearchIncludeDao.deleteForSearch(searchToDelete.getId()); + mySearchResultDao.deleteForSearch(searchToDelete.getId()); + mySearchDao.delete(searchToDelete); } - + @Override @Transactional(propagation = Propagation.NOT_SUPPORTED) public void pollForStaleSearchesAndDeleteThem() { - + long cutoffMillis = myDaoConfig.getExpireSearchResultsAfterMillis(); if (myDaoConfig.getReuseCachedSearchResultsForMillis() != null) { cutoffMillis = Math.max(cutoffMillis, myDaoConfig.getReuseCachedSearchResultsForMillis()); } - Date cutoff = new Date((System.currentTimeMillis() - cutoffMillis) - myCutoffSlack); - + final Date cutoff = new Date((System.currentTimeMillis() - cutoffMillis) - myCutoffSlack); + ourLog.debug("Searching for searches which are before {}", cutoff); - Collection toDelete = mySearchDao.findWhereLastReturnedBefore(cutoff); - if (!toDelete.isEmpty()) { - - for (final Long next : toDelete) { - deleteSearch(next); + TransactionTemplate tt = new TransactionTemplate(myTransactionManager); + int count = tt.execute(new TransactionCallback() { + @Override + public Integer doInTransaction(TransactionStatus theStatus) { + Slice toDelete = mySearchDao.findWhereLastReturnedBefore(cutoff, new PageRequest(0, 1000)); + for (final Long next : toDelete) { + deleteSearch(next); + } + return toDelete.getContent().size(); } + }); - ourLog.info("Deleted {} searches, {} remaining", toDelete.size(), mySearchDao.count()); + if (count > 0) { + long total = tt.execute(new TransactionCallback() { + @Override + public Long doInTransaction(TransactionStatus theStatus) { + return mySearchDao.count(); + } + }); + ourLog.info("Deleted {} searches, {} remaining", count, total); } + } @Scheduled(fixedDelay = DEFAULT_CUTOFF_SLACK) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvc.java index a2b3d0fa981..6db49a0e40b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvc.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvc.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.jpa.term; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,21 +19,10 @@ package ca.uhn.fhir.jpa.term; * limitations under the License. * #L% */ - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.PersistenceContextType; +import javax.persistence.*; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.time.DateUtils; @@ -51,19 +40,12 @@ import org.springframework.transaction.support.TransactionTemplate; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Stopwatch; import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimaps; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao; import ca.uhn.fhir.jpa.dao.DaoConfig; -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao; -import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao; -import ca.uhn.fhir.jpa.dao.data.ITermConceptDao; -import ca.uhn.fhir.jpa.dao.data.ITermConceptParentChildLinkDao; -import ca.uhn.fhir.jpa.entity.TermCodeSystem; -import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; -import ca.uhn.fhir.jpa.entity.TermConcept; -import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; +import ca.uhn.fhir.jpa.dao.data.*; +import ca.uhn.fhir.jpa.entity.*; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum; import ca.uhn.fhir.jpa.util.StopWatch; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; @@ -76,6 +58,8 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiTerminologySvc.class); private static final Object PLACEHOLDER_OBJECT = new Object(); + private ArrayListMultimap myChildToParentPidCache; + @Autowired protected ITermCodeSystemDao myCodeSystemDao; @@ -100,8 +84,8 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { @PersistenceContext(type = PersistenceContextType.TRANSACTION) protected EntityManager myEntityManager; - private long myNextReindexPass; + private boolean myProcessDeferred = true; @Autowired @@ -121,7 +105,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { private int ensureParentsSaved(Collection theParents) { ourLog.trace("Checking {} parents", theParents.size()); int retVal = 0; - + for (TermConceptParentChildLink nextLink : theParents) { if (nextLink.getRelationshipType() == RelationshipTypeEnum.ISA) { TermConcept nextParent = nextLink.getParent(); @@ -133,7 +117,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { } } } - + return retVal; } @@ -206,8 +190,11 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { /** * Subclasses may override - * @param theSystem The code system - * @param theCode The code + * + * @param theSystem + * The code system + * @param theCode + * The code */ protected List findCodesAboveUsingBuiltInSystems(String theSystem, String theCode) { return Collections.emptyList(); @@ -244,15 +231,19 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { ArrayList retVal = toVersionIndependentConcepts(theSystem, codes); return retVal; } + /** * Subclasses may override - * @param theSystem The code system - * @param theCode The code + * + * @param theSystem + * The code system + * @param theCode + * The code */ protected List findCodesBelowUsingBuiltInSystems(String theSystem, String theCode) { return Collections.emptyList(); } - + private TermCodeSystemVersion findCurrentCodeSystemVersionForSystem(String theCodeSystem) { TermCodeSystem cs = getCodeSystem(theCodeSystem); if (cs == null || cs.getCurrentVersion() == null) { @@ -274,7 +265,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { if (theConceptsStack.size() == 1 || theConceptsStack.size() % 10000 == 0) { float pct = (float) theConceptsStack.size() / (float) theTotalConcepts; - ourLog.info("Have processed {}/{} concepts ({}%)", theConceptsStack.size(), theTotalConcepts, (int)( pct*100.0f)); + ourLog.info("Have processed {}/{} concepts ({}%)", theConceptsStack.size(), theTotalConcepts, (int) (pct * 100.0f)); } theConcept.setCodeSystem(theCodeSystem); @@ -285,7 +276,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { } else { myConceptsToSaveLater.add(theConcept); } - + for (TermConceptParentChildLink next : theConcept.getChildren()) { persistChildren(next.getChild(), theCodeSystem, theConceptsStack, theTotalConcepts); } @@ -297,7 +288,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { myConceptLinksToSaveLater.add(next); } } - + } private void populateVersion(TermConcept theNext, TermCodeSystemVersion theCodeSystemVersion) { @@ -310,48 +301,56 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { } } - private ArrayListMultimap myChildToParentPidCache; - + private void processDeferredConcepts() { + int codeCount = 0, relCount = 0; + StopWatch stopwatch = new StopWatch(); + + int count = Math.min(myDaoConfig.getDeferIndexingForCodesystemsOfSize(), myConceptsToSaveLater.size()); + ourLog.info("Saving {} deferred concepts...", count); + while (codeCount < count && myConceptsToSaveLater.size() > 0) { + TermConcept next = myConceptsToSaveLater.remove(0); + codeCount += saveConcept(next); + } + + if (codeCount > 0) { + ourLog.info("Saved {} deferred concepts ({} codes remain and {} relationships remain) in {}ms ({}ms / code)", + new Object[] { codeCount, myConceptsToSaveLater.size(), myConceptLinksToSaveLater.size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(codeCount) }); + } + + if (codeCount == 0) { + count = Math.min(myDaoConfig.getDeferIndexingForCodesystemsOfSize(), myConceptLinksToSaveLater.size()); + ourLog.info("Saving {} deferred concept relationships...", count); + while (relCount < count && myConceptLinksToSaveLater.size() > 0) { + TermConceptParentChildLink next = myConceptLinksToSaveLater.remove(0); + + if (myConceptDao.findOne(next.getChild().getId()) == null || myConceptDao.findOne(next.getParent().getId()) == null) { + ourLog.warn("Not inserting link from child {} to parent {} because it appears to have been deleted", next.getParent().getCode(), next.getChild().getCode()); + continue; + } + + saveConceptLink(next); + relCount++; + } + } + + if (relCount > 0) { + ourLog.info("Saved {} deferred relationships ({} remain) in {}ms ({}ms / code)", + new Object[] { relCount, myConceptLinksToSaveLater.size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(codeCount) }); + } + + if ((myConceptsToSaveLater.size() + myConceptLinksToSaveLater.size()) == 0) { + ourLog.info("All deferred concepts and relationships have now been synchronized to the database"); + } + } + private void processReindexing() { if (System.currentTimeMillis() < myNextReindexPass && !ourForceSaveDeferredAlwaysForUnitTest) { return; } - + TransactionTemplate tt = new TransactionTemplate(myTransactionMgr); tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW); tt.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus theArg0) { - int maxResult = 1000; - Page concepts = myConceptDao.findResourcesRequiringReindexing(new PageRequest(0, maxResult)); - if (concepts.hasContent() == false) { - myNextReindexPass = System.currentTimeMillis() + DateUtils.MILLIS_PER_MINUTE; - myChildToParentPidCache = null; - return; - } - - if (myChildToParentPidCache == null) { - myChildToParentPidCache = ArrayListMultimap.create(); - } - - ourLog.info("Indexing {} / {} concepts", concepts.getContent().size(), concepts.getTotalElements()); - - int count = 0; - StopWatch stopwatch = new StopWatch(); - - for (TermConcept nextConcept : concepts) { - - StringBuilder parentsBuilder = new StringBuilder(); - createParentsString(parentsBuilder, nextConcept.getId()); - nextConcept.setParentPids(parentsBuilder.toString()); - - saveConcept(nextConcept); - count++; - } - - ourLog.info("Indexed {} / {} concepts in {}ms - Avg {}ms / resource", new Object[] { count, concepts.getContent().size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(count) }); - } - private void createParentsString(StringBuilder theParentsBuilder, Long theConceptPid) { Validate.notNull(theConceptPid, "theConceptPid must not be null"); List parents = myChildToParentPidCache.get(theConceptPid); @@ -368,8 +367,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { } } } - - + for (Long nextParent : parents) { if (theParentsBuilder.length() > 0) { theParentsBuilder.append(' '); @@ -378,13 +376,45 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { createParentsString(theParentsBuilder, nextParent); } } + + @Override + protected void doInTransactionWithoutResult(TransactionStatus theArg0) { + int maxResult = 1000; + Page concepts = myConceptDao.findResourcesRequiringReindexing(new PageRequest(0, maxResult)); + if (concepts.hasContent() == false) { + myNextReindexPass = System.currentTimeMillis() + DateUtils.MILLIS_PER_MINUTE; + myChildToParentPidCache = null; + return; + } + + if (myChildToParentPidCache == null) { + myChildToParentPidCache = ArrayListMultimap.create(); + } + + ourLog.info("Indexing {} / {} concepts", concepts.getContent().size(), concepts.getTotalElements()); + + int count = 0; + StopWatch stopwatch = new StopWatch(); + + for (TermConcept nextConcept : concepts) { + + StringBuilder parentsBuilder = new StringBuilder(); + createParentsString(parentsBuilder, nextConcept.getId()); + nextConcept.setParentPids(parentsBuilder.toString()); + + saveConcept(nextConcept); + count++; + } + + ourLog.info("Indexed {} / {} concepts in {}ms - Avg {}ms / resource", new Object[] { count, concepts.getContent().size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(count) }); + } }); } private int saveConcept(TermConcept theConcept) { int retVal = 0; - + /* * If the concept has an ID, we're reindexing, so there's no need to * save parent concepts first (it's way too slow to do that) @@ -392,25 +422,25 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { if (theConcept.getId() == null) { retVal += ensureParentsSaved(theConcept.getParents()); } - + if (theConcept.getId() == null || theConcept.getIndexStatus() == null) { retVal++; theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED); myConceptDao.save(theConcept); } - + ourLog.trace("Saved {} and got PID {}", theConcept.getCode(), theConcept.getId()); return retVal; } - + private void saveConceptLink(TermConceptParentChildLink next) { if (next.getId() == null) { myConceptParentChildLinkDao.save(next); } } - @Scheduled(fixedRate=5000) - @Transactional(propagation=Propagation.REQUIRED) + @Scheduled(fixedRate = 5000) + @Transactional(propagation = Propagation.NEVER) @Override public synchronized void saveDeferred() { if (!myProcessDeferred) { @@ -419,46 +449,18 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { processReindexing(); return; } - - int codeCount = 0, relCount = 0; - StopWatch stopwatch = new StopWatch(); - - int count = Math.min(myDaoConfig.getDeferIndexingForCodesystemsOfSize(), myConceptsToSaveLater.size()); - ourLog.info("Saving {} deferred concepts...", count); - while (codeCount < count && myConceptsToSaveLater.size() > 0) { - TermConcept next = myConceptsToSaveLater.remove(0); - codeCount += saveConcept(next); - } - if (codeCount > 0) { - ourLog.info("Saved {} deferred concepts ({} codes remain and {} relationships remain) in {}ms ({}ms / code)", new Object[] {codeCount, myConceptsToSaveLater.size(), myConceptLinksToSaveLater.size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(codeCount)}); - } - - if (codeCount == 0) { - count = Math.min(myDaoConfig.getDeferIndexingForCodesystemsOfSize(), myConceptLinksToSaveLater.size()); - ourLog.info("Saving {} deferred concept relationships...", count); - while (relCount < count && myConceptLinksToSaveLater.size() > 0) { - TermConceptParentChildLink next = myConceptLinksToSaveLater.remove(0); - - if (myConceptDao.findOne(next.getChild().getId()) == null || myConceptDao.findOne(next.getParent().getId()) == null) { - ourLog.warn("Not inserting link from child {} to parent {} because it appears to have been deleted", next.getParent().getCode(), next.getChild().getCode()); - continue; - } - - saveConceptLink(next); - relCount++; + TransactionTemplate tt = new TransactionTemplate(myTransactionMgr); + tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW); + tt.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus theArg0) { + processDeferredConcepts(); } - } - - if (relCount > 0) { - ourLog.info("Saved {} deferred relationships ({} remain) in {}ms ({}ms / code)", new Object[] {relCount, myConceptLinksToSaveLater.size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(codeCount)}); - } - - if ((myConceptsToSaveLater.size() + myConceptLinksToSaveLater.size()) == 0) { - ourLog.info("All deferred concepts and relationships have now been synchronized to the database"); - } + + }); } - + @Override public void setProcessDeferred(boolean theProcessDeferred) { myProcessDeferred = theProcessDeferred; @@ -487,7 +489,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { } ourLog.info("Flushing..."); - + myConceptParentChildLinkDao.flush(); myConceptDao.flush(); @@ -540,7 +542,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { } ourLog.info("Saving {} concepts...", totalCodeCount); - + IdentityHashMap conceptsStack2 = new IdentityHashMap(); for (TermConcept next : theCodeSystemVersion.getConcepts()) { persistChildren(next, codeSystemVersion, conceptsStack2, totalCodeCount); @@ -552,7 +554,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { myConceptParentChildLinkDao.flush(); ourLog.info("Done deleting old code system versions"); - + if (myConceptsToSaveLater.size() > 0 || myConceptLinksToSaveLater.size() > 0) { ourLog.info("Note that some concept saving was deferred - still have {} concepts and {} relationships", myConceptsToSaveLater.size(), myConceptLinksToSaveLater.size()); } @@ -563,7 +565,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { TermCodeSystem cs = getCodeSystem(theSystem); return cs != null; } - + private ArrayList toVersionIndependentConcepts(String theSystem, Set codes) { ArrayList retVal = new ArrayList(codes.size()); for (TermConcept next : codes) { @@ -582,7 +584,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc { throw new InvalidRequestException("CodeSystem contains circular reference around code " + theConcept.getCode()); } theConceptsStack.add(theConcept.getCode()); - + int retVal = 0; if (theAllConcepts.put(theConcept, theAllConcepts) == null) { if (theAllConcepts.size() % 1000 == 0) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java index ca455e62ff0..2950eacfdb5 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcR4.java @@ -29,8 +29,8 @@ import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.FullTextQuery; import org.hibernate.search.query.dsl.BooleanJunction; import org.hibernate.search.query.dsl.QueryBuilder; -import org.hl7.fhir.r4.hapi.validation.HapiWorkerContext; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport; +import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.CodeSystem.CodeSystemContentMode; import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvcR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvcR4.java index 83d9d7123ee..6676f51bf35 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvcR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvcR4.java @@ -1,26 +1,6 @@ package ca.uhn.fhir.jpa.term; -/* - * #%L - * HAPI FHIR JPA Server - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import org.hl7.fhir.r4.hapi.validation.IValidationSupport; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; public interface IHapiTerminologySvcR4 extends IHapiTerminologySvc, IValidationSupport { // nothing diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BaseIterator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BaseIterator.java new file mode 100644 index 00000000000..e4b8edbc06f --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/BaseIterator.java @@ -0,0 +1,12 @@ +package ca.uhn.fhir.jpa.util; + +import java.util.Iterator; + +public abstract class BaseIterator implements Iterator { + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + +} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChainR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChainR4.java index 06c964d024d..babea557031 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChainR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChainR4.java @@ -23,8 +23,8 @@ package ca.uhn.fhir.jpa.validation; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import org.hl7.fhir.r4.hapi.validation.DefaultProfileValidationSupport; -import org.hl7.fhir.r4.hapi.validation.ValidationSupportChain; +import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport; +import org.hl7.fhir.r4.hapi.ctx.ValidationSupportChain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/ConnectionWrapper.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/ConnectionWrapper.java new file mode 100644 index 00000000000..cb11e4135d5 --- /dev/null +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/ConnectionWrapper.java @@ -0,0 +1,289 @@ +package ca.uhn.fhir.jpa.config; + +import java.sql.*; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +public class ConnectionWrapper implements Connection { + + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ConnectionWrapper.class); + + private Connection myWrap; + + public ConnectionWrapper(Connection theConnection) { + myWrap = theConnection; + } + + @Override + public void abort(Executor theExecutor) throws SQLException { + myWrap.abort(theExecutor); + } + + @Override + public void clearWarnings() throws SQLException { + myWrap.clearWarnings(); + } + + @Override + public void close() throws SQLException { +// ourLog.info("** Closing connection"); + myWrap.close(); + } + + @Override + public void commit() throws SQLException { + myWrap.commit(); + } + + @Override + public Array createArrayOf(String theTypeName, Object[] theElements) throws SQLException { + return myWrap.createArrayOf(theTypeName, theElements); + } + + @Override + public Blob createBlob() throws SQLException { + return myWrap.createBlob(); + } + + @Override + public Clob createClob() throws SQLException { + return myWrap.createClob(); + } + + @Override + public NClob createNClob() throws SQLException { + return myWrap.createNClob(); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return myWrap.createSQLXML(); + } + + @Override + public Statement createStatement() throws SQLException { + return myWrap.createStatement(); + } + + @Override + public Statement createStatement(int theResultSetType, int theResultSetConcurrency) throws SQLException { + return myWrap.createStatement(theResultSetType, theResultSetConcurrency); + } + + @Override + public Statement createStatement(int theResultSetType, int theResultSetConcurrency, int theResultSetHoldability) throws SQLException { + return myWrap.createStatement(theResultSetType, theResultSetConcurrency, theResultSetHoldability); + } + + @Override + public Struct createStruct(String theTypeName, Object[] theAttributes) throws SQLException { + return myWrap.createStruct(theTypeName, theAttributes); + } + + @Override + public boolean getAutoCommit() throws SQLException { + return myWrap.getAutoCommit(); + } + + @Override + public String getCatalog() throws SQLException { + return myWrap.getCatalog(); + } + + @Override + public Properties getClientInfo() throws SQLException { + return myWrap.getClientInfo(); + } + + @Override + public String getClientInfo(String theName) throws SQLException { + return getClientInfo(theName); + } + + @Override + public int getHoldability() throws SQLException { + return myWrap.getHoldability(); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return myWrap.getMetaData(); + } + + @Override + public int getNetworkTimeout() throws SQLException { + return myWrap.getNetworkTimeout(); + } + + @Override + public String getSchema() throws SQLException { + return myWrap.getSchema(); + } + + @Override + public int getTransactionIsolation() throws SQLException { + return myWrap.getTransactionIsolation(); + } + + @Override + public Map> getTypeMap() throws SQLException { + return myWrap.getTypeMap(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return myWrap.getWarnings(); + } + + @Override + public boolean isClosed() throws SQLException { + return myWrap.isClosed(); + } + + @Override + public boolean isReadOnly() throws SQLException { + return myWrap.isReadOnly(); + } + + @Override + public boolean isValid(int theTimeout) throws SQLException { + return myWrap.isValid(theTimeout); + } + + @Override + public boolean isWrapperFor(Class theIface) throws SQLException { + return myWrap.isWrapperFor(theIface); + } + + @Override + public String nativeSQL(String theSql) throws SQLException { + return myWrap.nativeSQL(theSql); + } + + @Override + public CallableStatement prepareCall(String theSql) throws SQLException { + return myWrap.prepareCall(theSql); + } + + @Override + public CallableStatement prepareCall(String theSql, int theResultSetType, int theResultSetConcurrency) throws SQLException { + return myWrap.prepareCall(theSql, theResultSetType, theResultSetConcurrency); + } + + @Override + public CallableStatement prepareCall(String theSql, int theResultSetType, int theResultSetConcurrency, int theResultSetHoldability) throws SQLException { + return myWrap.prepareCall(theSql, theResultSetType, theResultSetConcurrency, theResultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String theSql) throws SQLException { + return myWrap.prepareStatement(theSql); + } + + @Override + public PreparedStatement prepareStatement(String theSql, int theAutoGeneratedKeys) throws SQLException { + return myWrap.prepareStatement(theSql, theAutoGeneratedKeys); + } + + @Override + public PreparedStatement prepareStatement(String theSql, int theResultSetType, int theResultSetConcurrency) throws SQLException { + return myWrap.prepareStatement(theSql, theResultSetType, theResultSetConcurrency); + } + + @Override + public PreparedStatement prepareStatement(String theSql, int theResultSetType, int theResultSetConcurrency, int theResultSetHoldability) throws SQLException { + return myWrap.prepareStatement(theSql, theResultSetType, theResultSetConcurrency, theResultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String theSql, int[] theColumnIndexes) throws SQLException { + return myWrap.prepareStatement(theSql, theColumnIndexes); + } + + @Override + public PreparedStatement prepareStatement(String theSql, String[] theColumnNames) throws SQLException { + return myWrap.prepareStatement(theSql, theColumnNames); + } + + @Override + public void releaseSavepoint(Savepoint theSavepoint) throws SQLException { + myWrap.releaseSavepoint(theSavepoint); + } + + @Override + public void rollback() throws SQLException { + myWrap.rollback(); + } + + @Override + public void rollback(Savepoint theSavepoint) throws SQLException { + myWrap.rollback(theSavepoint); + } + + @Override + public void setAutoCommit(boolean theAutoCommit) throws SQLException { + myWrap.setAutoCommit(theAutoCommit); + } + + @Override + public void setCatalog(String theCatalog) throws SQLException { + myWrap.setCatalog(theCatalog); + } + + @Override + public void setClientInfo(Properties theProperties) throws SQLClientInfoException { + myWrap.setClientInfo(theProperties); + } + + @Override + public void setClientInfo(String theName, String theValue) throws SQLClientInfoException { + myWrap.setClientInfo(theName, theValue); + } + + @Override + public void setHoldability(int theHoldability) throws SQLException { + myWrap.setHoldability(theHoldability); + } + + @Override + public void setNetworkTimeout(Executor theExecutor, int theMilliseconds) throws SQLException { + myWrap.setNetworkTimeout(theExecutor, theMilliseconds); + } + + @Override + public void setReadOnly(boolean theReadOnly) throws SQLException { + myWrap.setReadOnly(theReadOnly); + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return myWrap.setSavepoint(); + } + + @Override + public Savepoint setSavepoint(String theName) throws SQLException { + return myWrap.setSavepoint(theName); + } + + @Override + public void setSchema(String theSchema) throws SQLException { + myWrap.setSchema(theSchema); + } + + @Override + public void setTransactionIsolation(int theLevel) throws SQLException { + myWrap.setTransactionIsolation(theLevel); + } + + @Override + public void setTypeMap(Map> theMap) throws SQLException { + myWrap.setTypeMap(theMap); + } + + @Override + public T unwrap(Class theIface) throws SQLException { + return myWrap.unwrap(theIface); + } + +} \ No newline at end of file diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu3Config.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu3Config.java index 0a964f37767..f8d4802aee5 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu3Config.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/config/TestDstu3Config.java @@ -1,5 +1,7 @@ package ca.uhn.fhir.jpa.config; +import java.sql.Connection; +import java.sql.SQLException; import java.util.Properties; import java.util.concurrent.TimeUnit; @@ -8,9 +10,7 @@ import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSource; import org.hibernate.jpa.HibernatePersistenceProvider; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.*; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -18,30 +18,82 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; import ca.uhn.fhir.validation.ResultSeverityEnum; -import net.ttddyy.dsproxy.listener.logging.SLF4JLogLevel; import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder; @Configuration @EnableTransactionManagement() public class TestDstu3Config extends BaseJavaConfigDstu3 { + static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TestDstu3Config.class); + @Bean() public DaoConfig daoConfig() { return new DaoConfig(); } + private Exception myLastStackTrace; + @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(); + System.exit(1); + retVal = null; + } + + try { + throw new Exception(); + } catch (Exception e) { + myLastStackTrace = e; + } + + 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()); + } + + }; retVal.setDriver(new org.apache.derby.jdbc.EmbeddedDriver()); retVal.setUrl("jdbc:derby:memory:myUnitTestDB;create=true"); + retVal.setMaxWaitMillis(10000); retVal.setUsername(""); retVal.setPassword(""); - retVal.setMaxTotal(4); + + /* + * We use a randomized number of maximum threads in order to try + * and catch any potential deadlocks caused by database connection + * starvation + */ + int maxThreads = (int) (Math.random() * 6) + 1; + retVal.setMaxTotal(maxThreads); DataSource dataSource = ProxyDataSourceBuilder .create(retVal) - .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL") + // .logQueryBySlf4j(SLF4JLogLevel.INFO, "SQL") .logSlowQueryBySlf4j(10, TimeUnit.SECONDS) .countQuery() .build(); @@ -49,13 +101,6 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 { return dataSource; } - @Bean() - public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { - JpaTransactionManager retVal = new JpaTransactionManager(); - retVal.setEntityManagerFactory(entityManagerFactory); - return retVal; - } - @Bean() public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); @@ -95,4 +140,11 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 { return requestValidator; } + @Bean() + public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { + JpaTransactionManager retVal = new JpaTransactionManager(); + retVal.setEntityManagerFactory(entityManagerFactory); + return retVal; + } + } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java index 145df7af068..a1fb9aeb98b 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java @@ -16,7 +16,6 @@ import java.util.*; import org.apache.commons.io.IOUtils; import org.hl7.fhir.dstu3.model.*; -import org.hl7.fhir.dstu3.model.Bundle.*; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryRequestComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryResponseComponent; @@ -170,6 +169,74 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { return null; } + @Test + public void testBatchCreateWithBadRead() { + Bundle request = new Bundle(); + request.setType(BundleType.BATCH); + + Patient p; + p = new Patient(); + p.addIdentifier().setSystem("urn:system").setValue("FOO"); + request + .addEntry() + .setResource(p) + .getRequest() + .setMethod(HTTPVerb.POST) + .setUrl("Patient"); + + request + .addEntry() + .getRequest() + .setMethod(HTTPVerb.GET) + .setUrl("Patient/BABABABA"); + + Bundle response = mySystemDao.transaction(mySrd, request); + assertEquals(2, response.getEntry().size()); + + assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); + assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); + assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus()); + + OperationOutcome oo = (OperationOutcome) response.getEntry().get(1).getResponse().getOutcome(); + ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(oo)); + assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); + assertEquals("Resource Patient/BABABABA is not known", oo.getIssue().get(0).getDiagnostics()); + } + + @Test + public void testBatchCreateWithBadSearch() { + Bundle request = new Bundle(); + request.setType(BundleType.BATCH); + + Patient p; + p = new Patient(); + p.addIdentifier().setSystem("urn:system").setValue("FOO"); + request + .addEntry() + .setResource(p) + .getRequest() + .setMethod(HTTPVerb.POST) + .setUrl("Patient"); + + request + .addEntry() + .getRequest() + .setMethod(HTTPVerb.GET) + .setUrl("Patient?foobadparam=1"); + + Bundle response = mySystemDao.transaction(mySrd, request); + assertEquals(2, response.getEntry().size()); + + assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); + assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); + assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus()); + + OperationOutcome oo = (OperationOutcome) response.getEntry().get(1).getResponse().getOutcome(); + ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(oo)); + assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); + assertThat(oo.getIssue().get(0).getDiagnostics(), containsString("Unknown search parameter")); + } + @Test public void testCircularCreateAndDelete() { Encounter enc = new Encounter(); @@ -552,9 +619,10 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { assertThat(resp.getEntry().get(0).getResponse().getLocation(), startsWith("Patient/")); // Bundle.entry[1] is failed read response - assertEquals(OperationOutcome.class, resp.getEntry().get(1).getResource().getClass()); - assertEquals(IssueSeverity.ERROR, ((OperationOutcome) resp.getEntry().get(1).getResource()).getIssue().get(0).getSeverityElement().getValue()); - assertEquals("Resource Patient/THIS_ID_DOESNT_EXIST is not known", ((OperationOutcome) resp.getEntry().get(1).getResource()).getIssue().get(0).getDiagnostics()); + Resource oo = resp.getEntry().get(1).getResponse().getOutcome(); + assertEquals(OperationOutcome.class, oo.getClass()); + assertEquals(IssueSeverity.ERROR, ((OperationOutcome) oo).getIssue().get(0).getSeverityElement().getValue()); + assertEquals("Resource Patient/THIS_ID_DOESNT_EXIST is not known", ((OperationOutcome) oo).getIssue().get(0).getDiagnostics()); assertEquals("404 Not Found", resp.getEntry().get(1).getResponse().getStatus()); // Check POST @@ -869,6 +937,74 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { } + @Test + public void testTransactionCreateWithBadRead() { + Bundle request = new Bundle(); + request.setType(BundleType.TRANSACTION); + + Patient p; + p = new Patient(); + p.addIdentifier().setSystem("urn:system").setValue("FOO"); + request + .addEntry() + .setResource(p) + .getRequest() + .setMethod(HTTPVerb.POST) + .setUrl("Patient"); + + request + .addEntry() + .getRequest() + .setMethod(HTTPVerb.GET) + .setUrl("Patient/BABABABA"); + + Bundle response = mySystemDao.transaction(mySrd, request); + assertEquals(2, response.getEntry().size()); + + assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); + assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); + assertEquals("404 Not Found", response.getEntry().get(1).getResponse().getStatus()); + + OperationOutcome oo = (OperationOutcome) response.getEntry().get(1).getResponse().getOutcome(); + ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(oo)); + assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); + assertEquals("Resource Patient/BABABABA is not known", oo.getIssue().get(0).getDiagnostics()); + } + + @Test + public void testTransactionCreateWithBadSearch() { + Bundle request = new Bundle(); + request.setType(BundleType.TRANSACTION); + + Patient p; + p = new Patient(); + p.addIdentifier().setSystem("urn:system").setValue("FOO"); + request + .addEntry() + .setResource(p) + .getRequest() + .setMethod(HTTPVerb.POST) + .setUrl("Patient"); + + request + .addEntry() + .getRequest() + .setMethod(HTTPVerb.GET) + .setUrl("Patient?foobadparam=1"); + + Bundle response = mySystemDao.transaction(mySrd, request); + assertEquals(2, response.getEntry().size()); + + assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus()); + assertThat(response.getEntry().get(0).getResponse().getLocation(), matchesPattern(".*Patient/[0-9]+.*")); + assertEquals("400 Bad Request", response.getEntry().get(1).getResponse().getStatus()); + + OperationOutcome oo = (OperationOutcome) response.getEntry().get(1).getResponse().getOutcome(); + ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(oo)); + assertEquals(IssueSeverity.ERROR, oo.getIssue().get(0).getSeverity()); + assertThat(oo.getIssue().get(0).getDiagnostics(), containsString("Unknown search parameter")); + } + @Test public void testTransactionCreateWithDuplicateMatchUrl01() { String methodName = "testTransactionCreateWithDuplicateMatchUrl01"; @@ -914,7 +1050,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { "Unable to process Transaction - Request would cause multiple resources to match URL: \"Patient?identifier=urn%3Asystem%7CtestTransactionCreateWithDuplicateMatchUrl02\". Does transaction request contain duplicates?"); } } - + @Test public void testTransactionCreateWithInvalidMatchUrl() { String methodName = "testTransactionCreateWithInvalidMatchUrl"; @@ -949,6 +1085,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { assertEquals("Failed to parse match URL[Patient?foo=bar] - Resource type Patient does not have a parameter with name: foo", e.getMessage()); } } + @Test public void testTransactionCreateWithInvalidReferenceNumeric() { @@ -1332,20 +1469,15 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { @Test public void testTransactionDoesNotLeavePlaceholderIds() throws Exception { - newTxTemplate().execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus theStatus) { - String input; - try { - input = IOUtils.toString(getClass().getResourceAsStream("/cdr-bundle.json"), StandardCharsets.UTF_8); - } catch (IOException e) { - fail(e.toString()); - return; - } - Bundle bundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, input); - mySystemDao.transaction(mySrd, bundle); - } - }); + String input; + try { + input = IOUtils.toString(getClass().getResourceAsStream("/cdr-bundle.json"), StandardCharsets.UTF_8); + } catch (IOException e) { + fail(e.toString()); + return; + } + Bundle bundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, input); + mySystemDao.transaction(mySrd, bundle); IBundleProvider history = mySystemDao.history(null, null, null); Bundle list = toBundle(history); @@ -2161,16 +2293,16 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { * */ @Test - public void testTransactionWithPlaceholderIdInMatchUrlPut() { + public void testTransactionWithPlaceholderIdInMatchUrlPost() { - Bundle input = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.PUT); + Bundle input = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.POST); Bundle output = mySystemDao.transaction(null, input); assertEquals("201 Created", output.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", output.getEntry().get(1).getResponse().getStatus()); assertEquals("201 Created", output.getEntry().get(2).getResponse().getStatus()); - Bundle input2 = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.PUT); + Bundle input2 = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.POST); Bundle output2 = mySystemDao.transaction(null, input2); ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(output2)); @@ -2191,16 +2323,16 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { * */ @Test - public void testTransactionWithPlaceholderIdInMatchUrlPost() { + public void testTransactionWithPlaceholderIdInMatchUrlPut() { - Bundle input = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.POST); + Bundle input = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.PUT); Bundle output = mySystemDao.transaction(null, input); assertEquals("201 Created", output.getEntry().get(0).getResponse().getStatus()); assertEquals("201 Created", output.getEntry().get(1).getResponse().getStatus()); assertEquals("201 Created", output.getEntry().get(2).getResponse().getStatus()); - Bundle input2 = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.POST); + Bundle input2 = createInputTransactionWithPlaceholderIdInMatchUrl(HTTPVerb.PUT); Bundle output2 = mySystemDao.transaction(null, input2); ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(output2)); @@ -2247,6 +2379,7 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { assertEquals("Joshua", patient.getNameFirstRep().getGivenAsSingleString()); } + @Test public void testTransactionWithReferenceResource() { Bundle request = new Bundle(); @@ -2274,58 +2407,59 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { assertEquals(1, found.size().intValue()); } + @Test - public void testTransactionWithReferenceToCreateIfNoneExist() { - Bundle bundle = new Bundle(); - bundle.setType(BundleType.TRANSACTION); - - Medication med = new Medication(); - IdType medId = IdType.newRandomUuid(); - med.setId(medId); - med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); - bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); - - MedicationRequest mo = new MedicationRequest(); - mo.setMedication(new Reference(medId)); - bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); - - ourLog.info("Request:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); - - Bundle outcome = mySystemDao.transaction(mySrd, bundle); - ourLog.info("Response:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); - - IdType medId1 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); - IdType medOrderId1 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); - - /* - * Again! - */ - - bundle = new Bundle(); - bundle.setType(BundleType.TRANSACTION); - - med = new Medication(); - medId = IdType.newRandomUuid(); - med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); - bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); - - mo = new MedicationRequest(); - mo.setMedication(new Reference(medId)); - bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); - - outcome = mySystemDao.transaction(mySrd, bundle); - - IdType medId2 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); - IdType medOrderId2 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); - - assertTrue(medId1.isIdPartValidLong()); - assertTrue(medId2.isIdPartValidLong()); - assertTrue(medOrderId1.isIdPartValidLong()); - assertTrue(medOrderId2.isIdPartValidLong()); - - assertEquals(medId1, medId2); - assertNotEquals(medOrderId1, medOrderId2); - } + public void testTransactionWithReferenceToCreateIfNoneExist() { + Bundle bundle = new Bundle(); + bundle.setType(BundleType.TRANSACTION); + + Medication med = new Medication(); + IdType medId = IdType.newRandomUuid(); + med.setId(medId); + med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); + bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); + + MedicationRequest mo = new MedicationRequest(); + mo.setMedication(new Reference(medId)); + bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); + + ourLog.info("Request:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); + + Bundle outcome = mySystemDao.transaction(mySrd, bundle); + ourLog.info("Response:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); + + IdType medId1 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); + IdType medOrderId1 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); + + /* + * Again! + */ + + bundle = new Bundle(); + bundle.setType(BundleType.TRANSACTION); + + med = new Medication(); + medId = IdType.newRandomUuid(); + med.getCode().addCoding().setSystem("billscodes").setCode("theCode"); + bundle.addEntry().setResource(med).setFullUrl(medId.getValue()).getRequest().setMethod(HTTPVerb.POST).setIfNoneExist("Medication?code=billscodes|theCode"); + + mo = new MedicationRequest(); + mo.setMedication(new Reference(medId)); + bundle.addEntry().setResource(mo).setFullUrl(mo.getIdElement().getValue()).getRequest().setMethod(HTTPVerb.POST); + + outcome = mySystemDao.transaction(mySrd, bundle); + + IdType medId2 = new IdType(outcome.getEntry().get(0).getResponse().getLocation()); + IdType medOrderId2 = new IdType(outcome.getEntry().get(1).getResponse().getLocation()); + + assertTrue(medId1.isIdPartValidLong()); + assertTrue(medId2.isIdPartValidLong()); + assertTrue(medOrderId1.isIdPartValidLong()); + assertTrue(medOrderId2.isIdPartValidLong()); + + assertEquals(medId1, medId2); + assertNotEquals(medOrderId1, medOrderId2); + } // // @@ -2429,7 +2563,8 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest { // // } - @Test + + @Test public void testTransactionWithReferenceUuid() { Bundle request = new Bundle(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java index 2cbbbf8f381..47baa956052 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java @@ -2,9 +2,16 @@ package ca.uhn.fhir.jpa.provider.dstu3; import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.*; +import java.math.BigDecimal; import java.net.*; import java.nio.charset.StandardCharsets; import java.util.*; @@ -1973,7 +1980,9 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { .execute(); assertEquals(10, response.getEntry().size()); - assertEquals(null, response.getTotalElement().getValueAsString()); + if (response.getTotalElement().getValueAsString() != null) { + assertEquals("21", response.getTotalElement().getValueAsString()); + } assertThat(response.getLink("next").getUrl(), not(emptyString())); // Load page 2 @@ -1982,7 +1991,9 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { response = ourClient.fetchResourceFromUrl(Bundle.class, nextUrl); assertEquals(10, response.getEntry().size()); - assertEquals(null, response.getTotalElement().getValueAsString()); + if (response.getTotalElement().getValueAsString() != null) { + assertEquals("21", response.getTotalElement().getValueAsString()); + } assertThat(response.getLink("next").getUrl(), not(emptyString())); // Load page 3 @@ -1992,7 +2003,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { response = ourClient.fetchResourceFromUrl(Bundle.class, nextUrl); assertEquals(1, response.getEntry().size()); - assertEquals(21, response.getTotal()); + assertEquals("21", response.getTotalElement().getValueAsString()); assertEquals(null, response.getLink("next")); } @@ -3187,6 +3198,31 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test { } } + @Test() + public void testSearchNegativeNumbers() throws Exception { + Observation o = new Observation(); + o.setValue(new Quantity().setValue(new BigDecimal("-10"))); + String oid1 = myObservationDao.create(o, mySrd).getId().toUnqualifiedVersionless().getValue(); + + Observation o2 = new Observation(); + o2.setValue(new Quantity().setValue(new BigDecimal("-20"))); + String oid2 = myObservationDao.create(o2, mySrd).getId().toUnqualifiedVersionless().getValue(); + + HttpGet get = new HttpGet(ourServerBase + "/Observation?value-quantity=gt-15"); + CloseableHttpResponse resp = ourHttpClient.execute(get); + try { + assertEquals(200, resp.getStatusLine().getStatusCode()); + Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, IOUtils.toString(resp.getEntity().getContent(), Constants.CHARSET_UTF8)); + + List ids = toUnqualifiedVersionlessIdValues(bundle); + assertThat(ids, contains(oid1)); + assertThat(ids, not(contains(oid2))); + } finally { + IOUtils.closeQuietly(resp); + } + + } + @Test(expected = InvalidRequestException.class) public void testSearchWithInvalidSort() throws Exception { Observation o = new Observation(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java index 939f2b76185..2720e48f8f3 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.dao.*; import ca.uhn.fhir.jpa.dao.data.*; import ca.uhn.fhir.jpa.entity.*; +import ca.uhn.fhir.jpa.util.BaseIterator; import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.StringParam; @@ -139,9 +140,6 @@ public class SearchCoordinatorSvcImplTest { } - private String newUuid() { - return UUID.randomUUID().toString(); - } @Test public void testAsyncSearchLargeResultSetBigCountSameCoordinator() { SearchParameterMap params = new SearchParameterMap(); @@ -392,7 +390,7 @@ public class SearchCoordinatorSvcImplTest { TestUtil.clearAllStaticFieldsForUnitTest(); } - public static class FailAfterNIterator implements Iterator { + public static class FailAfterNIterator extends BaseIterator implements Iterator { private int myCount; private Iterator myWrap; @@ -419,7 +417,7 @@ public class SearchCoordinatorSvcImplTest { } - public static class SlowIterator implements Iterator { + public static class SlowIterator extends BaseIterator implements Iterator { private int myDelay; private Iterator myWrap; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/stresstest/StressTestDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/stresstest/StressTestDstu3Test.java index b3f72096863..82d2f6a02fe 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/stresstest/StressTestDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/stresstest/StressTestDstu3Test.java @@ -6,6 +6,7 @@ import static org.junit.Assert.fail; import java.util.List; import java.util.UUID; +import ca.uhn.fhir.rest.api.Constants; import org.apache.commons.io.IOUtils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -15,6 +16,7 @@ import org.hl7.fhir.dstu3.model.Bundle.BundleType; import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb; import org.junit.*; +import com.google.common.base.Charsets; import com.google.common.collect.Lists; import ca.uhn.fhir.jpa.provider.dstu3.BaseResourceProviderDstu3Test; @@ -42,6 +44,37 @@ public class StressTestDstu3Test extends BaseResourceProviderDstu3Test { ourRestServer.unregisterInterceptor(myRequestValidatingInterceptor); } + + + @Test + public void testMultithreadedSearch() throws Exception { + Bundle input = new Bundle(); + input.setType(BundleType.TRANSACTION); + for (int i = 0; i < 500; i++) { + Patient p = new Patient(); + p.addIdentifier().setSystem("http://test").setValue("BAR"); + input.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST).setUrl("Patient"); + } + ourClient.transaction().withBundle(input).execute(); + + + List tasks = Lists.newArrayList(); + try { + for (int threadIndex = 0; threadIndex < 10; threadIndex++) { + SearchTask task = new SearchTask(); + tasks.add(task); + task.start(); + } + } finally { + for (BaseTask next : tasks) { + next.join(); + } + } + + validateNoErrors(tasks); + + } + /** * This test prevents a deadlock that was detected with a large number of @@ -73,12 +106,12 @@ public class StressTestDstu3Test extends BaseResourceProviderDstu3Test { List tasks = Lists.newArrayList(); try { - for (int threadIndex = 0; threadIndex < 8; threadIndex++) { + for (int threadIndex = 0; threadIndex < 5; threadIndex++) { SearchTask task = new SearchTask(); tasks.add(task); task.start(); } - for (int threadIndex = 0; threadIndex < 8; threadIndex++) { + for (int threadIndex = 0; threadIndex < 5; threadIndex++) { CreateTask task = new CreateTask(); tasks.add(task); task.start(); @@ -89,6 +122,10 @@ public class StressTestDstu3Test extends BaseResourceProviderDstu3Test { } } + validateNoErrors(tasks); + } + + private void validateNoErrors(List tasks) { int total = 0; for (BaseTask next : tasks) { if (next.getError() != null) { @@ -127,16 +164,37 @@ public class StressTestDstu3Test extends BaseResourceProviderDstu3Test { @Override public void run() { - CloseableHttpResponse get = null; - for (int i = 0; i < 20; i++) { + CloseableHttpResponse getResp = null; + for (int i = 0; i < 10; i++) { try { - get = ourHttpClient.execute(new HttpGet(ourServerBase + "/Patient?identifier=http%3A%2F%2Ftest%7CBAR," + UUID.randomUUID().toString())); + Bundle respBundle; + + // Load search + HttpGet get = new HttpGet(ourServerBase + "/Patient?identifier=http%3A%2F%2Ftest%7CBAR," + UUID.randomUUID().toString()); + get.addHeader(Constants.HEADER_CONTENT_TYPE, Constants.CT_FHIR_JSON_NEW); + getResp = ourHttpClient.execute(get); try { - assertEquals(200, get.getStatusLine().getStatusCode()); + assertEquals(200, getResp.getStatusLine().getStatusCode()); + String respBundleString = IOUtils.toString(getResp.getEntity().getContent(), Charsets.UTF_8); + respBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, respBundleString); myTaskCount++; } finally { - IOUtils.closeQuietly(get); + IOUtils.closeQuietly(getResp); } + + // Load page 2 + get = new HttpGet(respBundle.getLink("next").getUrl()); + get.addHeader(Constants.HEADER_CONTENT_TYPE, Constants.CT_FHIR_JSON_NEW); + getResp = ourHttpClient.execute(get); + try { + assertEquals(200, getResp.getStatusLine().getStatusCode()); + String respBundleString = IOUtils.toString(getResp.getEntity().getContent(), Charsets.UTF_8); + respBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, respBundleString); + myTaskCount++; + } finally { + IOUtils.closeQuietly(getResp); + } + } catch (Throwable e) { ourLog.error("Failure during search", e); myError = e; diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamTest.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamDstu2Test.java similarity index 67% rename from hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamTest.java rename to hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamDstu2Test.java index b8a29bda234..988403e51ac 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamTest.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamDstu2Test.java @@ -1,19 +1,18 @@ package ca.uhn.fhir.rest.param; -import static org.junit.Assert.*; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.model.dstu.composite.CodingDt; -import ca.uhn.fhir.rest.method.QualifiedParamList; -import ca.uhn.fhir.util.TestUtil; - -import org.junit.AfterClass; -import org.junit.Test; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; -public class TokenOrListParamTest { +import org.junit.AfterClass; +import org.junit.Test; + +import ca.uhn.fhir.model.dstu2.composite.CodingDt; +import ca.uhn.fhir.util.TestUtil; + +public class TokenOrListParamDstu2Test { @Test public void testWhenParamListHasAnyMatchingCodingsForCodingList_doesCodingListMatch_shouldBeTrue() { TokenOrListParam params = new TokenOrListParam(); @@ -53,22 +52,6 @@ public class TokenOrListParamTest { assertFalse(params.doesCodingListMatch(codings)); } - /** - * See #192 - */ - @Test - public void testParseExcaped() { - TokenOrListParam params = new TokenOrListParam(); - params.setValuesAsQueryTokens(ourCtx, null, QualifiedParamList.singleton("system|code-include-but-not-end-with-comma\\,suffix")); - - assertEquals(1, params.getListAsCodings().size()); - assertEquals("system", params.getListAsCodings().get(0).getSystemElement().getValue()); - assertEquals("code-include-but-not-end-with-comma,suffix", params.getListAsCodings().get(0).getCodeElement().getValue()); - } - - - private static FhirContext ourCtx = FhirContext.forDstu1(); - @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/ConceptMap.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/ConceptMap.java index ebb30d41722..7133530ea7a 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/ConceptMap.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/model/ConceptMap.java @@ -47,7 +47,8 @@ import org.hl7.fhir.exceptions.FHIRException; * A statement of relationships from one set of concepts to one or more other concepts - either code systems or data elements, or classes in class models. */ @ResourceDef(name="ConceptMap", profile="http://hl7.org/fhir/Profile/ConceptMap") -@ChildOrder(names={"url", "identifier", "version", "name", "title", "status", "experimental", "date", "publisher", "contact", "description", "useContext", "jurisdiction", "purpose", "copyright", "source[x]", "target[x]", "group"}) +//@ChildOrder(names={"url", "identifier", "version", "name", "title", "status", "experimental", "date", "publisher", "contact", "description", "useContext", "jurisdiction", "purpose", "copyright", "source[x]", "target[x]", "group"}) +@ChildOrder(names={"url", "identifier", "version", "name", "title", "status", "experimental", "date", "publisher", "contact", "description", "useContext", "jurisdiction", "purpose", "copyright", "source", "target", "group"}) public class ConceptMap extends MetadataResource { public enum ConceptMapGroupUnmappedMode { diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/CustomResource364Dstu3.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/CustomResource364Dstu3.java index 243f78334ac..1a01e58cf48 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/CustomResource364Dstu3.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/CustomResource364Dstu3.java @@ -1,17 +1,10 @@ package ca.uhn.fhir.parser; -import org.hl7.fhir.dstu3.model.DateTimeType; -import org.hl7.fhir.dstu3.model.DomainResource; -import org.hl7.fhir.dstu3.model.ResourceType; -import org.hl7.fhir.dstu3.model.Type; -import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; +import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.instance.model.api.ICompositeType; import ca.uhn.fhir.context.FhirVersionEnum; -import ca.uhn.fhir.model.api.IElement; -import ca.uhn.fhir.model.api.annotation.Child; -import ca.uhn.fhir.model.api.annotation.DatatypeDef; -import ca.uhn.fhir.model.api.annotation.ResourceDef; +import ca.uhn.fhir.model.api.annotation.*; import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.util.ElementUtil; diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java index 6a4969af012..0eecb5ccca3 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java @@ -31,6 +31,8 @@ import java.util.*; import org.apache.commons.io.IOUtils; import org.hamcrest.Matchers; import org.hamcrest.core.StringContains; +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.dstu3.model.Address.AddressUse; import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory; @@ -42,6 +44,7 @@ import org.hl7.fhir.dstu3.model.Enumeration; import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender; import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse; import org.hl7.fhir.dstu3.model.Observation.ObservationStatus; +import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.junit.*; @@ -59,8 +62,7 @@ import ca.uhn.fhir.parser.XmlParserDstu3Test.TestPatientFor327; import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType; import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType; import ca.uhn.fhir.util.TestUtil; -import ca.uhn.fhir.validation.FhirValidator; -import ca.uhn.fhir.validation.ValidationResult; +import ca.uhn.fhir.validation.*; import net.sf.json.*; public class JsonParserDstu3Test { @@ -71,6 +73,78 @@ public class JsonParserDstu3Test { public void after() { ourCtx.setNarrativeGenerator(null); } + + @Test + public void testActivityDefinitionElementsOrder() throws Exception { + final String origContent = "{\"resourceType\":\"ActivityDefinition\",\"id\":\"x1\",\"url\":\"http://testing.org\",\"status\":\"draft\",\"timingDateTime\":\"2011-02-03\"}"; + final IParser parser = ourCtx.newJsonParser(); + DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport(); + + // verify that InstanceValidator likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, origContent); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + ActivityDefinition fhirObj = parser.parseResource(ActivityDefinition.class, origContent); + String content = parser.encodeResourceToString(fhirObj); + ourLog.info("Serialized form: {}", content); + + // verify that InstanceValidator still likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, content); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + // verify that the original and newly serialized match + Assert.assertEquals(origContent, content); + } + + @Test + public void testConceptMapElementsOrder() throws Exception { + final String origContent = "{\"resourceType\":\"ConceptMap\",\"id\":\"x1\",\"url\":\"http://testing.org\",\"status\":\"draft\",\"sourceUri\":\"http://y1\"}"; + final IParser parser = ourCtx.newJsonParser(); + DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport(); + + // verify that InstanceValidator likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, origContent); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + ConceptMap fhirObj = parser.parseResource(ConceptMap.class, origContent); + String content = parser.encodeResourceToString(fhirObj); + ourLog.info("Serialized form: {}", content); + + // verify that InstanceValidator still likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, content); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + // verify that the original and newly serialized match + Assert.assertEquals(origContent, content); + } /** * See #563 diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java index dc291fdaf42..0da4e8804bc 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/XmlParserDstu3Test.java @@ -34,6 +34,8 @@ import org.custommonkey.xmlunit.XMLUnit; import org.hamcrest.collection.IsEmptyCollection; import org.hamcrest.core.StringContains; import org.hamcrest.text.StringContainsInOrder; +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.dstu3.model.Address.AddressUse; import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory; @@ -64,6 +66,10 @@ import ca.uhn.fhir.parser.IParserErrorHandler.IParseLocation; import ca.uhn.fhir.parser.PatientWithCustomCompositeExtension.FooParentExtension; import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.util.TestUtil; +import ca.uhn.fhir.validation.IValidationContext; +import ca.uhn.fhir.validation.SingleValidationMessage; +import ca.uhn.fhir.validation.ValidationContext; +import ca.uhn.fhir.validation.ValidationResult; public class XmlParserDstu3Test { private static FhirContext ourCtx = FhirContext.forDstu3(); @@ -76,7 +82,7 @@ public class XmlParserDstu3Test { } ourCtx.setNarrativeGenerator(null); } - + /** * See #544 */ @@ -104,7 +110,7 @@ public class XmlParserDstu3Test { assertNotNull(subject); assertEquals("FAMILY", subject.getNameFirstRep().getFamily()); } - + @Test public void testBundleWithBinary() { @@ -135,6 +141,81 @@ public class XmlParserDstu3Test { } + /** + * See #683 + */ + @Test + public void testChildOrderWithChoiceType() throws Exception { + final String origContent = ""; + final IParser parser = ourCtx.newXmlParser(); + DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport(); + + // verify that InstanceValidator likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, origContent); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + ActivityDefinition fhirObj = parser.parseResource(ActivityDefinition.class, origContent); + String content = parser.encodeResourceToString(fhirObj); + ourLog.info("Serialized form: {}", content); + + // verify that InstanceValidator still likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, content); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + // verify that the original and newly serialized match + Assert.assertEquals(origContent, content); + } + + @Test + public void testConceptMapElementsOrder() throws Exception { + final String origContent = ""; + final IParser parser = ourCtx.newXmlParser(); + DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport(); + + // verify that InstanceValidator likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, origContent); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + ConceptMap fhirObj = parser.parseResource(ConceptMap.class, origContent); + String content = parser.encodeResourceToString(fhirObj); + ourLog.info("Serialized form: {}", content); + + // verify that InstanceValidator still likes the format + { + IValidationContext validationCtx = ValidationContext.forText(ourCtx, content); + new FhirInstanceValidator(validationSupport).validateResource(validationCtx); + ValidationResult result = validationCtx.toResult(); + for (SingleValidationMessage msg : result.getMessages()) { + ourLog.info("{}", msg); + } + Assert.assertEquals(0, result.getMessages().size()); + } + + // verify that the original and newly serialized match + Assert.assertEquals(origContent, content); + } + @Test public void testContainedResourceInExtensionUndeclared() { Patient p = new Patient(); diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java similarity index 97% rename from hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java rename to hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java index a788e6bca3e..ae7dc877e7f 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/DateRangeParamTest.java @@ -5,10 +5,7 @@ import static org.junit.Assert.assertNotNull; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; +import java.util.*; import org.junit.AfterClass; import org.junit.Test; @@ -18,13 +15,15 @@ import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum; import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.InstantDt; -import ca.uhn.fhir.rest.method.QualifiedParamList; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.util.TestUtil; public class DateRangeParamTest { + private static FhirContext ourCtx = FhirContext.forDstu3(); private static final SimpleDateFormat ourFmt; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DateRangeParamTest.class); static { @@ -35,54 +34,6 @@ public class DateRangeParamTest { return new DateRangeParam(new DateParam(theString)); } - @Test - public void testRangeFromDates() { - TimeZone tz = TimeZone.getDefault(); - TimeZone.setDefault(TimeZone.getTimeZone("America/Toronto")); - try { - Date startDate = new InstantDt("2010-01-01T00:00:00.000Z").getValue(); - Date endDate = new InstantDt("2010-01-01T00:00:00.001Z").getValue(); - DateTimeDt startDateTime = new DateTimeDt(startDate, TemporalPrecisionEnum.MILLI); - DateTimeDt endDateTime = new DateTimeDt(endDate, TemporalPrecisionEnum.MILLI); - - DateRangeParam range = new DateRangeParam(startDateTime, endDateTime); - assertEquals("2009-12-31T19:00:00.000-05:00", range.getValuesAsQueryTokens().get(0).getValueAsString()); - assertEquals("2009-12-31T19:00:00.001-05:00", range.getValuesAsQueryTokens().get(1).getValueAsString()); - - // Now try with arguments reversed (should still create same range) - range = new DateRangeParam(endDateTime, startDateTime); - assertEquals("2009-12-31T19:00:00.000-05:00", range.getValuesAsQueryTokens().get(0).getValueAsString()); - assertEquals("2009-12-31T19:00:00.001-05:00", range.getValuesAsQueryTokens().get(1).getValueAsString()); - - } finally { - TimeZone.setDefault(tz); - } - } - - @Test - public void testRange() { - InstantDt start = new InstantDt("2015-09-23T07:43:34.811-04:00"); - InstantDt end = new InstantDt("2015-09-23T07:43:34.899-04:00"); - DateParam lowerBound = new DateParam(QuantityCompararatorEnum.GREATERTHAN, start.getValue()); - DateParam upperBound = new DateParam(QuantityCompararatorEnum.LESSTHAN, end.getValue()); - assertEquals(QuantityCompararatorEnum.GREATERTHAN, lowerBound.getComparator()); - assertEquals(QuantityCompararatorEnum.LESSTHAN, upperBound.getComparator()); - - /* - * When DateParam (which extends DateTimeDt) gets passed in, make sure we preserve the comparators.. - */ - DateRangeParam param = new DateRangeParam(lowerBound, upperBound); - ourLog.info(param.toString()); - assertEquals(QuantityCompararatorEnum.GREATERTHAN, param.getLowerBound().getComparator()); - assertEquals(QuantityCompararatorEnum.LESSTHAN, param.getUpperBound().getComparator()); - - param = new DateRangeParam(new DateTimeDt(lowerBound.getValue()), new DateTimeDt(upperBound.getValue())); - ourLog.info(param.toString()); - assertEquals(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, param.getLowerBound().getComparator()); - assertEquals(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, param.getUpperBound().getComparator()); - - } - @Test public void testAddAnd() { assertEquals(1, new DateAndListParam().addAnd(new DateOrListParam()).getValuesAsQueryTokens().size()); @@ -159,6 +110,54 @@ public class DateRangeParamTest { assertNotNull(new StringOrListParam().newInstance()); } + @Test + public void testRange() { + InstantDt start = new InstantDt("2015-09-23T07:43:34.811-04:00"); + InstantDt end = new InstantDt("2015-09-23T07:43:34.899-04:00"); + DateParam lowerBound = new DateParam(QuantityCompararatorEnum.GREATERTHAN, start.getValue()); + DateParam upperBound = new DateParam(QuantityCompararatorEnum.LESSTHAN, end.getValue()); + assertEquals(QuantityCompararatorEnum.GREATERTHAN, lowerBound.getComparator()); + assertEquals(QuantityCompararatorEnum.LESSTHAN, upperBound.getComparator()); + + /* + * When DateParam (which extends DateTimeDt) gets passed in, make sure we preserve the comparators.. + */ + DateRangeParam param = new DateRangeParam(lowerBound, upperBound); + ourLog.info(param.toString()); + assertEquals(QuantityCompararatorEnum.GREATERTHAN, param.getLowerBound().getComparator()); + assertEquals(QuantityCompararatorEnum.LESSTHAN, param.getUpperBound().getComparator()); + + param = new DateRangeParam(new DateTimeDt(lowerBound.getValue()), new DateTimeDt(upperBound.getValue())); + ourLog.info(param.toString()); + assertEquals(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, param.getLowerBound().getComparator()); + assertEquals(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, param.getUpperBound().getComparator()); + + } + + @Test + public void testRangeFromDates() { + TimeZone tz = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("America/Toronto")); + try { + Date startDate = new InstantDt("2010-01-01T00:00:00.000Z").getValue(); + Date endDate = new InstantDt("2010-01-01T00:00:00.001Z").getValue(); + DateTimeDt startDateTime = new DateTimeDt(startDate, TemporalPrecisionEnum.MILLI); + DateTimeDt endDateTime = new DateTimeDt(endDate, TemporalPrecisionEnum.MILLI); + + DateRangeParam range = new DateRangeParam(startDateTime, endDateTime); + assertEquals("2009-12-31T19:00:00.000-05:00", range.getValuesAsQueryTokens().get(0).getValueAsString()); + assertEquals("2009-12-31T19:00:00.001-05:00", range.getValuesAsQueryTokens().get(1).getValueAsString()); + + // Now try with arguments reversed (should still create same range) + range = new DateRangeParam(endDateTime, startDateTime); + assertEquals("2009-12-31T19:00:00.000-05:00", range.getValuesAsQueryTokens().get(0).getValueAsString()); + assertEquals("2009-12-31T19:00:00.001-05:00", range.getValuesAsQueryTokens().get(1).getValueAsString()); + + } finally { + TimeZone.setDefault(tz); + } + } + @Test public void testSecond() throws Exception { assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01T00:00:00", "<2011-01-01T01:00:00").getLowerBoundAsInstant()); @@ -177,6 +176,11 @@ public class DateRangeParamTest { assertEquals(parseM1("2014-01-01 00:00:00.0000"), create(">2011", "<=2013").getUpperBoundAsInstant()); } + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException { DateRangeParam p = new DateRangeParam(); List tokens = new ArrayList(); @@ -188,8 +192,6 @@ public class DateRangeParamTest { return p; } - private static FhirContext ourCtx = FhirContext.forDstu1(); - public static Date parse(String theString) throws ParseException { return ourFmt.parse(theString); } @@ -198,9 +200,4 @@ public class DateRangeParamTest { return new Date(ourFmt.parse(theString).getTime() - 1L); } - @AfterClass - public static void afterClassClearContext() { - TestUtil.clearAllStaticFieldsForUnitTest(); - } - } diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/NumberParamTest.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/NumberParamTest.java new file mode 100644 index 00000000000..d15fac757e0 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/NumberParamTest.java @@ -0,0 +1,76 @@ +package ca.uhn.fhir.rest.param; + +import static org.junit.Assert.assertEquals; + +import java.math.BigDecimal; + +import org.junit.AfterClass; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.util.TestUtil; + +public class NumberParamTest { + private static FhirContext ourCtx = FhirContext.forDstu3(); + + @Test + public void testFull() { + NumberParam p = new NumberParam(); + p.setValueAsQueryToken(ourCtx, null, null, "<5.4"); + assertEquals(ParamPrefixEnum.LESSTHAN, p.getPrefix()); + assertEquals("5.4", p.getValue().toPlainString()); + assertEquals("lt5.4", p.getValueAsQueryToken(ourCtx)); + } + + @Test + public void testApproximateLegacy() { + NumberParam p = new NumberParam(); + p.setValueAsQueryToken(ourCtx, null, null, "~5.4"); + assertEquals(null,p.getComparator()); + assertEquals(ParamPrefixEnum.APPROXIMATE, p.getPrefix()); + assertEquals("5.4", p.getValue().toPlainString()); + assertEquals("ap5.4", p.getValueAsQueryToken(ourCtx)); + } + + @Test + public void testApproximate() { + NumberParam p = new NumberParam(); + p.setValueAsQueryToken(ourCtx, null, null, "ap5.4"); + assertEquals(null,p.getComparator()); + assertEquals(ParamPrefixEnum.APPROXIMATE, p.getPrefix()); + assertEquals("5.4", p.getValue().toPlainString()); + assertEquals("ap5.4", p.getValueAsQueryToken(ourCtx)); + } + + @Test + public void testNoQualifier() { + NumberParam p = new NumberParam(); + p.setValueAsQueryToken(ourCtx, null, null, "5.4"); + assertEquals(null, p.getComparator()); + assertEquals(null, p.getPrefix()); + assertEquals("5.4", p.getValue().toPlainString()); + assertEquals("5.4", p.getValueAsQueryToken(ourCtx)); + } + + + /** + * See #696 + */ + @Test + public void testNegativeNumber() { + NumberParam p = new NumberParam(); + p.setValueAsQueryToken(ourCtx, null, null, "-5.4"); + assertEquals(null, p.getComparator()); + assertEquals(null, p.getPrefix()); + assertEquals("-5.4", p.getValue().toPlainString()); + assertEquals(new BigDecimal("-5.4"), p.getValue()); + assertEquals("-5.4", p.getValueAsQueryToken(ourCtx)); + } + + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + +} diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/QuantityParamTest.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/QuantityParamTest.java similarity index 53% rename from hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/QuantityParamTest.java rename to hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/QuantityParamTest.java index 0784dc19a0b..853560b722e 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/QuantityParamTest.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/QuantityParamTest.java @@ -2,6 +2,8 @@ package ca.uhn.fhir.rest.param; import static org.junit.Assert.*; +import java.math.BigDecimal; + import org.junit.AfterClass; import org.junit.Test; @@ -10,37 +12,52 @@ import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum; import ca.uhn.fhir.util.TestUtil; public class QuantityParamTest { - private static FhirContext ourCtx = FhirContext.forDstu1(); + private static FhirContext ourCtx = FhirContext.forDstu3(); @Test public void testFull() { QuantityParam p = new QuantityParam(); p.setValueAsQueryToken(ourCtx, null, null, "<5.4|http://unitsofmeasure.org|mg"); assertEquals(QuantityCompararatorEnum.LESSTHAN,p.getComparator()); + assertEquals(ParamPrefixEnum.LESSTHAN, p.getPrefix()); assertEquals("5.4", p.getValue().toPlainString()); assertEquals("http://unitsofmeasure.org", p.getSystem()); assertEquals("mg", p.getUnits()); - assertEquals("<5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken(ourCtx)); + assertEquals("lt5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken(ourCtx)); + } + + @Test + public void testApproximateLegacy() { + QuantityParam p = new QuantityParam(); + p.setValueAsQueryToken(ourCtx, null, null, "~5.4|http://unitsofmeasure.org|mg"); + assertEquals(null,p.getComparator()); + assertEquals(ParamPrefixEnum.APPROXIMATE, p.getPrefix()); + assertEquals(true, p.isApproximate()); + assertEquals("5.4", p.getValue().toPlainString()); + assertEquals("http://unitsofmeasure.org", p.getSystem()); + assertEquals("mg", p.getUnits()); + assertEquals("ap5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken(ourCtx)); } @Test public void testApproximate() { QuantityParam p = new QuantityParam(); - p.setValueAsQueryToken(ourCtx, null, null, "~5.4|http://unitsofmeasure.org|mg"); + p.setValueAsQueryToken(ourCtx, null, null, "ap5.4|http://unitsofmeasure.org|mg"); assertEquals(null,p.getComparator()); + assertEquals(ParamPrefixEnum.APPROXIMATE, p.getPrefix()); assertEquals(true, p.isApproximate()); assertEquals("5.4", p.getValue().toPlainString()); assertEquals("http://unitsofmeasure.org", p.getSystem()); assertEquals("mg", p.getUnits()); - assertEquals("~5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken(ourCtx)); + assertEquals("ap5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken(ourCtx)); } - @Test public void testNoQualifier() { QuantityParam p = new QuantityParam(); p.setValueAsQueryToken(ourCtx, null, null, "5.4|http://unitsofmeasure.org|mg"); assertEquals(null, p.getComparator()); + assertEquals(null, p.getPrefix()); assertEquals("5.4", p.getValue().toPlainString()); assertEquals("http://unitsofmeasure.org", p.getSystem()); assertEquals("mg", p.getUnits()); @@ -53,6 +70,7 @@ public class QuantityParamTest { QuantityParam p = new QuantityParam(); p.setValueAsQueryToken(ourCtx, null, null, "5.4"); assertEquals(null, p.getComparator()); + assertEquals(null, p.getPrefix()); assertEquals("5.4", p.getValue().toPlainString()); assertEquals(null, p.getSystem()); assertEquals(null, p.getUnits()); @@ -84,6 +102,54 @@ public class QuantityParamTest { assertEquals("mg", param.getUnits()); } + /** + * See #696 + */ + @Test + public void testNegativeQuantityWithUnits() { + QuantityParam p = new QuantityParam(); + p.setValueAsQueryToken(ourCtx, null, null, "-5.4|http://unitsofmeasure.org|mg"); + assertEquals(null, p.getComparator()); + assertEquals(null, p.getPrefix()); + assertEquals("-5.4", p.getValue().toPlainString()); + assertEquals(new BigDecimal("-5.4"), p.getValue()); + assertEquals("http://unitsofmeasure.org", p.getSystem()); + assertEquals("mg", p.getUnits()); + assertEquals("-5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken(ourCtx)); + } + + /** + * See #696 + */ + @Test + public void testNegativeQuantityWithoutUnits() { + QuantityParam p = new QuantityParam(); + p.setValueAsQueryToken(ourCtx, null, null, "-5.4"); + assertEquals(null, p.getComparator()); + assertEquals(null, p.getPrefix()); + assertEquals("-5.4", p.getValue().toPlainString()); + assertEquals(new BigDecimal("-5.4"), p.getValue()); + assertEquals(null, p.getSystem()); + assertEquals(null, p.getUnits()); + assertEquals("-5.4||", p.getValueAsQueryToken(ourCtx)); + } + + /** + * See #696 + */ + @Test + public void testNegativeQuantityWithoutUnitsWithComparator() { + QuantityParam p = new QuantityParam(); + p.setValueAsQueryToken(ourCtx, null, null, "gt-5.4"); + assertEquals(QuantityCompararatorEnum.GREATERTHAN, p.getComparator()); + assertEquals(ParamPrefixEnum.GREATERTHAN, p.getPrefix()); + assertEquals("-5.4", p.getValue().toPlainString()); + assertEquals(new BigDecimal("-5.4"), p.getValue()); + assertEquals(null, p.getSystem()); + assertEquals(null, p.getUnits()); + assertEquals("gt-5.4||", p.getValueAsQueryToken(ourCtx)); + } + @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/ReferenceParamTest.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/ReferenceParamTest.java similarity index 94% rename from hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/ReferenceParamTest.java rename to hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/ReferenceParamTest.java index 616b2c84875..e67d644dcf3 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/param/ReferenceParamTest.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/ReferenceParamTest.java @@ -10,15 +10,7 @@ import ca.uhn.fhir.util.TestUtil; public class ReferenceParamTest { - @Test - public void testWithResourceTypeAsQualifier() { - - ReferenceParam rp = new ReferenceParam(); - rp.setValueAsQueryToken(ourCtx, null, ":Location", "123"); - assertEquals("Location", rp.getResourceType()); - assertEquals("123", rp.getIdPart()); - - } + private FhirContext ourCtx = FhirContext.forDstu3(); @Test public void testWithResourceType() { @@ -30,7 +22,15 @@ public class ReferenceParamTest { } - private FhirContext ourCtx = FhirContext.forDstu1(); + @Test + public void testWithResourceTypeAsQualifier() { + + ReferenceParam rp = new ReferenceParam(); + rp.setValueAsQueryToken(ourCtx, null, ":Location", "123"); + assertEquals("Location", rp.getResourceType()); + assertEquals("123", rp.getIdPart()); + + } @AfterClass public static void afterClassClearContext() { diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamDstu3Test.java new file mode 100644 index 00000000000..5bb72a72ef3 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/param/TokenOrListParamDstu3Test.java @@ -0,0 +1,34 @@ +package ca.uhn.fhir.rest.param; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.QualifiedParamList; +import ca.uhn.fhir.util.TestUtil; + +public class TokenOrListParamDstu3Test { + + private static FhirContext ourCtx = FhirContext.forDstu3(); + + /** + * See #192 + */ + @Test + public void testParseExcaped() { + TokenOrListParam params = new TokenOrListParam(); + params.setValuesAsQueryTokens(ourCtx, null, QualifiedParamList.singleton("system|code-include-but-not-end-with-comma\\,suffix")); + + assertEquals(1, params.getListAsCodings().size()); + assertEquals("system", params.getListAsCodings().get(0).getSystemElement().getValue()); + assertEquals("code-include-but-not-end-with-comma,suffix", params.getListAsCodings().get(0).getCodeElement().getValue()); + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + +} diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/DefaultProfileValidationSupport.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java similarity index 95% rename from hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/DefaultProfileValidationSupport.java rename to hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java index 2f7c41757e1..1961fa84b46 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/DefaultProfileValidationSupport.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r4.hapi.validation; +package org.hl7.fhir.r4.hapi.ctx; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -68,9 +68,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport { codeSystems = new HashMap(); valueSets = new HashMap(); - loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/instance/model/dstu3/valueset/valuesets.xml"); - loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/instance/model/dstu3/valueset/v2-tables.xml"); - loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/instance/model/dstu3/valueset/v3-codesystems.xml"); + loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/r4/model/valueset/valuesets.xml"); + loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/r4/model/valueset/v2-tables.xml"); + loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/r4/model/valueset/v3-codesystems.xml"); myCodeSystems = codeSystems; myValueSets = valueSets; @@ -184,9 +184,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport { if (structureDefinitions == null) { structureDefinitions = new HashMap(); - loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/instance/model/dstu3/profile/profiles-resources.xml"); - loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/instance/model/dstu3/profile/profiles-types.xml"); - loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/instance/model/dstu3/profile/profiles-others.xml"); + loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-resources.xml"); + loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-types.xml"); + loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-others.xml"); myStructureDefinitions = structureDefinitions; } diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/FhirR4.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/FhirR4.java index 3341cafa242..9340fc10bde 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/FhirR4.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/FhirR4.java @@ -28,7 +28,6 @@ import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.r4.hapi.fluentpath.FluentPathR4; import org.hl7.fhir.r4.hapi.rest.server.R4BundleFactory; -import org.hl7.fhir.r4.hapi.validation.DefaultProfileValidationSupport; import org.hl7.fhir.r4.model.*; import ca.uhn.fhir.context.*; @@ -41,89 +40,90 @@ import ca.uhn.fhir.util.ReflectionUtil; public class FhirR4 implements IFhirVersion { - private String myId; + private String myId; - @Override - public IFluentPath createFluentPathExecutor(FhirContext theFhirContext) { - return new FluentPathR4(theFhirContext); - } + @Override + public IFluentPath createFluentPathExecutor(FhirContext theFhirContext) { + return new FluentPathR4(theFhirContext); + } - @Override - public IContextValidationSupport createValidationSupport() { - return new DefaultProfileValidationSupport(); - } + @Override + public IContextValidationSupport createValidationSupport() { + return ReflectionUtil.newInstanceOfFhirProfileValidationSupport("org.hl7.fhir.r4.hapi.validation.DefaultProfileValidationSupport"); + } - @Override - public IBaseResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition, String theServerBase) { - StructureDefinition retVal = new StructureDefinition(); + @Override + public IBaseResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition, String theServerBase) { + StructureDefinition retVal = new StructureDefinition(); - RuntimeResourceDefinition def = theRuntimeResourceDefinition; + RuntimeResourceDefinition def = theRuntimeResourceDefinition; - myId = def.getId(); - if (StringUtils.isBlank(myId)) { - myId = theRuntimeResourceDefinition.getName().toLowerCase(); - } + myId = def.getId(); + if (StringUtils.isBlank(myId)) { + myId = theRuntimeResourceDefinition.getName().toLowerCase(); + } - retVal.setId(new IdDt(myId)); - return retVal; - } + retVal.setId(new IdDt(myId)); + return retVal; + } - @SuppressWarnings("rawtypes") - @Override - public Class getContainedType() { - return List.class; - } + @SuppressWarnings("rawtypes") + @Override + public Class getContainedType() { + return List.class; + } - @Override - public InputStream getFhirVersionPropertiesFile() { - InputStream str = FhirR4.class.getResourceAsStream("/org/hl7/fhir/r4/model/fhirversion.properties"); - if (str == null) { - str = FhirR4.class.getResourceAsStream("/org/hl7/fhir/r4/model/fhirversion.properties"); - } - if (str == null) { - throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/r4/fhirversion.properties"); - } - return str; - } + @Override + public InputStream getFhirVersionPropertiesFile() { + String path = "org/hl7/fhir/r4/model/fhirversion.properties"; + InputStream str = FhirR4.class.getResourceAsStream("/" + path); + if (str == null) { + str = FhirR4.class.getResourceAsStream(path); + } + if (str == null) { + throw new ConfigurationException("Can not find model property file on classpath: " + path); + } + return str; + } - @Override - public IPrimitiveType getLastUpdated(IBaseResource theResource) { - return ((Resource) theResource).getMeta().getLastUpdatedElement(); - } + @Override + public IPrimitiveType getLastUpdated(IBaseResource theResource) { + return ((Resource) theResource).getMeta().getLastUpdatedElement(); + } - @Override - public String getPathToSchemaDefinitions() { - return "/org/hl7/fhir/instance/model/dstu3/schema"; - } + @Override + public String getPathToSchemaDefinitions() { + return "/org/hl7/fhir/r4/model/schema"; + } - @Override - public Class getResourceReferenceType() { - return Reference.class; - } + @Override + public Class getResourceReferenceType() { + return Reference.class; + } - @Override - public Object getServerVersion() { - return ReflectionUtil.newInstanceOfFhirServerType("org.hl7.fhir.dstu3.hapi.ctx.FhirServerDstu3"); - } + @Override + public Object getServerVersion() { + return ReflectionUtil.newInstanceOfFhirServerType("org.hl7.fhir.r4.hapi.ctx.FhirServerR4"); + } - @Override - public FhirVersionEnum getVersion() { - return FhirVersionEnum.R4; - } + @Override + public FhirVersionEnum getVersion() { + return FhirVersionEnum.R4; + } - @Override - public IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext) { - return new R4BundleFactory(theContext); - } + @Override + public IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext) { + return new R4BundleFactory(theContext); + } - @Override - public IBaseCoding newCodingDt() { - return new Coding(); - } + @Override + public IBaseCoding newCodingDt() { + return new Coding(); + } - @Override - public IIdType newIdType() { - return new IdType(); - } + @Override + public IIdType newIdType() { + return new IdType(); + } } diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/HapiWorkerContext.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/HapiWorkerContext.java similarity index 98% rename from hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/HapiWorkerContext.java rename to hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/HapiWorkerContext.java index 60fc60ca9cd..da298fc702d 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/HapiWorkerContext.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/HapiWorkerContext.java @@ -1,19 +1,17 @@ -package org.hl7.fhir.r4.hapi.validation; +package org.hl7.fhir.r4.hapi.ctx; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.util.*; -import javax.annotation.Resource; - import org.apache.commons.lang3.Validate; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.TerminologyServiceException; import org.hl7.fhir.r4.context.IWorkerContext; import org.hl7.fhir.r4.formats.IParser; import org.hl7.fhir.r4.formats.ParserType; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport.CodeValidationResult; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport.CodeValidationResult; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionBindingComponent; diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/IValidationSupport.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/IValidationSupport.java similarity index 98% rename from hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/IValidationSupport.java rename to hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/IValidationSupport.java index 4b86f3a632a..950269ed213 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/IValidationSupport.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/IValidationSupport.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r4.hapi.validation; +package org.hl7.fhir.r4.hapi.ctx; import java.util.List; diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/PrePopulatedValidationSupport.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/PrePopulatedValidationSupport.java similarity index 99% rename from hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/PrePopulatedValidationSupport.java rename to hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/PrePopulatedValidationSupport.java index 5d062b9aa17..7545997ff31 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/PrePopulatedValidationSupport.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/PrePopulatedValidationSupport.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r4.hapi.validation; +package org.hl7.fhir.r4.hapi.ctx; import static org.apache.commons.lang3.StringUtils.isNotBlank; diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/ValidationSupportChain.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/ValidationSupportChain.java similarity index 98% rename from hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/ValidationSupportChain.java rename to hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/ValidationSupportChain.java index 34794d55c9a..64d29bf119f 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/ValidationSupportChain.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/ValidationSupportChain.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r4.hapi.validation; +package org.hl7.fhir.r4.hapi.ctx; import static org.apache.commons.lang3.StringUtils.isBlank; diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/fluentpath/FluentPathR4.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/fluentpath/FluentPathR4.java index b801605c27b..ae5dcbba6a7 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/fluentpath/FluentPathR4.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/fluentpath/FluentPathR4.java @@ -4,8 +4,8 @@ import java.util.List; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBase; -import org.hl7.fhir.r4.hapi.validation.HapiWorkerContext; -import org.hl7.fhir.r4.hapi.validation.IValidationSupport; +import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext; +import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.model.Base; import org.hl7.fhir.r4.utils.FHIRPathEngine; diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/InstanceValidator.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/InstanceValidator.java deleted file mode 100644 index 9c89dbcd813..00000000000 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/InstanceValidator.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.hl7.fhir.r4.hapi.validation; - -import java.util.List; - -import org.hl7.fhir.r4.model.StructureDefinition; -import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.r4.utils.IResourceValidator.BestPracticeWarningLevel; -import org.hl7.fhir.r4.utils.IResourceValidator.IdStatus; -import org.hl7.fhir.utilities.validation.ValidationMessage; -import org.w3c.dom.Document; - -import com.google.gson.JsonObject; - -public class InstanceValidator { - - public InstanceValidator(HapiWorkerContext theWorkerContext, IEvaluationContext theEvaluationCtx) { - throw new Error(); - } - - public void setBestPracticeWarningLevel(BestPracticeWarningLevel theBestPracticeWarningLevel) { - throw new Error(); - } - - public void setAnyExtensionsAllowed(boolean theAnyExtensionsAllowed) { - throw new Error(); - } - - public void setResourceIdRule(IdStatus theOptional) { - throw new Error(); - } - - public void validate(Object theObject, List theMessages, Document theDocument, StructureDefinition theProfile) { - throw new Error(); - } - - public void validate(Object theObject, List theMessages, JsonObject theJson, StructureDefinition theProfile) { - throw new Error(); - } - -} diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/utils/NarrativeGenerator.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/utils/NarrativeGenerator.java index 86cb4a71853..c6209cb4be4 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/utils/NarrativeGenerator.java +++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/utils/NarrativeGenerator.java @@ -167,7 +167,6 @@ import org.hl7.fhir.utilities.xml.XmlGenerator; import org.w3c.dom.Element; import com.github.rjeschke.txtmark.Processor; -import com.sun.webkit.BackForwardList; public class NarrativeGenerator implements INarrativeGenerator { diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/CustomResource364R4.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/CustomResource364R4.java new file mode 100644 index 00000000000..2ce2ba853d8 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/CustomResource364R4.java @@ -0,0 +1,92 @@ +package ca.uhn.fhir.parser; + +import org.hl7.fhir.instance.model.api.ICompositeType; +import org.hl7.fhir.r4.model.*; + +import ca.uhn.fhir.context.FhirVersionEnum; +import ca.uhn.fhir.model.api.annotation.*; +import ca.uhn.fhir.model.primitive.DateTimeDt; +import ca.uhn.fhir.util.ElementUtil; + +/** + * This is an example of a custom resource that also uses a custom + * datatype. + * + * See #364 + */ +@ResourceDef(name = "CustomResource", profile = "http://hl7.org/fhir/profiles/custom-resource", id = "custom-resource") +public class CustomResource364R4 extends DomainResource { + + private static final long serialVersionUID = 1L; + + @Child(name = "baseValue", min = 1, max = Child.MAX_UNLIMITED, type= {}) + private Type baseValues; + + public Type getBaseValues() { + return baseValues; + } + + + @Override + public FhirVersionEnum getStructureFhirVersionEnum() { + return FhirVersionEnum.R4; + } + + @Override + public boolean isEmpty() { + return ElementUtil.isEmpty(baseValues); + } + + public void setBaseValues(Type theValue) { + this.baseValues = theValue; + } + + @DatatypeDef(name="CustomDate") + public static class CustomResource364CustomDate extends Type implements ICompositeType { + + private static final long serialVersionUID = 1L; + + @Child(name = "date", order = 0, min = 1, max = 1, type = { DateTimeDt.class }) + private DateTimeType date; + + + public DateTimeType getDate() { + if (date == null) + date = new DateTimeType(); + return date; + } + + @Override + public boolean isEmpty() { + return ElementUtil.isEmpty(date); + } + + public CustomResource364CustomDate setDate(DateTimeType theValue) { + date = theValue; + return this; + } + + @Override + protected CustomResource364CustomDate typedCopy() { + CustomResource364CustomDate retVal = new CustomResource364CustomDate(); + super.copyValues(retVal); + retVal.date = date; + return retVal; + } + } + + @Override + public CustomResource364R4 copy() { + CustomResource364R4 retVal = new CustomResource364R4(); + super.copyValues(retVal); + retVal.baseValues = baseValues; + return retVal; + } + + + @Override + public ResourceType getResourceType() { + return null; + } + +} \ No newline at end of file diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/CustomTypeR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/CustomTypeR4Test.java new file mode 100644 index 00000000000..7e4b6bde851 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/CustomTypeR4Test.java @@ -0,0 +1,647 @@ +package ca.uhn.fhir.parser; + +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.stringContainsInOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.List; + +import org.hl7.fhir.instance.model.api.IBase; +import org.hl7.fhir.r4.model.*; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.api.AddProfileTagEnum; +import ca.uhn.fhir.model.api.annotation.*; +import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.model.primitive.DateTimeDt; +import ca.uhn.fhir.model.primitive.StringDt; +import ca.uhn.fhir.parser.CustomResource364R4.CustomResource364CustomDate; +import ca.uhn.fhir.util.ElementUtil; +import ca.uhn.fhir.util.TestUtil; + +public class CustomTypeR4Test { + + private static FhirContext ourCtx = FhirContext.forR4(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CustomTypeR4Test.class); + + @Before + public void before() { + ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.ONLY_FOR_CUSTOM); + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @SuppressWarnings("serial") + @ResourceDef + public static class PatientWithExtensionWithTwoTypes extends Patient { + @Child(name = "foo", type = { DateTimeType.class, Period.class }, min = 0, max = 1) + @Extension(url = "http://example.com/extension#foo", definedLocally = true, isModifier = false) + @Description(shortDefinition = "Some description") + private Type foo; + + public Type getFoo() { + return foo; + } + + public void setFoo(Type theFoo) { + foo = theFoo; + } + } + + @Test + public void testExtensionWithTwoTypes() { + PatientWithExtensionWithTwoTypes pt = new PatientWithExtensionWithTwoTypes(); + pt.setFoo(new DateTimeType("2011-01-01T00:00:00Z")); + + String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(pt); + ourLog.info(encoded); + + pt = ourCtx.newXmlParser().parseResource(PatientWithExtensionWithTwoTypes.class, encoded); + assertEquals("2011-01-01T00:00:00Z", ((DateTimeType)pt.getFoo()).getValueAsString()); + } + + @SuppressWarnings("serial") + @ResourceDef + public static class PatientWithExtensionWithOneTypes extends Patient { + @Child(name = "foo", type = { DateTimeType.class }, min = 0, max = 1) + @Extension(url = "http://example.com/extension#foo", definedLocally = true, isModifier = false) + @Description(shortDefinition = "Some description") + private Type foo; + + public Type getFoo() { + return foo; + } + + public void setFoo(Type theFoo) { + foo = theFoo; + } + } + + @Test + public void testExtensionWithOneTypes() { + PatientWithExtensionWithOneTypes pt = new PatientWithExtensionWithOneTypes(); + pt.setFoo(new DateTimeType("2011-01-01T00:00:00Z")); + + String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(pt); + ourLog.info(encoded); + + pt = ourCtx.newXmlParser().parseResource(PatientWithExtensionWithOneTypes.class, encoded); + assertEquals("2011-01-01T00:00:00Z", ((DateTimeType)pt.getFoo()).getValueAsString()); + } + + /** + * See #364 + */ + @Test + public void testCustomTypeWithCustomDatatype() { + FhirContext context = FhirContext.forR4(); + context.registerCustomType(CustomResource364R4.class); + context.registerCustomType(CustomResource364CustomDate.class); + IParser parser = context.newXmlParser(); + + CustomResource364R4 resource = new CustomResource364R4(); + resource.setBaseValues(new CustomResource364CustomDate().setDate(new DateTimeType("2016-05-13"))); + + String xml = parser.encodeResourceToString(resource); + ourLog.info(xml); + + //@formatter:on + assertThat(xml, stringContainsInOrder( + "", + "", + "", + "")); + //@formatter:on + + CustomResource364R4 parsedResource = parser.parseResource(CustomResource364R4.class, xml); + assertEquals("2016-05-13", ((CustomResource364CustomDate) parsedResource.getBaseValues()).getDate().getValueAsString()); + } + + /** + * See #364 + */ + @Test + public void testCustomTypeWithPrimitiveType() { + FhirContext context = FhirContext.forR4(); + context.registerCustomTypes(new ArrayList>()); + + IParser parser = context.newXmlParser(); + + CustomResource364R4 resource = new CustomResource364R4(); + resource.setBaseValues(new StringType("2016-05-13")); + + String xml = parser.encodeResourceToString(resource); + + //@formatter:on + assertThat(xml, stringContainsInOrder( + "", + "", + "", + "")); + //@formatter:on + + CustomResource364R4 parsedResource = parser.parseResource(CustomResource364R4.class, xml); + assertEquals("2016-05-13", ((StringType) parsedResource.getBaseValues()).getValueAsString()); + } + + @Test + public void parseBundleWithResourceDirective() { + String input = createBundle(createResource(false), createResource(true)); + + FhirContext ctx = FhirContext.forR4(); + ctx.setDefaultTypeForProfile("http://example.com/foo", MyCustomPatient.class); + + Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, input); + + Patient res0 = (Patient) bundle.getEntry().get(0).getResource(); + assertEquals(0, res0.getMeta().getProfile().size()); + List exts = res0.getExtensionsByUrl("http://example.com/Weight"); + assertEquals(1, exts.size()); + assertEquals("185 cm", ((StringType) exts.get(0).getValue()).getValue()); + + MyCustomPatient res1 = (MyCustomPatient) bundle.getEntry().get(1).getResource(); + assertEquals(1, res1.getMeta().getProfile().size()); + assertEquals("http://example.com/foo", res1.getMeta().getProfile().get(0).getValue()); + exts = res1.getExtensionsByUrl("http://example.com/Weight"); + assertEquals(0, exts.size()); + assertEquals("185 cm", res1.getWeight().getValue()); + } + + @Test + public void parseResourceWithDirective() { + String input = createResource(true); + + FhirContext ctx = FhirContext.forR4(); + ctx.setDefaultTypeForProfile("http://example.com/foo", MyCustomPatient.class); + + MyCustomPatient parsed = (MyCustomPatient) ctx.newXmlParser().parseResource(input); + assertEquals(1, parsed.getMeta().getProfile().size()); + assertEquals("http://example.com/foo", parsed.getMeta().getProfile().get(0).getValue()); + + List exts = parsed.getExtensionsByUrl("http://example.com/Weight"); + assertEquals(0, exts.size()); + + assertEquals("185 cm", parsed.getWeight().getValue()); + } + + @Test + public void parseResourceWithNoDirective() { + String input = createResource(true); + + FhirContext ctx = FhirContext.forR4(); + Patient parsed = (Patient) ctx.newXmlParser().parseResource(input); + assertEquals(1, parsed.getMeta().getProfile().size()); + assertEquals("http://example.com/foo", parsed.getMeta().getProfile().get(0).getValue()); + + List exts = parsed.getExtensionsByUrl("http://example.com/Weight"); + assertEquals(1, exts.size()); + assertEquals("185 cm", ((StringType) exts.get(0).getValue()).getValue()); + } + + @Test + public void testAccessEmptyMetaLists() { + Patient p = new Patient(); + assertThat(p.getMeta().getProfile(), empty()); + assertThat(p.getMeta().getFormatCommentsPost(), empty()); + assertThat(p.getMeta().getFormatCommentsPre(), empty()); + assertThat(p.getMeta().getLastUpdated(), nullValue()); + assertThat(p.getMeta().getSecurity(), empty()); + assertThat(p.getMeta().getSecurity("foo", "bar"), nullValue()); + assertThat(p.getMeta().getTag(), empty()); + assertThat(p.getMeta().getTag("foo", "bar"), nullValue()); + assertThat(p.getMeta().getVersionId(), nullValue()); + + } + + @Test + public void testEncodeCompleteMetaLists() { + Patient p = new Patient(); + p.getMeta().addProfile("http://foo/profile1"); + p.getMeta().addProfile("http://foo/profile2"); + p.getMeta().addSecurity().setSystem("SEC_S1").setCode("SEC_C1").setDisplay("SED_D1"); + p.getMeta().addSecurity().setSystem("SEC_S2").setCode("SEC_C2").setDisplay("SED_D2"); + p.getMeta().addTag().setSystem("TAG_S1").setCode("TAG_C1").setDisplay("TAG_D1"); + p.getMeta().addTag().setSystem("TAG_S2").setCode("TAG_C2").setDisplay("TAG_D2"); + + String out = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p); + ourLog.info(out); + + //@formatter:off + assertThat(out, stringContainsInOrder( + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "")); + //@formatter:on + + } + + @Test + public void testEncodeWithCustomType() { + + MyCustomPatient patient = new MyCustomPatient(); + + patient.addIdentifier().setSystem("urn:system").setValue("1234"); + patient.addName().setFamily("Rossi").addGiven("Mario"); + patient.setInsulinLevel(new Quantity()); + patient.setGlucoseLevel(new Quantity()); + patient.setHbA1c(new Quantity()); + patient.setBloodPressure(new Quantity()); + patient.setCholesterol(new Quantity()); + patient.setWeight(new StringDt("80 kg")); + patient.setWeight(new StringDt("185 cm")); + patient.setCheckDates(new ArrayList()); + patient.getCheckDates().add(new DateTimeDt("2014-01-26T11:11:11")); + + ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.ONLY_FOR_CUSTOM); + IParser p = ourCtx.newXmlParser().setPrettyPrint(true); + String messageString = p.encodeResourceToString(patient); + + ourLog.info(messageString); + + //@formatter:off + assertThat(messageString, stringContainsInOrder( + "", + "", + "")); + //@formatter:on + + //@formatter:off + assertThat(messageString, not(stringContainsInOrder( + "", + "", + "", + ""))); + //@formatter:on + } + + @Test + public void testEncodeWithCustomTypeAndAutoInsertedProfile() { + + MyCustomPatient patient = new MyCustomPatient(); + + patient.getMeta().addProfile("http://example.com/foo"); + patient.getMeta().addProfile("http://example.com/bar"); + + patient.addIdentifier().setSystem("urn:system").setValue("1234"); + patient.addName().setFamily("Rossi").addGiven("Mario"); + patient.setInsulinLevel(new Quantity()); + patient.setGlucoseLevel(new Quantity()); + patient.setHbA1c(new Quantity()); + patient.setBloodPressure(new Quantity()); + patient.setCholesterol(new Quantity()); + patient.setWeight(new StringDt("80 kg")); + patient.setWeight(new StringDt("185 cm")); + patient.setCheckDates(new ArrayList()); + patient.getCheckDates().add(new DateTimeDt("2014-01-26T11:11:11")); + + ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.ONLY_FOR_CUSTOM); + IParser p = ourCtx.newXmlParser().setPrettyPrint(true); + String messageString = p.encodeResourceToString(patient); + + ourLog.info(messageString); + + //@formatter:off + assertThat(messageString, stringContainsInOrder( + "", + "", + "", + "")); + //@formatter:on + + //@formatter:off + assertThat(messageString, not(stringContainsInOrder( + "", + "", + "", + ""))); + //@formatter:on + } + + /** + * See #318 + */ + @Test + public void testParseResourceWithContainedResourcesWithProfile() { + //@formatter:off + String input = "" + + " " + + " " + + " " + + " " + + " " + + " " + + "" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + ""; + //@formatter:on + + FhirContext ctx = FhirContext.forR4(); + ctx.setDefaultTypeForProfile("http://fhir.something.com/StructureDefinition/our-medication", MyMedication.class); + + MedicationRequest mo = ctx.newXmlParser().parseResource(MedicationRequest.class, input); + assertEquals(MyMedication.class, mo.getContained().get(0).getClass()); + } + + public static String createBundle(String... theResources) { + StringBuilder b = new StringBuilder(); + b.append("\n"); + for (String next : theResources) { + b.append(" \n"); + b.append(" \n"); + b.append(next); + b.append(" \n"); + b.append(" \n"); + } + b.append(""); + return b.toString(); + } + + public static String createResource(boolean theWithProfile) { + StringBuilder b = new StringBuilder(); + b.append("\n"); + if (theWithProfile) { + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + } + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(" \n"); + b.append(""); + String input = b.toString(); + return input; + } + + @ResourceDef(name = "Patient", profile = "http://example.com/foo") + public static class MyCustomPatient extends Patient { + + private static final long serialVersionUID = 1L; + + @Child(name = "bloodPressure") // once every 3 month. The average target is 130/80 mmHg or less + @Extension(url = "http://example.com/BloodPressure", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The value of the patient's blood pressure") + private Quantity myBloodPressure; + + // Dates of periodic tests + @Child(name = "CheckDates", max = Child.MAX_UNLIMITED) + @Extension(url = "http://example.com/diabetes2", definedLocally = false, isModifier = true) + @Description(shortDefinition = "Dates of periodic tests") + private List myCheckDates; + + @Child(name = "cholesterol") // once a year. The target is triglycerides =< 2 mmol/l e cholesterol =< 4 mmol/l + @Extension(url = "http://example.com/Cholesterol", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The value of the patient's cholesterol") + private Quantity myCholesterol; + + @Child(name = "glucoseLevel") // fingerprick test + @Extension(url = "http://example.com/Glucose", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The value of the patient's blood glucose") + private Quantity myGlucoseLevel; + + // Periodic Tests + @Child(name = "hbA1c") // once every 6 month. The average target is 53 mmol/mol (or 7%) or less. + @Extension(url = "http://example.com/HbA1c", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The value of the patient's glucose") + private Quantity myHbA1c; + + @Child(name = "Height") + @Extension(url = "http://example.com/Height", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The patient's height in cm") + private StringDt myHeight; + + @Child(name = "insulinLevel") // Normal range is [43,208] pmol/l + @Extension(url = "http://example.com/Insuline", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The value of the patient's insulin") + private Quantity myInsulinLevel; + + // Other parameters + @Child(name = "weight") + @Extension(url = "http://example.com/Weight", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The patient's weight in Kg") + private StringDt myWeight; + + public Quantity Cholesterol() { + if (myCholesterol == null) { + myCholesterol = new Quantity(); + } + myCholesterol.getValue(); + myCholesterol.getSystem(); + myCholesterol.getCode(); + + return myCholesterol; + } + + public Quantity getBloodPressure() { + if (myBloodPressure == null) { + myBloodPressure = new Quantity(); + } + myBloodPressure.getValue(); + myBloodPressure.getSystem(); + myBloodPressure.getCode(); + + return myBloodPressure; + } + + public List getCheckDates() { + if (myCheckDates == null) { + myCheckDates = new ArrayList(); + } + return myCheckDates; + } + + public Quantity getGlucoseLevel() { + if (myGlucoseLevel == null) { + myGlucoseLevel = new Quantity(); + } + myGlucoseLevel.getValue(); + myGlucoseLevel.getSystem(); + myGlucoseLevel.getCode(); + + return myGlucoseLevel; + } + + public Quantity getHbA1c() { + if (myHbA1c == null) { + myHbA1c = new Quantity(); + } + myHbA1c.getValue(); + myHbA1c.getSystem(); + myHbA1c.getCode(); + + return myHbA1c; + } + + public StringDt getHeight() { + if (myHeight == null) { + myHeight = new StringDt(); + } + return myHeight; + } + + public Quantity getInsulinLevel() { + if (myInsulinLevel == null) { + myInsulinLevel = new Quantity(); + } + myInsulinLevel.getValue(); + myInsulinLevel.getSystem(); + myInsulinLevel.getCode(); + + return myInsulinLevel; + } + + public StringDt getWeight() { + if (myWeight == null) { + myWeight = new StringDt(); + } + return myWeight; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && ElementUtil.isEmpty(myInsulinLevel, myGlucoseLevel, myHbA1c, myBloodPressure, myCholesterol, myWeight, myHeight, myCheckDates); + } + + public void setBloodPressure(Quantity bloodPressure) { + myBloodPressure = bloodPressure; + myBloodPressure.setValue(110); + myBloodPressure.setSystem("http://unitsofmeasure.org"); + myBloodPressure.setCode("mmHg"); + } + + public void setCheckDates(List theCheckDates) { + myCheckDates = theCheckDates; + myCheckDates.add(new DateTimeDt("2010-01-02")); + } + + public void setCholesterol(Quantity cholesterol) { + myCholesterol = cholesterol; + myCholesterol.setValue(2); + myCholesterol.setSystem("http://unitsofmeasure.org"); + myCholesterol.setCode("mmol/l"); + } + + public void setGlucoseLevel(Quantity glucoseLevel) { + myGlucoseLevel = glucoseLevel; + myGlucoseLevel.setValue(95); + myGlucoseLevel.setSystem("http://unitsofmeasure.org"); + myGlucoseLevel.setCode("mg/dl"); + } + + public void setHbA1c(Quantity hba1c) { + myHbA1c = hba1c; + myHbA1c.setValue(48); + myHbA1c.setSystem("http://unitsofmeasure.org"); + myHbA1c.setCode("mmol/mol"); + } + + public void setHeight(StringDt height) { + myHeight = height; + } + + // Setter/Getter methods + public void setInsulinLevel(Quantity insulinLevel) { + myInsulinLevel = insulinLevel; + myInsulinLevel.setValue(125); + myInsulinLevel.setSystem("http://unitsofmeasure.org"); + myInsulinLevel.setCode("pmol/l"); + } + + public void setWeight(StringDt weight) { + myWeight = weight; + } + + } + + @ResourceDef() + public static class MyMedication extends Medication { + + private static final long serialVersionUID = 1L; + + } +} \ No newline at end of file diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientMimetypeR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientMimetypeR4Test.java new file mode 100644 index 00000000000..2b952551b45 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientMimetypeR4Test.java @@ -0,0 +1,171 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.Charset; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.*; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; +import ca.uhn.fhir.util.TestUtil; + +/** + * http://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_id=677&tracker_item_id=10199 + */ +public class ClientMimetypeR4Test { + private static FhirContext ourCtx; + private HttpClient myHttpClient; + private HttpResponse myHttpResponse; + + @Before + public void before() { + myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + } + + @Test + public void testMimetypeXmlNew() throws Exception { + String requestCt = Constants.CT_FHIR_XML_NEW; + + ArgumentCaptor capt = prepareMimetypePostTest(requestCt, true); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.create().resource(pt).execute(); + + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals(Constants.CT_FHIR_XML_NEW, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue()); + assertEquals("
A PATIENT
", extractBodyAsString(capt)); + } + + @Test + public void testMimetypeXmlLegacy() throws Exception { + String requestCt = Constants.CT_FHIR_XML; + + ArgumentCaptor capt = prepareMimetypePostTest(requestCt, true); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.create().resource(pt).execute(); + + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals(Constants.CT_FHIR_XML_NEW, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue()); + assertEquals("
A PATIENT
", extractBodyAsString(capt)); + } + + @Test + public void testMimetypeJsonNew() throws Exception { + String requestCt = Constants.CT_FHIR_JSON_NEW; + + ArgumentCaptor capt = prepareMimetypePostTest(requestCt, false); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.create().resource(pt).encodedJson().execute(); + + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals(Constants.CT_FHIR_JSON_NEW, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals(Constants.HEADER_ACCEPT_VALUE_JSON_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue()); + assertEquals("{\"resourceType\":\"Patient\",\"text\":{\"div\":\"
A PATIENT
\"}}", extractBodyAsString(capt)); + } + + @Test + public void testMimetypeJsonLegacy() throws Exception { + String requestCt = Constants.CT_FHIR_JSON; + + ArgumentCaptor capt = prepareMimetypePostTest(requestCt, false); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.create().resource(pt).encodedJson().execute(); + + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals(Constants.CT_FHIR_JSON_NEW, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals(Constants.HEADER_ACCEPT_VALUE_JSON_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue()); + assertEquals("{\"resourceType\":\"Patient\",\"text\":{\"div\":\"
A PATIENT
\"}}", extractBodyAsString(capt)); + } + + private String extractBodyAsString(ArgumentCaptor capt) throws IOException { + String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8"); + return body; + } + + private ArgumentCaptor prepareMimetypePostTest(String requestCt, boolean theXml) throws IOException, ClientProtocolException { + final IParser p = theXml ? ourCtx.newXmlParser() : ourCtx.newJsonParser(); + + final Patient resp1 = new Patient(); + resp1.getText().setDivAsString("FINAL VALUE"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer() { + @Override + public Header[] answer(InvocationOnMock theInvocation) throws Throwable { + 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", requestCt + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + } + }); + return capt; + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() { + ourCtx = FhirContext.forR4(); + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientWithCustomTypeR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientWithCustomTypeR4Test.java new file mode 100644 index 00000000000..27f6486fc69 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientWithCustomTypeR4Test.java @@ -0,0 +1,179 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.List; + +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Organization; +import org.junit.*; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; +import ca.uhn.fhir.rest.param.DateParam; +import ca.uhn.fhir.rest.param.ParamPrefixEnum; +import ca.uhn.fhir.util.TestUtil; + +public class ClientWithCustomTypeR4Test { + private static FhirContext ourCtx; + private HttpClient myHttpClient; + private HttpResponse myHttpResponse; + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @Before + public void before() { + myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + } + + @Test + public void testReadCustomType() throws Exception { + IParser p = ourCtx.newXmlParser(); + + MyPatientWithExtensions response = new MyPatientWithExtensions(); + response.addName().setFamily("FAMILY"); + response.getStringExt().setValue("STRINGVAL"); + response.getDateExt().setValueAsString("2011-01-02"); + final String respString = p.encodeResourceToString(response); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + MyPatientWithExtensions value = client + .read() + .resource(MyPatientWithExtensions.class) + .withId("123") + .execute(); + //@formatter:on + + HttpUriRequest request = capt.getAllValues().get(0); + + assertEquals("http://example.com/fhir/Patient/123", request.getURI().toASCIIString()); + assertEquals("GET", request.getMethod()); + + assertEquals(1, value.getName().size()); + assertEquals("FAMILY", value.getName().get(0).getFamily()); + assertEquals("STRINGVAL", value.getStringExt().getValue()); + assertEquals("2011-01-02", value.getDateExt().getValueAsString()); + + } + + @Test + public void testSearchWithGenericReturnType() throws Exception { + + final Bundle bundle = new Bundle(); + + final ExtendedPatient patient = new ExtendedPatient(); + patient.addIdentifier().setValue("PRP1660"); + bundle.addEntry().setResource(patient); + + final Organization org = new Organization(); + org.setName("FOO"); + patient.getManagingOrganization().setResource(org); + + final FhirContext ctx = FhirContext.forR4(); + ctx.setDefaultTypeForProfile(ExtendedPatient.HTTP_FOO_PROFILES_PROFILE, ExtendedPatient.class); + ctx.getRestfulClientFactory().setHttpClient(myHttpClient); + ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + + String msg = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(bundle); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + + // httpResponse = new BasicHttpResponse(statusline, catalog, locale) + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + + ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); + List response = client.getPatientByDobWithGenericResourceReturnType(new DateParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); + + assertEquals("http://foo/Patient?birthdate=ge2011-01-02", capt.getValue().getURI().toString()); + ExtendedPatient patientResp = (ExtendedPatient) response.get(0); + assertEquals("PRP1660", patientResp.getIdentifier().get(0).getValue()); + + } + + @Test + public void testSearchWithGenericReturnType2() throws Exception { + + final Bundle bundle = new Bundle(); + + final ExtendedPatient patient = new ExtendedPatient(); + patient.addIdentifier().setValue("PRP1660"); + bundle.addEntry().setResource(patient); + + final Organization org = new Organization(); + org.setName("FOO"); + patient.getManagingOrganization().setResource(org); + + final FhirContext ctx = FhirContext.forR4(); + ctx.setDefaultTypeForProfile(ExtendedPatient.HTTP_FOO_PROFILES_PROFILE, ExtendedPatient.class); + ctx.getRestfulClientFactory().setHttpClient(myHttpClient); + ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + + String msg = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(bundle); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + + // httpResponse = new BasicHttpResponse(statusline, catalog, locale) + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + + ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); + List response = client.getPatientByDobWithGenericResourceReturnType2(new DateParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); + + assertEquals("http://foo/Patient?birthdate=ge2011-01-02", capt.getValue().getURI().toString()); + ExtendedPatient patientResp = (ExtendedPatient) response.get(0); + assertEquals("PRP1660", patientResp.getIdentifier().get(0).getValue()); + + } + + @BeforeClass + public static void beforeClass() { + ourCtx = FhirContext.forR4(); + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ExtendedPatient.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ExtendedPatient.java new file mode 100644 index 00000000000..ac647ee15e2 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ExtendedPatient.java @@ -0,0 +1,38 @@ +package ca.uhn.fhir.rest.client; + +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.StringType; + +import ca.uhn.fhir.model.api.annotation.*; + +@ResourceDef(name = "Patient", profile = ExtendedPatient.HTTP_FOO_PROFILES_PROFILE) +public class ExtendedPatient extends Patient { + + static final String HTTP_FOO_PROFILES_PROFILE = "http://foo/profiles/Profile"; + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * Each extension is defined in a field. Any valid HAPI Data Type + * can be used for the field type. Note that the [name=""] attribute + * in the @Child annotation needs to match the name for the bean accessor + * and mutator methods. + */ + @Child(name = "petName") + @Extension(url = "http://example.com/dontuse#petname", definedLocally = false, isModifier = false) + @Description(shortDefinition = "The name of the patient's favourite pet") + private StringType myPetName; + + public StringType getPetName() { + if (myPetName == null) { + myPetName = new StringType(); + } + return myPetName; + } + + public void setPetName(StringType thePetName) { + myPetName = thePetName; + } + +} \ No newline at end of file diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientR4Test.java new file mode 100644 index 00000000000..38e8ef7d7fc --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientR4Test.java @@ -0,0 +1,2079 @@ +package ca.uhn.fhir.rest.client; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.*; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.*; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.*; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.Bundle.BundleType; +import org.junit.*; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +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; +import ca.uhn.fhir.model.api.TemporalPrecisionEnum; +import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum; +import ca.uhn.fhir.model.primitive.*; +import ca.uhn.fhir.parser.CustomTypeR4Test; +import ca.uhn.fhir.parser.CustomTypeR4Test.MyCustomPatient; +import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; +import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException; +import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; +import ca.uhn.fhir.rest.client.impl.BaseClient; +import ca.uhn.fhir.rest.client.interceptor.CookieInterceptor; +import ca.uhn.fhir.rest.client.interceptor.UserInfoInterceptor; +import ca.uhn.fhir.rest.param.ParamPrefixEnum; +import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException; +import ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException; +import ca.uhn.fhir.util.*; + +public class GenericClientR4Test { + private static FhirContext ourCtx; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClientR4Test.class); + private int myAnswerCount; + private HttpClient myHttpClient; + private HttpResponse myHttpResponse; + + @Before + public void before() { + myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + myAnswerCount = 0; + System.setProperty(BaseClient.HAPI_CLIENT_KEEPRESPONSES, "true"); + } + + private String expectedUserAgent() { + return "HAPI-FHIR/" + VersionUtil.getVersion() + " (FHIR Client; FHIR " + FhirVersionEnum.R4.getFhirVersionString() + "/R4; apache)"; + } + + private byte[] extractBodyAsByteArray(ArgumentCaptor capt) throws IOException { + byte[] body = IOUtils.toByteArray(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent()); + return body; + } + + private String extractBodyAsString(ArgumentCaptor capt) throws IOException { + String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8"); + return body; + } + + private ArgumentCaptor prepareClientForSearchResponse() throws IOException, ClientProtocolException { + 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 capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + return capt; + } + + @Test + public void testRevIncludeRecursive() throws ClientProtocolException, IOException { + ArgumentCaptor capt = prepareClientForSearchResponse(); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + client.search() + .forResource(EpisodeOfCare.class) + .where(EpisodeOfCare.PATIENT.hasId("123")) + .revInclude(Encounter.INCLUDE_EPISODEOFCARE) + .revInclude(Observation.INCLUDE_ENCOUNTER.asRecursive()) + .returnBundle(Bundle.class) + .execute(); + + assertEquals("http://example.com/fhir/EpisodeOfCare?patient=123&_revinclude=Encounter%3Aepisodeofcare&_revinclude%3Arecurse=Observation%3Aencounter", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + } + + @Test + public void testPatchJsonByIdString() throws Exception { + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + final String respString = ourCtx.newJsonParser().encodeResourceToString(conf); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]"; + + MethodOutcome outcome = client + .patch() + .withBody(patch) + .withId("Patient/123") + .execute(); + + assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod()); + assertEquals(patch, extractBodyAsString(capt)); + assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", "")); + idx++; + + OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome(); + assertThat(oo.getText().getDivAsString(), containsString("OK!")); + } + + + + @Test + public void testPatchJsonByIdType() throws Exception { + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + final String respString = ourCtx.newJsonParser().encodeResourceToString(conf); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]"; + + MethodOutcome outcome = client + .patch() + .withBody(patch) + .withId(new IdType("http://localhost/fhir/Patient/123/_history/234")) + .execute(); + + assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod()); + assertEquals(patch, extractBodyAsString(capt)); + assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", "")); + idx++; + + OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome(); + assertThat(oo.getText().getDivAsString(), containsString("OK!")); + } + + @Test + public void testPatchJsonByConditionalString() throws Exception { + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + final String respString = ourCtx.newJsonParser().encodeResourceToString(conf); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]"; + + MethodOutcome outcome = client + .patch() + .withBody(patch) + .conditionalByUrl("Patient?foo=bar") + .execute(); + + assertEquals("http://example.com/fhir/Patient?foo=bar", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod()); + assertEquals(patch, extractBodyAsString(capt)); + assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", "")); + idx++; + + OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome(); + assertThat(oo.getText().getDivAsString(), containsString("OK!")); + } + + @Test + public void testPatchJsonByConditionalParam() throws Exception { + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + final String respString = ourCtx.newJsonParser().encodeResourceToString(conf); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]"; + + MethodOutcome outcome = client + .patch() + .withBody(patch) + .conditional("Patient").where(Patient.NAME.matches().value("TEST")) + .and(Patient.FAMILY.matches().value("TEST2")) + .execute(); + + assertEquals("http://example.com/fhir/Patient?name=TEST&family=TEST2", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod()); + assertEquals(patch, extractBodyAsString(capt)); + assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", "")); + idx++; + + OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome(); + assertThat(oo.getText().getDivAsString(), containsString("OK!")); + } + + @Test + public void testPatchJsonByConditionalParamResourceType() throws Exception { + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + final String respString = ourCtx.newJsonParser().encodeResourceToString(conf); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]"; + + MethodOutcome outcome = client + .patch() + .withBody(patch) + .conditional(Patient.class).where(Patient.NAME.matches().value("TEST")) + .and(Patient.FAMILY.matches().value("TEST2")) + .execute(); + + assertEquals("http://example.com/fhir/Patient?name=TEST&family=TEST2", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod()); + assertEquals(patch, extractBodyAsString(capt)); + assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", "")); + idx++; + + OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome(); + assertThat(oo.getText().getDivAsString(), containsString("OK!")); + } + + @Test + public void testPatchXmlByIdString() throws Exception { + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + final String respString = ourCtx.newJsonParser().encodeResourceToString(conf); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + String patch = "false"; + + MethodOutcome outcome = client + .patch() + .withBody(patch) + .withId("Patient/123") + .execute(); + + assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod()); + assertEquals(patch, extractBodyAsString(capt)); + assertEquals(Constants.CT_XML_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", "")); + idx++; + + OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome(); + assertThat(oo.getText().getDivAsString(), containsString("OK!")); + } + + @Test + public void testPatchInvalid() throws Exception { + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client + .patch() + .withBody("AA") + .withId("Patient/123") + .execute(); + } catch (IllegalArgumentException e) { + assertEquals("Unable to determine encoding of patch", e.getMessage()); + } + } + + @Test + public void testAcceptHeaderWithEncodingSpecified() throws Exception { + 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 capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client.setEncoding(EncodingEnum.JSON); + client.search() + .forResource("Device") + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Device?_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("application/fhir+json;q=1.0, application/json+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue()); + idx++; + + //@formatter:off + client.setEncoding(EncodingEnum.XML); + client.search() + .forResource("Device") + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Device?_format=xml", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue()); + idx++; + + } + + @Test + public void testBinaryCreateWithFhirContentType() throws Exception { + IParser p = ourCtx.newXmlParser(); + + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + + final String respString = p.encodeResourceToString(conf); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + Binary bin = new Binary(); + bin.setContent(ourCtx.newJsonParser().encodeResourceToString(pt).getBytes("UTF-8")); + bin.setContentType(Constants.CT_FHIR_JSON); + client.create().resource(bin).execute(); + + ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString()); + + assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString()); + validateUserAgent(capt); + + assertEquals("application/fhir+xml;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", "")); + assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue()); + Binary output = ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt)); + assertEquals(Constants.CT_FHIR_JSON, output.getContentType()); + + Patient outputPt = (Patient) ourCtx.newJsonParser().parseResource(new String(output.getContent(), "UTF-8")); + assertEquals("
A PATIENT
", outputPt.getText().getDivAsString()); + } + + @Test + public void testBinaryCreateWithNoContentType() throws Exception { + IParser p = ourCtx.newXmlParser(); + + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + + final String respString = p.encodeResourceToString(conf); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Binary bin = new Binary(); + bin.setContent(new byte[] { 0, 1, 2, 3, 4 }); + client.create().resource(bin).execute(); + + ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString()); + + assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString()); + validateUserAgent(capt); + + assertEquals("application/fhir+xml;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", "")); + assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue()); + assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt)).getContent()); + + } + + @SuppressWarnings("unchecked") + @Test + public void testClientFailures() throws Exception { + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenThrow(IllegalStateException.class, RuntimeException.class, Exception.class); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.read().resource(Patient.class).withId("1").execute(); + fail(); + } catch (FhirClientConnectionException e) { + assertEquals("java.lang.IllegalStateException", e.getMessage()); + } + + try { + client.read().resource(Patient.class).withId("1").execute(); + fail(); + } catch (RuntimeException e) { + assertEquals("java.lang.RuntimeException", e.toString()); + } + + try { + client.read().resource(Patient.class).withId("1").execute(); + fail(); + } catch (FhirClientConnectionException e) { + assertEquals("java.lang.Exception", e.getMessage()); + } + } + + @Test + public void testCookieInterceptor() throws Exception { + final String respString = CustomTypeR4Test.createBundle(CustomTypeR4Test.createResource(false)); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + client.registerInterceptor(new CookieInterceptor("foo=bar")); + + //@formatter:off + Bundle resp = client + .history() + .onType(Patient.class) + .andReturnBundle(Bundle.class) + .execute(); + //@formatter:on + + assertEquals("foo=bar", capt.getAllValues().get(0).getFirstHeader("Cookie").getValue()); + } + + @Test + public void testCreateWithPreferRepresentationServerReturnsOO() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + final OperationOutcome resp0 = new OperationOutcome(); + resp0.getText().setDivAsString("OK!"); + + final Patient resp1 = new Patient(); + resp1.getText().setDivAsString("FINAL VALUE"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer() { + @Override + public Header[] answer(InvocationOnMock theInvocation) throws Throwable { + 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() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + if (myAnswerCount++ == 0) { + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8")); + } else { + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + } + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.create().resource(pt).prefer(PreferReturnEnum.REPRESENTATION).execute(); + + assertEquals(2, myAnswerCount); + assertNotNull(outcome.getOperationOutcome()); + assertNotNull(outcome.getResource()); + + assertEquals("
OK!
", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString()); + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + + assertEquals(myAnswerCount, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals(Constants.CT_FHIR_XML_NEW, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + + assertEquals("http://foo.com/base/Patient/222/_history/3", capt.getAllValues().get(1).getURI().toASCIIString()); + } + + @Test + public void testCreateWithPreferRepresentationServerReturnsResource() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + final Patient resp1 = new Patient(); + resp1.getText().setDivAsString("FINAL VALUE"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer() { + @Override + public Header[] answer(InvocationOnMock theInvocation) throws Throwable { + 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() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + myAnswerCount++; + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.create().resource(pt).prefer(PreferReturnEnum.REPRESENTATION).execute(); + + assertEquals(1, myAnswerCount); + assertNull(outcome.getOperationOutcome()); + assertNotNull(outcome.getResource()); + + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + + assertEquals(myAnswerCount, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); + } + + @Test + public void testExplicitCustomTypeHistoryType() throws Exception { + final String respString = CustomTypeR4Test.createBundle(CustomTypeR4Test.createResource(false)); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle resp = client + .history() + .onType(CustomTypeR4Test.MyCustomPatient.class) + .andReturnBundle(Bundle.class) + .execute(); + //@formatter:on + + assertEquals(1, resp.getEntry().size()); + assertEquals(CustomTypeR4Test.MyCustomPatient.class, resp.getEntry().get(0).getResource().getClass()); + assertEquals("http://example.com/fhir/Patient/_history", capt.getAllValues().get(0).getURI().toASCIIString()); + } + + @Test + public void testExplicitCustomTypeLoadPage() throws Exception { + final String respString = CustomTypeR4Test.createBundle(CustomTypeR4Test.createResource(false)); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + Bundle bundle = new Bundle(); + bundle.addLink().setRelation("next").setUrl("http://foo/next"); + + //@formatter:off + Bundle resp = client + .loadPage() + .next(bundle) + .preferResponseType(MyCustomPatient.class) + .execute(); + //@formatter:on + + assertEquals(1, resp.getEntry().size()); + assertEquals(CustomTypeR4Test.MyCustomPatient.class, resp.getEntry().get(0).getResource().getClass()); + assertEquals("http://foo/next", capt.getAllValues().get(0).getURI().toASCIIString()); + + //@formatter:off + resp = client + .loadPage() + .next(bundle) + .preferResponseTypes(toTypeList(MyCustomPatient.class)) + .execute(); + //@formatter:on + + assertEquals(1, resp.getEntry().size()); + assertEquals(CustomTypeR4Test.MyCustomPatient.class, resp.getEntry().get(0).getResource().getClass()); + assertEquals("http://foo/next", capt.getAllValues().get(0).getURI().toASCIIString()); + } + + @Test + public void testExplicitCustomTypeOperation() throws Exception { + + Parameters param = new Parameters(); + Patient patient = new Patient(); + patient.addName().setFamily("FOO"); + param.addParameter().setName("foo").setResource(patient); + final String respString = ourCtx.newXmlParser().encodeResourceToString(param); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Parameters resp = client + .operation() + .onServer() + .named("foo") + .withNoParameters(Parameters.class) + .preferResponseType(MyCustomPatient.class) + .execute(); + //@formatter:on + + assertEquals(1, resp.getParameter().size()); + assertEquals(CustomTypeR4Test.MyCustomPatient.class, resp.getParameter().get(0).getResource().getClass()); + assertEquals("http://example.com/fhir/$foo", capt.getAllValues().get(0).getURI().toASCIIString()); + + //@formatter:off + resp = client + .operation() + .onType(MyCustomPatient.class) + .named("foo") + .withNoParameters(Parameters.class) + .execute(); + //@formatter:on + + assertEquals(1, resp.getParameter().size()); + assertEquals(CustomTypeR4Test.MyCustomPatient.class, resp.getParameter().get(0).getResource().getClass()); + assertEquals("http://example.com/fhir/Patient/$foo", capt.getAllValues().get(1).getURI().toASCIIString()); + } + + @Test + public void testExplicitCustomTypeSearch() throws Exception { + final String respString = CustomTypeR4Test.createBundle(CustomTypeR4Test.createResource(false)); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle resp = client + .search() + .forResource(CustomTypeR4Test.MyCustomPatient.class) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + + assertEquals(1, resp.getEntry().size()); + assertEquals(CustomTypeR4Test.MyCustomPatient.class, resp.getEntry().get(0).getResource().getClass()); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); + } + + @Test + public void testFetchCapabilityStatementReceiveCapabilityStatement() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + final CapabilityStatement conf = new CapabilityStatement(); + conf.setCopyright("COPY"); + + final Patient patient = new Patient(); + patient.addName().setFamily("FAM"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + private int myCount = 0; + + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + final String respString; + if (myCount == 1 || myCount == 2) { + ourLog.info("Encoding patient"); + respString = p.encodeResourceToString(patient); + } else { + ourLog.info("Encoding conformance"); + respString = p.encodeResourceToString(conf); + } + myCount++; + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE); + IGenericClient client = ourCtx.newRestfulGenericClient("http://testForceConformanceCapabilityStatement.com/fhir"); + + client.read().resource("Patient").withId("1").execute(); + assertEquals(2, capt.getAllValues().size()); + assertEquals("http://testForceConformanceCapabilityStatement.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals("http://testForceConformanceCapabilityStatement.com/fhir/Patient/1", capt.getAllValues().get(1).getURI().toASCIIString()); + + client.read().resource("Patient").withId("1").execute(); + assertEquals(3, capt.getAllValues().size()); + assertEquals("http://testForceConformanceCapabilityStatement.com/fhir/Patient/1", capt.getAllValues().get(2).getURI().toASCIIString()); + + client.forceConformanceCheck(); + assertEquals(4, capt.getAllValues().size()); + assertEquals("http://testForceConformanceCapabilityStatement.com/fhir/metadata", capt.getAllValues().get(3).getURI().toASCIIString()); + } + + @Test + public void testForceConformance() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + final CapabilityStatement conf = new CapabilityStatement(); + conf.setCopyright("COPY"); + + final Patient patient = new Patient(); + patient.addName().setFamily("FAM"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + final String respString; + if (myAnswerCount >= 1) { + ourLog.info("Encoding patient"); + respString = p.encodeResourceToString(patient); + } else { + ourLog.info("Encoding conformance"); + respString = p.encodeResourceToString(conf); + } + myAnswerCount++; + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE); + IGenericClient client = ourCtx.newRestfulGenericClient("http://testForceConformance.com/fhir"); + + client.read().resource("Patient").withId("1").execute(); + assertEquals(2, capt.getAllValues().size()); + assertEquals("http://testForceConformance.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals("http://testForceConformance.com/fhir/Patient/1", capt.getAllValues().get(1).getURI().toASCIIString()); + + client.read().resource("Patient").withId("1").execute(); + assertEquals(3, capt.getAllValues().size()); + assertEquals("http://testForceConformance.com/fhir/Patient/1", capt.getAllValues().get(2).getURI().toASCIIString()); + + myAnswerCount = 0; + client.forceConformanceCheck(); + assertEquals(4, capt.getAllValues().size()); + assertEquals("http://testForceConformance.com/fhir/metadata", capt.getAllValues().get(3).getURI().toASCIIString()); + } + + @Test + public void testHttp499() throws Exception { + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 499, "Wacky Message")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public StringInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new StringInputStream("HELLO", Charsets.UTF_8); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.read().resource(Patient.class).withId("1").execute(); + fail(); + } catch (UnclassifiedServerFailureException e) { + assertEquals("ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException: HTTP 499 Wacky Message", e.toString()); + assertEquals("HELLO", e.getResponseBody()); + } + + } + + @Test + public void testHttp501() throws Exception { + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 501, "Not Implemented")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public StringInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new StringInputStream("not implemented", Charsets.UTF_8); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.read().resource(Patient.class).withId("1").execute(); + fail(); + } catch (NotImplementedOperationException e) { + assertEquals("HTTP 501 Not Implemented", e.getMessage()); + } + + } + + @SuppressWarnings("deprecation") + @Test + public void testInvalidConformanceCall() { + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + try { + client.conformance(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Must call fetchConformance() instead of conformance() for RI/STU3+ structures", e.getMessage()); + } + } + + /** + * See #150 + */ + @Test + public void testNullAndEmptyParamValuesAreIgnored() throws Exception { + ArgumentCaptor capt = prepareClientForSearchResponse(); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client + .search() + .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.ORGANIZATION.hasId((String)null)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client + .search() + .forResource(Encounter.class) + .where(Encounter.LENGTH.exactly().number(null)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Encounter", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client + .search() + .forResource(Observation.class) + .where(Observation.VALUE_QUANTITY.exactly().number(null).andUnits(null)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Observation", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + } + + @Test + public void testPutDoesntForceAllIdsJson() throws Exception { + IParser p = ourCtx.newJsonParser(); + + Patient patient = new Patient(); + patient.setId("PATIENT1"); + patient.addName().setFamily("PATIENT1"); + + Bundle bundle = new Bundle(); + bundle.setId("BUNDLE1"); + bundle.addEntry().setResource(patient); + + final String encoded = p.encodeResourceToString(bundle); + assertEquals("{\"resourceType\":\"Bundle\",\"id\":\"BUNDLE1\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"PATIENT1\",\"name\":[{\"family\":\"PATIENT1\"}]}}]}", encoded); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client + .update() + .resource(bundle) + .prefer(PreferReturnEnum.REPRESENTATION) + .encodedJson() + .execute(); + + HttpPut httpRequest = (HttpPut) capt.getValue(); + assertEquals("http://example.com/fhir/Bundle/BUNDLE1", httpRequest.getURI().toASCIIString()); + + String requestString = IOUtils.toString(httpRequest.getEntity().getContent(), StandardCharsets.UTF_8); + assertEquals(encoded, requestString); + } + + @Test + public void testPutDoesntForceAllIdsXml() throws Exception { + IParser p = ourCtx.newXmlParser(); + + Patient patient = new Patient(); + patient.setId("PATIENT1"); + patient.addName().setFamily("PATIENT1"); + + Bundle bundle = new Bundle(); + bundle.setId("BUNDLE1"); + bundle.addEntry().setResource(patient); + + final String encoded = p.encodeResourceToString(bundle); + assertEquals("", encoded); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client + .update() + .resource(bundle) + .prefer(PreferReturnEnum.REPRESENTATION) + .execute(); + + HttpPut httpRequest = (HttpPut) capt.getValue(); + assertEquals("http://example.com/fhir/Bundle/BUNDLE1", httpRequest.getURI().toASCIIString()); + + String requestString = IOUtils.toString(httpRequest.getEntity().getContent(), StandardCharsets.UTF_8); + assertEquals(encoded, requestString); + } + + @Test + public void testReadWithUnparseableResponse() throws Exception { + String msg = "{\"resourceTypeeeee\":\"Patient\"}"; + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.read().resource("Patient").withId("123").elementsSubset("name", "identifier").execute(); + fail(); + } catch (FhirClientConnectionException e) { + assertEquals("Failed to parse response from server when performing GET to URL http://example.com/fhir/Patient/123?_elements=identifier%2Cname - ca.uhn.fhir.parser.DataFormatException: Invalid JSON content detected, missing required element: 'resourceType'", e.getMessage()); + } + } + + @Test + public void testResponseHasContentTypeMissing() throws Exception { + IParser p = ourCtx.newXmlParser(); + Patient patient = new Patient(); + patient.addName().setFamily("FAM"); + final String respString = p.encodeResourceToString(patient); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + // when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(null); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + try { + client.read().resource(Patient.class).withId("1").execute(); + fail(); + } catch (NonFhirResponseException e) { + assertEquals("Response contains no Content-Type", e.getMessage()); + } + + // Patient resp = client.read().resource(Patient.class).withId("1").execute(); + // assertEquals("FAM", resp.getNameFirstRep().getFamilyAsSingleString()); + } + + @Test + public void testResponseHasContentTypeNonFhir() throws Exception { + IParser p = ourCtx.newXmlParser(); + Patient patient = new Patient(); + patient.addName().setFamily("FAM"); + final String respString = p.encodeResourceToString(patient); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", "text/plain")); + // when(myHttpResponse.getEntity().getContentType()).thenReturn(null); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + try { + client.read().resource(Patient.class).withId("1").execute(); + fail(); + } catch (NonFhirResponseException e) { + assertEquals("Response contains non FHIR Content-Type 'text/plain' : ", e.getMessage()); + } + + // Patient resp = client.read().resource(Patient.class).withId("1").execute(); + // assertEquals("FAM", resp.getNameFirstRep().getFamilyAsSingleString()); + } + + @Test + public void testSearchWithNullParameters() throws Exception { + 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 capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + DateTimeDt now = DateTimeDt.withCurrentTime(); + String dateString = now.getValueAsString().substring(0, 10); + + client.search() + .forResource("Patient") + .where(Patient.NAME.matches().value((String)null)) + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString()); + idx++; + } + + @Test + public void testSearchByDate() throws Exception { + 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 capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + DateTimeDt now = DateTimeDt.withCurrentTime(); + String dateString = now.getValueAsString().substring(0, 10); + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.after().day(dateString)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=gt" + dateString, capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.after().day(now.getValue())) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=gt" + dateString, capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.afterOrEquals().day(dateString)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=ge" + dateString, capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.before().day(dateString)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=lt" + dateString, capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.beforeOrEquals().day(dateString)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=le" + dateString, capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.exactly().day(dateString)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=" + dateString, capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.after().second("2011-01-02T22:33:01Z")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=gt2011-01-02T22:33:01Z", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.after().second(now.getValueAsString())) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?birthdate=gt" + now.getValueAsString(), UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.BIRTHDATE.after().now()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertThat(capt.getAllValues().get(idx).getURI().toString(), startsWith("http://example.com/fhir/Patient?birthdate=gt2")); + dateString = UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()).substring(44); + ourLog.info(dateString); + assertEquals(TemporalPrecisionEnum.SECOND, new DateTimeDt(dateString).getPrecision()); + idx++; + } + + @SuppressWarnings("deprecation") + @Test + public void testSearchByQuantity() throws Exception { + 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 capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.approximately().number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=ap123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.approximately().number("123").andUnits("CODE")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=ap123||CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.approximately().number("123").andUnits("SYSTEM", "CODE")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=ap123|SYSTEM|CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.exactly().number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.exactly().number("123").andUnits("CODE")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=123||CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.exactly().number("123").andUnits("SYSTEM", "CODE")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=123|SYSTEM|CODE", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.greaterThan().number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=gt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.lessThan().number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=lt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.greaterThanOrEquals().number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=ge123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.lessThanOrEquals().number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=le123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.withComparator(QuantityCompararatorEnum.GREATERTHAN).number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=gt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Observation") + .where(Observation.VALUE_QUANTITY.withPrefix(ParamPrefixEnum.GREATERTHAN).number(123).andNoUnits()) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Observation?value-quantity=gt123||", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + } + + @Test + public void testSearchByString() throws Exception { + 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 capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matches().value("AAA")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name=AAA", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matches().value(new StringDt("AAA"))) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name=AAA", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matches().values("AAA", "BBB")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matches().values(Arrays.asList("AAA", "BBB"))) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matchesExactly().value("AAA")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name%3Aexact=AAA", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matchesExactly().value(new StringDt("AAA"))) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name%3Aexact=AAA", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matchesExactly().values("AAA", "BBB")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name:exact=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.NAME.matchesExactly().values(Arrays.asList("AAA", "BBB"))) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?name:exact=AAA,BBB", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + } + + @Test + public void testSearchByUrl() throws Exception { + 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 capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).then(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client.search() + .forResource("Device") + .where(Device.URL.matches().value("http://foo.com")) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Device?url=http://foo.com", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + assertEquals("http://example.com/fhir/Device?url=http%3A%2F%2Ffoo.com", capt.getAllValues().get(idx).getURI().toString()); + idx++; + + //@formatter:off + client.search() + .forResource("Device") + .where(Device.URL.matches().value(new StringDt("http://foo.com"))) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Device?url=http://foo.com", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + } + + @Test + public void testSearchForUnknownType() throws Exception { + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + try { + client.search(new UriDt("?aaaa")); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unable to determine the resource type from the given URI: ?aaaa", e.getMessage()); + } + } + + @Test + public void testSearchWithMultipleTokens() throws Exception { + ArgumentCaptor capt = prepareClientForSearchResponse(); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + Collection values = Arrays.asList("VAL1", "VAL2", "VAL3A,B"); + + //@formatter:off + client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().systemAndValues("SYS", values)) + .returnBundle(Bundle.class) + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient?identifier=SYS%7CVAL1%2CSYS%7CVAL2%2CSYS%7CVAL3A%5C%2CB", capt.getAllValues().get(idx).getURI().toString()); + assertEquals("http://example.com/fhir/Patient?identifier=SYS|VAL1,SYS|VAL2,SYS|VAL3A\\,B", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString())); + idx++; + + } + + /** + * See #371 + */ + @Test + public void testSortR4Test() throws Exception { + IParser p = ourCtx.newXmlParser(); + + Bundle b = new Bundle(); + b.setType(BundleType.SEARCHSET); + + final String respString = p.encodeResourceToString(b); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + client + .search() + .forResource(Patient.class) + .sort().ascending("address") + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient?_sort=address", capt.getAllValues().get(idx++).getURI().toASCIIString()); + + client + .search() + .forResource(Patient.class) + .sort().descending("address") + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient?_sort=-address", capt.getAllValues().get(idx++).getURI().toASCIIString()); + + client + .search() + .forResource(Patient.class) + .sort().descending("address") + .sort().ascending("name") + .sort().descending(Patient.BIRTHDATE) + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient?_sort=-address%2Cname%2C-birthdate", capt.getAllValues().get(idx++).getURI().toASCIIString()); + //@formatter:on + } + + @Test + public void testTransactionWithInvalidBody() throws Exception { + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + // Transaction + try { + client.transaction().withBundle("FOO"); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage()); + } + + // Create + try { + client.create().resource("FOO").execute(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage()); + } + + // Update + try { + client.update().resource("FOO").execute(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage()); + } + + // Validate + try { + client.validate().resource("FOO").execute(); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage()); + } + + } + + @Test + public void testUpdateById() throws Exception { + IParser p = ourCtx.newXmlParser(); + + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + + final String respString = p.encodeResourceToString(conf); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.setId("222"); + pt.getText().setDivAsString("A PATIENT"); + + client.update().resource(pt).withId("111").execute(); + + ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString()); + + assertEquals("http://example.com/fhir/Patient/111", capt.getAllValues().get(0).getURI().toASCIIString()); + validateUserAgent(capt); + + assertEquals("application/fhir+xml;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", "")); + assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue()); + String body = extractBodyAsString(capt); + assertThat(body, containsString("")); + } + + @Test + public void testUpdateWithPreferRepresentationServerReturnsOO() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + final OperationOutcome resp0 = new OperationOutcome(); + resp0.getText().setDivAsString("OK!"); + + final Patient resp1 = new Patient(); + resp1.getText().setDivAsString("FINAL VALUE"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer() { + @Override + public Header[] answer(InvocationOnMock theInvocation) throws Throwable { + 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() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + if (myAnswerCount++ == 0) { + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8")); + } else { + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + } + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.setId("Patient/222"); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.update().resource(pt).prefer(PreferReturnEnum.REPRESENTATION).execute(); + + assertEquals(2, myAnswerCount); + assertNotNull(outcome.getOperationOutcome()); + assertNotNull(outcome.getResource()); + + assertEquals("
OK!
", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString()); + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + + assertEquals(myAnswerCount, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient/222", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals("http://foo.com/base/Patient/222/_history/3", capt.getAllValues().get(1).getURI().toASCIIString()); + } + + @Test + public void testUpdateWithPreferRepresentationServerReturnsResource() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + final Patient resp1 = new Patient(); + resp1.getText().setDivAsString("FINAL VALUE"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer() { + @Override + public Header[] answer(InvocationOnMock theInvocation) throws Throwable { + 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() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + myAnswerCount++; + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.setId("Patient/222"); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.update().resource(pt).prefer(PreferReturnEnum.REPRESENTATION).execute(); + + assertEquals(1, myAnswerCount); + assertNull(outcome.getOperationOutcome()); + assertNotNull(outcome.getResource()); + + assertEquals("
FINAL VALUE
", ((Patient) outcome.getResource()).getText().getDivAsString()); + + assertEquals(myAnswerCount, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient/222", capt.getAllValues().get(0).getURI().toASCIIString()); + } + + @Test + public void testUserAgentForBinary() throws Exception { + IParser p = ourCtx.newXmlParser(); + + CapabilityStatement conf = new CapabilityStatement(); + conf.setCopyright("COPY"); + + final String respString = p.encodeResourceToString(conf); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Binary bin = new Binary(); + bin.setContentType("application/foo"); + bin.setContent(new byte[] { 0, 1, 2, 3, 4 }); + client.create().resource(bin).execute(); + + ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString()); + + assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString()); + validateUserAgent(capt); + + assertEquals("application/foo", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue()); + assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue()); + assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, extractBodyAsByteArray(capt)); + + } + + @Test + public void testUserAgentForConformance() throws Exception { + IParser p = ourCtx.newXmlParser(); + + CapabilityStatement conf = new CapabilityStatement(); + conf.setCopyright("COPY"); + + final String respString = p.encodeResourceToString(conf); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + client.fetchConformance().ofType(CapabilityStatement.class).execute(); + assertEquals("http://example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString()); + validateUserAgent(capt); + } + + @Test + public void testUserInfoInterceptor() throws Exception { + final String respString = CustomTypeR4Test.createBundle(CustomTypeR4Test.createResource(false)); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + client.registerInterceptor(new UserInfoInterceptor("user_id", "user_name", "app-name")); + + //@formatter:off + Bundle resp = client + .history() + .onType(Patient.class) + .andReturnBundle(Bundle.class) + .execute(); + //@formatter:on + + } + + @Test + public void testValidate() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + final OperationOutcome resp0 = new OperationOutcome(); + resp0.getText().setDivAsString("OK!"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer() { + @Override + public Header[] answer(InvocationOnMock theInvocation) throws Throwable { + 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() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.setId("Patient/222"); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.validate().resource(pt).execute(); + + assertNotNull(outcome.getOperationOutcome()); + assertEquals("
OK!
", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString()); + + } + + @Test + public void testValidateCustomTypeFromClientRead() throws Exception { + IParser p = ourCtx.newXmlParser(); + + MyPatientWithExtensions patient = new MyPatientWithExtensions(); + patient.setId("123"); + patient.getText().setDivAsString("OK!"); + + final String respString = p.encodeResourceToString(patient); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + MyPatientWithExtensions read = client.read().resource(MyPatientWithExtensions.class).withId(new IdType("1")).execute(); + assertEquals("
OK!
", read.getText().getDivAsString()); + + // Ensure that we haven't overridden the default type for the name + assertFalse(MyPatientWithExtensions.class.isAssignableFrom(Patient.class)); + assertFalse(Patient.class.isAssignableFrom(MyPatientWithExtensions.class)); + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + IParser parser = ourCtx.newXmlParser(); + String encoded = parser.encodeResourceToString(pt); + pt = (Patient) parser.parseResource(encoded); + + } + + @Test + public void testValidateCustomTypeFromClientSearch() throws Exception { + IParser p = ourCtx.newXmlParser(); + + Bundle b = new Bundle(); + + MyPatientWithExtensions patient = new MyPatientWithExtensions(); + patient.setId("123"); + patient.getText().setDivAsString("OK!"); + b.addEntry().setResource(patient); + + final String respString = p.encodeResourceToString(b); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + Bundle bundle = client.search().forResource(MyPatientWithExtensions.class).returnBundle(Bundle.class).execute(); + + assertEquals(1, bundle.getEntry().size()); + assertEquals(MyPatientWithExtensions.class, bundle.getEntry().get(0).getResource().getClass()); + } + + private List> toTypeList(Class theClass) { + ArrayList> retVal = new ArrayList>(); + retVal.add(theClass); + return retVal; + } + + private void validateUserAgent(ArgumentCaptor capt) { + assertEquals(1, capt.getAllValues().get(0).getHeaders("User-Agent").length); + assertEquals(expectedUserAgent(), capt.getAllValues().get(0).getHeaders("User-Agent")[0].getValue()); + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() { + ourCtx = FhirContext.forR4(); + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java new file mode 100644 index 00000000000..ff22d4d0893 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java @@ -0,0 +1,22 @@ +package ca.uhn.fhir.rest.client; + +import java.util.List; + +import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.Patient; + +import ca.uhn.fhir.rest.annotation.RequiredParam; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.client.api.IBasicClient; +import ca.uhn.fhir.rest.param.DateParam; + +public interface ITestClient extends IBasicClient { + + @Search(type=ExtendedPatient.class) + public List getPatientByDobWithGenericResourceReturnType(@RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theBirthDate); + + @Search(type=ExtendedPatient.class) + public List getPatientByDobWithGenericResourceReturnType2(@RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theBirthDate); + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/MyPatientWithExtensions.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/MyPatientWithExtensions.java new file mode 100644 index 00000000000..981aefdaa9f --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/MyPatientWithExtensions.java @@ -0,0 +1,86 @@ +package ca.uhn.fhir.rest.client; + +import java.util.ArrayList; +import java.util.List; + +import org.hl7.fhir.r4.model.*; + +import ca.uhn.fhir.model.api.annotation.*; +import ca.uhn.fhir.model.api.annotation.Extension; +import ca.uhn.fhir.util.ElementUtil; + + +@ResourceDef(name="Patient", profile="http://example.com/StructureDefinition/patient_with_extensions") +public class MyPatientWithExtensions extends DomainResource { + + private static final long serialVersionUID = 1L; + + @Extension(url = "http://example.com/ext/date", definedLocally = false, isModifier = true) + @Child(name = "modExt") + private DateType myDateExt; + + @Extension(url = "http://example.com/ext/string", definedLocally = false, isModifier = false) + @Child(name = "extAtt") + private StringType myStringExt; + + @Child(name = "name", type = {HumanName.class}, min=0, max=Child.MAX_UNLIMITED, modifier=false, summary=true) + @Description(shortDefinition="A name associated with the patient", formalDefinition="A name associated with the individual." ) + private List myName; + + + public List getName() { + if (myName == null) { + myName = new ArrayList(); + } + return myName; + } + + public void setName(List theName) { + myName = theName; + } + + public DateType getDateExt() { + if (myDateExt == null) { + myDateExt = new DateType(); + } + return myDateExt; + } + + public StringType getStringExt() { + if (myStringExt == null) { + myStringExt = new StringType(); + } + return myStringExt; + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && ElementUtil.isEmpty(myStringExt, myDateExt); + } + + public void setDateExt(DateType theDateExt) { + myDateExt = theDateExt; + } + + public void setStringExt(StringType theStringExt) { + myStringExt = theStringExt; + } + + @Override + public DomainResource copy() { + return null; + } + + @Override + public ResourceType getResourceType() { + return ResourceType.Patient; + } + + public HumanName addName() { + HumanName retVal = new HumanName(); + getName().add(retVal); + return retVal; + } + + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/NonGenericClientR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/NonGenericClientR4Test.java new file mode 100644 index 00000000000..e28f7e6b54d --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/NonGenericClientR4Test.java @@ -0,0 +1,186 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.*; +import org.junit.*; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.ValidationModeEnum; +import ca.uhn.fhir.rest.client.api.IRestfulClient; +import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; +import ca.uhn.fhir.rest.client.impl.BaseClient; +import ca.uhn.fhir.util.TestUtil; + +public class NonGenericClientR4Test { + private static FhirContext ourCtx; + private HttpClient myHttpClient; + private HttpResponse myHttpResponse; + + @Before + public void before() { + myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + + System.setProperty(BaseClient.HAPI_CLIENT_KEEPRESPONSES, "true"); + + } + + private String extractBodyAsString(ArgumentCaptor capt, int theIdx) throws IOException { + String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(theIdx)).getEntity().getContent(), "UTF-8"); + return body; + } + + @Test + public void testValidateCustomTypeFromClientSearch() throws Exception { + IParser p = ourCtx.newXmlParser(); + + Bundle b = new Bundle(); + + MyPatientWithExtensions patient = new MyPatientWithExtensions(); + patient.setId("123"); + patient.getText().setDivAsString("OK!"); + b.addEntry().setResource(patient); + + + final String respString = p.encodeResourceToString(b); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IClientWithCustomType client = ourCtx.newRestfulClient(IClientWithCustomType.class, "http://example.com/fhir"); + List list = client.search(); + + assertEquals(1, list.size()); + assertEquals(MyPatientWithExtensions.class, list.get(0).getClass()); + } + + @Test + public void testValidateCustomTypeFromClientRead() throws Exception { + IParser p = ourCtx.newXmlParser(); + + MyPatientWithExtensions patient = new MyPatientWithExtensions(); + patient.setId("123"); + patient.getText().setDivAsString("OK!"); + + final String respString = p.encodeResourceToString(patient); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IClientWithCustomType client = ourCtx.newRestfulClient(IClientWithCustomType.class, "http://example.com/fhir"); + MyPatientWithExtensions read = client.read(new IdType("1")); + assertEquals("
OK!
", read.getText().getDivAsString()); + } + + @Test + public void testValidateResourceOnly() throws Exception { + IParser p = ourCtx.newXmlParser(); + + OperationOutcome conf = new OperationOutcome(); + conf.getText().setDivAsString("OK!"); + + final String respString = p.encodeResourceToString(conf); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + } + }); + + IClient client = ourCtx.newRestfulClient(IClient.class, "http://example.com/fhir"); + + Patient patient = new Patient(); + patient.addName().setFamily("FAM"); + + int idx = 0; + MethodOutcome outcome = client.validate(patient, null, null); + String resp = ourCtx.newXmlParser().encodeResourceToString(outcome.getOperationOutcome()); + assertEquals("
OK!
", resp); + assertEquals("http://example.com/fhir/$validate", capt.getAllValues().get(idx).getURI().toString()); + String request = extractBodyAsString(capt,idx); + assertEquals("", request); + + idx = 1; + outcome = client.validate(patient, ValidationModeEnum.CREATE, "http://foo"); + resp = ourCtx.newXmlParser().encodeResourceToString(outcome.getOperationOutcome()); + assertEquals("
OK!
", resp); + assertEquals("http://example.com/fhir/$validate", capt.getAllValues().get(idx).getURI().toString()); + request = extractBodyAsString(capt,idx); + assertEquals("", request); + } + + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() { + ourCtx = FhirContext.forR4(); + } + + private interface IClient extends IRestfulClient { + + @Validate + MethodOutcome validate(@ResourceParam IBaseResource theResource, @Validate.Mode ValidationModeEnum theMode, @Validate.Profile String theProfile); + + } + + private interface IClientWithCustomType extends IRestfulClient { + + @Search + List search(); + + @Read + MyPatientWithExtensions read(@IdParam IdType theId); + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/OperationClientR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/OperationClientR4Test.java new file mode 100644 index 00000000000..e5a7bdfa107 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/OperationClientR4Test.java @@ -0,0 +1,188 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.InputStream; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.*; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.r4.model.Parameters; +import org.hl7.fhir.r4.model.StringType; +import org.junit.*; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.google.common.base.Charsets; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.Operation; +import ca.uhn.fhir.rest.annotation.OperationParam; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.client.api.*; +import ca.uhn.fhir.rest.param.*; +import ca.uhn.fhir.util.TestUtil; + +public class OperationClientR4Test { + + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(OperationClientR4Test.class); + private FhirContext ourCtx; + private HttpClient ourHttpClient; + + private HttpResponse ourHttpResponse; + private IOpClient ourAnnClient; + private ArgumentCaptor capt; + private IGenericClient ourGenClient; + + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + + @Before + public void before() throws Exception { + ourCtx = FhirContext.forR4(); + + ourHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(ourHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + + ourHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + + Parameters outParams = new Parameters(); + outParams.addParameter().setName("FOO"); + final String retVal = ourCtx.newXmlParser().encodeResourceToString(outParams); + + capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse); + when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(retVal), Charset.forName("UTF-8")); + } + }); + + ourAnnClient = ourCtx.newRestfulClient(IOpClient.class, "http://foo"); + ourGenClient = ourCtx.newRestfulGenericClient("http://foo"); + } + + @Test + public void testNonRepeatingGenericUsingParameters() throws Exception { + ourGenClient + .operation() + .onServer() + .named("nonrepeating") + .withSearchParameter(Parameters.class, "valstr", new StringParam("str")) + .andSearchParameter("valtok", new TokenParam("sys2", "val2")) + .execute(); + Parameters response = ourAnnClient.nonrepeating(new StringParam("str"), new TokenParam("sys", "val")); + assertEquals("FOO", response.getParameter().get(0).getName()); + + HttpPost value = (HttpPost) capt.getAllValues().get(0); + String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent()); + ourLog.info(requestBody); + Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody); + assertEquals("http://foo/$nonrepeating", value.getURI().toASCIIString()); + assertEquals(2, request.getParameter().size()); + assertEquals("valstr", request.getParameter().get(0).getName()); + assertEquals("str", ((StringType) request.getParameter().get(0).getValue()).getValue()); + assertEquals("valtok", request.getParameter().get(1).getName()); + assertEquals("sys2|val2", ((StringType) request.getParameter().get(1).getValue()).getValue()); + } + + @Test + public void testNonRepeatingGenericUsingUrl() throws Exception { + ourGenClient + .operation() + .onServer() + .named("nonrepeating") + .withSearchParameter(Parameters.class, "valstr", new StringParam("str")) + .andSearchParameter("valtok", new TokenParam("sys2", "val2")) + .useHttpGet() + .execute(); + Parameters response = ourAnnClient.nonrepeating(new StringParam("str"), new TokenParam("sys", "val")); + assertEquals("FOO", response.getParameter().get(0).getName()); + + HttpGet value = (HttpGet) capt.getAllValues().get(0); + assertEquals("http://foo/$nonrepeating?valstr=str&valtok=sys2%7Cval2", value.getURI().toASCIIString()); + } + + @Test + public void testNonRepeatingUsingParameters() throws Exception { + Parameters response = ourAnnClient.nonrepeating(new StringParam("str"), new TokenParam("sys", "val")); + assertEquals("FOO", response.getParameter().get(0).getName()); + + HttpPost value = (HttpPost) capt.getAllValues().get(0); + String requestBody = IOUtils.toString(((HttpPost) value).getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(((HttpPost) value).getEntity().getContent()); + ourLog.info(requestBody); + Parameters request = ourCtx.newXmlParser().parseResource(Parameters.class, requestBody); + assertEquals("http://foo/$nonrepeating", value.getURI().toASCIIString()); + assertEquals(2, request.getParameter().size()); + assertEquals("valstr", request.getParameter().get(0).getName()); + assertEquals("str", ((StringType) request.getParameter().get(0).getValue()).getValue()); + assertEquals("valtok", request.getParameter().get(1).getName()); + assertEquals("sys|val", ((StringType) request.getParameter().get(1).getValue()).getValue()); + } + + public interface IOpClient extends IBasicClient { + + @Operation(name = "$andlist", idempotent = true) + public Parameters andlist( + //@formatter:off + @OperationParam(name="valstr", max=10) StringAndListParam theValStr, + @OperationParam(name="valtok", max=10) TokenAndListParam theValTok + //@formatter:on + ); + + @Operation(name = "$andlist-withnomax", idempotent = true) + public Parameters andlistWithNoMax( + //@formatter:off + @OperationParam(name="valstr") StringAndListParam theValStr, + @OperationParam(name="valtok") TokenAndListParam theValTok + //@formatter:on + ); + + @Operation(name = "$nonrepeating", idempotent = true) + public Parameters nonrepeating( + //@formatter:off + @OperationParam(name="valstr") StringParam theValStr, + @OperationParam(name="valtok") TokenParam theValTok + //@formatter:on + ); + + @Operation(name = "$orlist", idempotent = true) + public Parameters orlist( + //@formatter:off + @OperationParam(name="valstr", max=10) List theValStr, + @OperationParam(name="valtok", max=10) List theValTok + //@formatter:on + ); + + @Operation(name = "$orlist-withnomax", idempotent = true) + public Parameters orlistWithNoMax( + //@formatter:off + @OperationParam(name="valstr") List theValStr, + @OperationParam(name="valtok") List theValTok + //@formatter:on + ); + + } +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/PatchClientR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/PatchClientR4Test.java new file mode 100644 index 00000000000..de790524193 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/PatchClientR4Test.java @@ -0,0 +1,131 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.Charset; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.r4.model.*; +import org.junit.*; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.PatchTypeEnum; +import ca.uhn.fhir.rest.client.api.*; +import ca.uhn.fhir.util.TestUtil; + +public class PatchClientR4Test { + public interface IClientType extends IRestfulClient { + + @Patch(type=Patient.class) + MethodOutcome patch(@IdParam IdType theId, @ResourceParam String theBody, PatchTypeEnum thePatchType); + + } + + private static FhirContext ourCtx; + private HttpClient myHttpClient; + private HttpResponse myHttpResponse; + + @Before + public void before() { + myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + } + + @Test + public void testJsonPatchAnnotation() throws Exception { + ArgumentCaptor capt = prepareResponse(); + + IClientType client = ourCtx.newRestfulClient(IClientType.class, "http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + + MethodOutcome outcome = client.patch(new IdType("Patient/123"), "{}", PatchTypeEnum.JSON_PATCH); + + assertEquals("PATCH", capt.getAllValues().get(0).getMethod()); + assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(0).getURI().toASCIIString()); + assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals("{}", extractBodyAsString(capt)); + assertEquals("
OK
", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString()); + } + + @Test + @Ignore + public void testJsonPatchFluent() throws Exception { + ArgumentCaptor capt = prepareResponse(); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient pt = new Patient(); + pt.getText().setDivAsString("A PATIENT"); + +// MethodOutcome outcome = client.patch().resource(""). + +// patch(new IdType("Patient/123"), "{}", PatchTypeEnum.JSON_PATCH); + +// assertEquals("PATCH", capt.getAllValues().get(0).getMethod()); +// assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(0).getURI().toASCIIString()); +// assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", "")); +// assertEquals("{}", extractBodyAsString(capt)); +// assertEquals("
OK
", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString()); + } + + + private String extractBodyAsString(ArgumentCaptor capt) throws IOException { + String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8"); + return body; + } + + private ArgumentCaptor prepareResponse() throws IOException, ClientProtocolException { + final IParser p = ourCtx.newXmlParser(); + + final OperationOutcome resp1 = new OperationOutcome(); + resp1.getText().setDivAsString("OK"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML_NEW + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + } + }); + return capt; + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() { + ourCtx = FhirContext.forR4(); + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/SearchClientR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/SearchClientR4Test.java new file mode 100644 index 00000000000..b51706bb5d1 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/SearchClientR4Test.java @@ -0,0 +1,234 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.InputStream; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.*; + +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; +import org.junit.*; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.annotation.Count; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.SortOrderEnum; +import ca.uhn.fhir.rest.api.SortSpec; +import ca.uhn.fhir.rest.client.api.IRestfulClient; +import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.util.TestUtil; +import ca.uhn.fhir.util.UrlUtil; + +public class SearchClientR4Test { + + private FhirContext ourCtx; + private HttpClient ourHttpClient; + private HttpResponse ourHttpResponse; + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @Before + public void before() { + ourCtx = FhirContext.forR4(); + + ourHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(ourHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + + ourHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + } + + /** + * See #299 + */ + @Test + public void testListResponseWithSearchExtension() throws Exception { + + final String response = createBundleWithSearchExtension(); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse); + when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(response), Charset.forName("UTF-8")); + } + }); + + ILocationClient client = ourCtx.newRestfulClient(ILocationClient.class, "http://localhost:8081/hapi-fhir/fhir"); + + List matches = client.getMatches(new StringParam("smith"), 100); + assertEquals(1, matches.size()); + assertEquals("Sample Clinic", matches.get(0).getName()); + + HttpGet value = (HttpGet) capt.getValue(); + assertEquals("http://localhost:8081/hapi-fhir/fhir/Location?_query=match&name=smith&_count=100", value.getURI().toString()); + } + + /** + * See #371 + */ + @Test + public void testSortForDstu3() throws Exception { + + final String response = createBundleWithSearchExtension(); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse); + when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(response), Charset.forName("UTF-8")); + } + }); + + ILocationClient client = ourCtx.newRestfulClient(ILocationClient.class, "http://localhost/fhir"); + + int idx = 0; + + client.search(new SortSpec("param1", SortOrderEnum.ASC)); + assertEquals("http://localhost/fhir/Bundle?_sort=param1", ((HttpGet) capt.getAllValues().get(idx++)).getURI().toString()); + + client.search(new SortSpec("param1", SortOrderEnum.ASC).setChain(new SortSpec("param2", SortOrderEnum.DESC))); + assertEquals("http://localhost/fhir/Bundle?_sort=param1%2C-param2", ((HttpGet) capt.getAllValues().get(idx++)).getURI().toString()); + } + + @Test + public void testSearchWithPrimitiveTypes() throws Exception { + TimeZone tz = TimeZone.getDefault(); + try { + TimeZone.setDefault(TimeZone.getTimeZone("America/Toronto")); + + Date date = new Date(23898235986L); + Calendar cal = new GregorianCalendar(); + cal.setTime(date); + ; + + final String response = createBundleWithSearchExtension(); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse); + when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(response), Charset.forName("UTF-8")); + } + }); + + ILocationClient client = ourCtx.newRestfulClient(ILocationClient.class, "http://localhost/fhir"); + + int idx = 0; + + client.search("STRING1", new StringType("STRING2"), date, cal); + assertEquals("http://localhost/fhir/Bundle?stringParam=STRING1&stringTypeParam=STRING2&dateParam=1970-10-04T10:23:55.986-04:00&calParam=1970-10-04T10:23:55.986-04:00", + UrlUtil.unescape(((HttpGet) capt.getAllValues().get(idx++)).getURI().toString())); + + client.search(null, null, null, null); + assertEquals("http://localhost/fhir/Bundle", + UrlUtil.unescape(((HttpGet) capt.getAllValues().get(idx++)).getURI().toString())); + } finally { + TimeZone.setDefault(tz); + } + } + + /** + * See #299 + */ + @Test + public void testBundleResponseWithSearchExtension() throws Exception { + + final String response = createBundleWithSearchExtension(); + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(ourHttpClient.execute(capt.capture())).thenReturn(ourHttpResponse); + when(ourHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(ourHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(ourHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(response), Charset.forName("UTF-8")); + } + }); + + ILocationClient client = ourCtx.newRestfulClient(ILocationClient.class, "http://localhost:8081/hapi-fhir/fhir"); + + Bundle matches = client.getMatchesReturnBundle(new StringParam("smith"), 100); + + assertEquals(1, matches.getEntry().size()); + BundleEntryComponent entry = matches.getEntry().get(0); + assertEquals("Sample Clinic", ((Location) entry.getResource()).getName()); + + List ext = entry.getSearch().getExtensionsByUrl("http://hl7.org/fhir/StructureDefinition/algorithmic-match"); + assertEquals(1, ext.size()); + + HttpGet value = (HttpGet) capt.getValue(); + assertEquals("http://localhost:8081/hapi-fhir/fhir/Location?_query=match&name=smith&_count=100", value.getURI().toString()); + } + + private String createBundleWithSearchExtension() { + //@formatter:off + final String response = "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + //@formatter:on + return response; + } + + public interface ILocationClient extends IRestfulClient { + @Search(queryName = "match") + public List getMatches(final @RequiredParam(name = Location.SP_NAME) StringParam name, final @Count Integer count); + + @Search(queryName = "match", type = Location.class) + public Bundle getMatchesReturnBundle(final @RequiredParam(name = Location.SP_NAME) StringParam name, final @Count Integer count); + + @Search + public Bundle search(@Sort SortSpec theSort); + + @Search + public Bundle search(@OptionalParam(name = "stringParam") String theString, @OptionalParam(name = "stringTypeParam") StringType theStringDt, @OptionalParam(name = "dateParam") Date theDate, + @OptionalParam(name = "calParam") Calendar theCal); + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateBinaryR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateBinaryR4Test.java new file mode 100644 index 00000000000..51d2abef86f --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateBinaryR4Test.java @@ -0,0 +1,168 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.*; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.Create; +import ca.uhn.fhir.rest.annotation.ResourceParam; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class CreateBinaryR4Test { + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static Binary ourLastBinary; + private static byte[] ourLastBinaryBytes; + private static String ourLastBinaryString; + private static int ourPort; + private static Server ourServer; + + @Before + public void before() { + ourLastBinary = null; + ourLastBinaryBytes = null; + ourLastBinaryString = null; + } + + @Test + public void testRawBytesBinaryContentType() throws Exception { + HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary"); + post.setEntity(new ByteArrayEntity(new byte[] { 0, 1, 2, 3, 4 })); + post.addHeader("Content-Type", "application/foo"); + CloseableHttpResponse status = ourClient.execute(post); + try { + assertEquals("application/foo", ourLastBinary.getContentType()); + assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourLastBinary.getContent()); + assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourLastBinaryBytes); + } finally { + IOUtils.closeQuietly(status); + } + } + + /** + * Technically the client shouldn't be doing it this way, but we'll be accepting + */ + @Test + public void testRawBytesFhirContentType() throws Exception { + + Binary b = new Binary(); + b.setContentType("application/foo"); + b.setContent(new byte[] { 0, 1, 2, 3, 4 }); + String encoded = ourCtx.newJsonParser().encodeResourceToString(b); + + HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary"); + post.setEntity(new StringEntity(encoded)); + post.addHeader("Content-Type", Constants.CT_FHIR_JSON); + CloseableHttpResponse status = ourClient.execute(post); + try { + assertEquals("application/foo", ourLastBinary.getContentType()); + assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourLastBinary.getContent()); + } finally { + IOUtils.closeQuietly(status); + } + } + + @Test + public void testRawBytesFhirContentTypeContainingFhir() throws Exception { + + Patient p = new Patient(); + p.getText().setDivAsString("A PATIENT"); + + Binary b = new Binary(); + b.setContentType("application/xml+fhir"); + b.setContent(ourCtx.newXmlParser().encodeResourceToString(p).getBytes("UTF-8")); + String encoded = ourCtx.newJsonParser().encodeResourceToString(b); + + HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary"); + post.setEntity(new StringEntity(encoded)); + post.addHeader("Content-Type", Constants.CT_FHIR_JSON); + CloseableHttpResponse status = ourClient.execute(post); + try { + assertEquals("application/xml+fhir", ourLastBinary.getContentType()); + assertArrayEquals(b.getContent(), ourLastBinary.getContent()); + assertEquals(encoded, ourLastBinaryString); + assertArrayEquals(encoded.getBytes("UTF-8"), ourLastBinaryBytes); + } finally { + IOUtils.closeQuietly(status); + } + } + + @Test + public void testRawBytesNoContentType() throws Exception { + HttpPost post = new HttpPost("http://localhost:" + ourPort + "/Binary"); + post.setEntity(new ByteArrayEntity(new byte[] { 0, 1, 2, 3, 4 })); + CloseableHttpResponse status = ourClient.execute(post); + try { + assertNull(ourLastBinary.getContentType()); + assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourLastBinary.getContent()); + } finally { + IOUtils.closeQuietly(status); + } + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + BinaryProvider binaryProvider = new BinaryProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.setResourceProviders(binaryProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + } + + public static class BinaryProvider implements IResourceProvider { + + @Create() + public MethodOutcome createBinary(@ResourceParam Binary theBinary, @ResourceParam String theBinaryString, @ResourceParam byte[] theBinaryBytes) { + ourLastBinary = theBinary; + ourLastBinaryString = theBinaryString; + ourLastBinaryBytes = theBinaryBytes; + return new MethodOutcome(new IdType("Binary/001/_history/002")); + } + + @Override + public Class getResourceType() { + return Binary.class; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateR4Test.java new file mode 100644 index 00000000000..e2a39db2802 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CreateR4Test.java @@ -0,0 +1,269 @@ +package ca.uhn.fhir.rest.server; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.stringContainsInOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.OperationOutcome.OperationOutcomeIssueComponent; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.client.MyPatientWithExtensions; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class CreateR4Test { + private static CloseableHttpClient ourClient; + + private static FhirContext ourCtx = FhirContext.forR4(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CreateR4Test.class); + private static int ourPort; + private static Server ourServer; + public static IBaseOperationOutcome ourReturnOo; + + @Before + public void before() { + ourReturnOo = null; + } + + /** + * #472 + */ + @Test + public void testCreateReturnsLocationHeader() throws Exception { + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity("{\"resourceType\":\"Patient\", \"status\":\"active\"}", ContentType.parse("application/fhir+json; charset=utf-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + + assertEquals(1, status.getHeaders("Location").length); + assertEquals(0, status.getHeaders("Content-Location").length); + assertEquals("http://localhost:" + ourPort + "/Patient/1", status.getFirstHeader("Location").getValue()); + + } + + @Test + public void testCreateReturnsOperationOutcome() throws Exception { + ourReturnOo = new OperationOutcome().addIssue(new OperationOutcomeIssueComponent().setDiagnostics("DIAG")); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity("{\"resourceType\":\"Patient\", \"status\":\"active\"}", ContentType.parse("application/fhir+json; charset=utf-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + + assertThat(responseContent, containsString("DIAG")); + } + + /** + * #342 + */ + @Test + public void testCreateWithInvalidContent() throws Exception { + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity("FOO", ContentType.parse("application/xml+fhir; charset=utf-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(400, status.getStatusLine().getStatusCode()); + + assertThat(responseContent, containsString("", + "", + "", + "", + "", + "", + "", + "", + "")); + //@formatter:on + + assertThat(responseContent, not(containsString("http://hl7.org/fhir/"))); + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + PatientProvider patientProvider = new PatientProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class PatientProvider implements IResourceProvider { + + @Create() + public MethodOutcome create(@ResourceParam Patient theIdParam) { + return new MethodOutcome(new IdType("Patient", "1"), true).setOperationOutcome(ourReturnOo); + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Read() + public MyPatientWithExtensions read(@IdParam IdType theIdParam) { + MyPatientWithExtensions p0 = new MyPatientWithExtensions(); + p0.setId(theIdParam); + p0.setDateExt(new DateType("2011-01-01")); + return p0; + } + + @Search + public List search() { + ArrayList retVal = new ArrayList(); + + MyPatientWithExtensions p0 = new MyPatientWithExtensions(); + p0.setId(new IdType("Patient/0")); + p0.setDateExt(new DateType("2011-01-01")); + retVal.add(p0); + + Patient p1 = new Patient(); + p1.setId(new IdType("Patient/1")); + p1.addName().setFamily("The Family"); + retVal.add(p1); + + return retVal; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CustomTypeServerR4.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CustomTypeServerR4.java new file mode 100644 index 00000000000..db560aa7835 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/CustomTypeServerR4.java @@ -0,0 +1,171 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.assertEquals; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.r4.model.*; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.primitive.StringDt; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class CustomTypeServerR4 { + private static CloseableHttpClient ourClient; + + private static FhirContext ourCtx = FhirContext.forR4(); + private static String ourLastConditionalUrl; + private static IdType ourLastId; + private static IdType ourLastIdParam; + private static boolean ourLastRequestWasSearch; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CustomTypeServerR4.class); + private static int ourPort; + private static Server ourServer; + + @Before + public void before() { + ourLastId = null; + ourLastConditionalUrl = null; + ourLastIdParam = null; + ourLastRequestWasSearch = false; + } + + + @Test + public void testCreateWithIdInBody() throws Exception { + + Patient patient = new Patient(); + patient.setId("2"); + patient.addIdentifier().setValue("002"); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); +// httpPost.addHeader(Constants.HEADER_IF_NONE_EXIST, "Patient?identifier=system%7C001"); + httpPost.setEntity(new StringEntity(ourCtx.newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + } + + @Test + public void testCreateWithIdInUrl() throws Exception { + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/2"); +// httpPost.addHeader(Constants.HEADER_IF_NONE_EXIST, "Patient?identifier=system%7C001"); + httpPost.setEntity(new StringEntity(ourCtx.newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(400, status.getStatusLine().getStatusCode()); + OperationOutcome oo = ourCtx.newXmlParser().parseResource(OperationOutcome.class, responseContent); + assertEquals("Can not create resource with ID \"2\", ID must not be supplied on a create (POST) operation (use an HTTP PUT / update operation if you wish to supply an ID)", oo.getIssue().get(0).getDiagnostics()); + } + + @Test + public void testCreateWithIdInUrlForConditional() throws Exception { + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/2"); + httpPost.addHeader(Constants.HEADER_IF_NONE_EXIST, "Patient?identifier=system%7C001"); + httpPost.setEntity(new StringEntity(ourCtx.newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(400, status.getStatusLine().getStatusCode()); + OperationOutcome oo = ourCtx.newXmlParser().parseResource(OperationOutcome.class, responseContent); + assertEquals("Can not create resource with ID \"2\", ID must not be supplied on a create (POST) operation (use an HTTP PUT / update operation if you wish to supply an ID)", oo.getIssue().get(0).getDiagnostics()); + } + + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + PatientProvider patientProvider = new PatientProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class PatientProvider implements IResourceProvider { + + @Create() + public MethodOutcome createPatient(@ResourceParam Patient thePatient, @ConditionalUrlParam String theConditional, @IdParam IdType theIdParam) { + ourLastConditionalUrl = theConditional; + ourLastId = thePatient.getIdElement(); + ourLastIdParam = theIdParam; + return new MethodOutcome(new IdType("Patient/001/_history/002")); + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Search + public List search(@OptionalParam(name = "foo") StringDt theString) { + ourLastRequestWasSearch = true; + return new ArrayList(); + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/DateRangeParamSearchR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/DateRangeParamSearchR4Test.java new file mode 100644 index 00000000000..095e31de5bb --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/DateRangeParamSearchR4Test.java @@ -0,0 +1,230 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.assertEquals; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; + +import com.google.common.base.Charsets; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; +import ca.uhn.fhir.rest.annotation.RequiredParam; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.param.DateRangeParam; +import ca.uhn.fhir.rest.param.ParamPrefixEnum; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class DateRangeParamSearchR4Test { + + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static DateRangeParam ourLastDateRange; + private static int ourPort; + + private static Server ourServer; + private static SimpleDateFormat ourFmt; + private static String ourBaseUrl; + + @Before + public void before() { + ourLastDateRange = null; + } + + @Test + public void testSearchForMultipleUnqualifiedDate() throws Exception { + String baseUrl = "http://localhost:" + ourPort + "/Patient?" + Patient.SP_BIRTHDATE + "="; + HttpGet httpGet = new HttpGet(baseUrl + "2012-01-01&" + Patient.SP_BIRTHDATE + "=2012-02-03"); + HttpResponse status = ourClient.execute(httpGet); + IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(400, status.getStatusLine().getStatusCode()); + + } + + + @Test + public void testSearchForOneUnqualifiedDate() throws Exception { + HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=2012-01-01"); + HttpResponse status = ourClient.execute(httpGet); + IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("2012-01-01", ourLastDateRange.getLowerBound().getValueAsString()); + assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString()); + + assertEquals(parse("2012-01-01 00:00:00.0000"), ourLastDateRange.getLowerBoundAsInstant()); + assertEquals(parseM1("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant()); + assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getLowerBound().getPrefix()); + assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getUpperBound().getPrefix()); + } + + @Test + public void testSearchForOneQualifiedDateEq() throws Exception { + HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=eq2012-01-01"); + HttpResponse status = ourClient.execute(httpGet); + IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("2012-01-01", ourLastDateRange.getLowerBound().getValueAsString()); + assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString()); + + assertEquals(parse("2012-01-01 00:00:00.0000"), ourLastDateRange.getLowerBoundAsInstant()); + assertEquals(parseM1("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant()); + assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getLowerBound().getPrefix()); + assertEquals(ParamPrefixEnum.EQUAL, ourLastDateRange.getUpperBound().getPrefix()); + } + + @Test + public void testSearchForOneQualifiedDateGt() throws Exception { + HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=gt2012-01-01"); + HttpResponse status = ourClient.execute(httpGet); + IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("2012-01-01", ourLastDateRange.getLowerBound().getValueAsString()); + assertEquals(null, ourLastDateRange.getUpperBound()); + + assertEquals(parse("2012-01-02 00:00:00.0000"), ourLastDateRange.getLowerBoundAsInstant()); + assertEquals(null, ourLastDateRange.getUpperBoundAsInstant()); + assertEquals(ParamPrefixEnum.GREATERTHAN, ourLastDateRange.getLowerBound().getPrefix()); + assertEquals(null, ourLastDateRange.getUpperBound()); + } + + @Test + public void testSearchForOneQualifiedDateLt() throws Exception { + HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=lt2012-01-01"); + HttpResponse status = ourClient.execute(httpGet); + IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals(null, ourLastDateRange.getLowerBound()); + assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString()); + + assertEquals(null, ourLastDateRange.getLowerBoundAsInstant()); + assertEquals(parseM1("2012-01-01 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant()); + assertEquals(null, ourLastDateRange.getLowerBound()); + assertEquals(ParamPrefixEnum.LESSTHAN, ourLastDateRange.getUpperBound().getPrefix()); + } + + @Test + public void testSearchForOneQualifiedDateGe() throws Exception { + HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=ge2012-01-01"); + HttpResponse status = ourClient.execute(httpGet); + IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("2012-01-01", ourLastDateRange.getLowerBound().getValueAsString()); + assertEquals(null, ourLastDateRange.getUpperBound()); + + assertEquals(parse("2012-01-01 00:00:00.0000"), ourLastDateRange.getLowerBoundAsInstant()); + assertEquals(null, ourLastDateRange.getUpperBoundAsInstant()); + assertEquals(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, ourLastDateRange.getLowerBound().getPrefix()); + assertEquals(null, ourLastDateRange.getUpperBound()); + } + + @Test + public void testSearchForOneQualifiedDateLe() throws Exception { + HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=le2012-01-01"); + HttpResponse status = ourClient.execute(httpGet); + IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals(null, ourLastDateRange.getLowerBound()); + assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString()); + + assertEquals(null, ourLastDateRange.getLowerBoundAsInstant()); + assertEquals(parseM1("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant()); + assertEquals(null, ourLastDateRange.getLowerBound()); + assertEquals(ParamPrefixEnum.LESSTHAN_OR_EQUALS, ourLastDateRange.getUpperBound().getPrefix()); + } + + + public static Date parse(String theString) throws ParseException { + return ourFmt.parse(theString); + } + + public static Date parseM1(String theString) throws ParseException { + return new Date(ourFmt.parse(theString).getTime() - 1L); + } + static { + ourFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS"); + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); + + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + ourBaseUrl = "http://localhost:" + ourPort + "/Patient"; + } + + + public static class DummyPatientResourceProvider implements IResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } + + + @Search() + public List search(@RequiredParam(name=Patient.SP_BIRTHDATE) DateRangeParam theDateRange) { + ourLastDateRange = theDateRange; + + ArrayList retVal = new ArrayList(); + + Patient patient = new Patient(); + patient.setId("1"); + patient.addIdentifier().setSystem("system").setValue("hello"); + retVal.add(patient); + return retVal; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/DeleteConditionalR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/DeleteConditionalR4Test.java new file mode 100644 index 00000000000..af27c110792 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/DeleteConditionalR4Test.java @@ -0,0 +1,128 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.TimeUnit; + +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class DeleteConditionalR4Test { + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static IGenericClient ourHapiClient; + private static String ourLastConditionalUrl; + private static IdType ourLastIdParam; + private static boolean ourLastRequestWasDelete; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DeleteConditionalR4Test.class); + private static int ourPort; + private static Server ourServer; + + + @Before + public void before() { + ourLastConditionalUrl = null; + ourLastIdParam = null; + ourLastRequestWasDelete = false; + } + + + + @Test + public void testSearchStillWorks() throws Exception { + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + +// HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_pretty=true"); +// +// HttpResponse status = ourClient.execute(httpGet); +// +// String responseContent = IOUtils.toString(status.getEntity().getContent()); +// IOUtils.closeQuietly(status.getEntity().getContent()); +// +// ourLog.info("Response was:\n{}", responseContent); + + //@formatter:off + ourHapiClient + .delete() + .resourceConditionalByType(Patient.class) + .where(Patient.IDENTIFIER.exactly().systemAndIdentifier("SOMESYS","SOMEID")) + .execute(); + //@formatter:on + + assertTrue(ourLastRequestWasDelete); + assertEquals(null, ourLastIdParam); + assertEquals("Patient?identifier=SOMESYS%7CSOMEID", ourLastConditionalUrl); + + } + + + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + PatientProvider patientProvider = new PatientProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + ourCtx.getRestfulClientFactory().setSocketTimeout(500 * 1000); + ourHapiClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort + "/"); + ourHapiClient.registerInterceptor(new LoggingInterceptor()); + } + + public static class PatientProvider implements IResourceProvider { + + @Delete() + public MethodOutcome deletePatient(@IdParam IdType theIdParam, @ConditionalUrlParam String theConditional) { + ourLastRequestWasDelete = true; + ourLastConditionalUrl = theConditional; + ourLastIdParam = theIdParam; + return new MethodOutcome(new IdType("Patient/001/_history/002")); + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/OperationServerR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/OperationServerR4Test.java new file mode 100644 index 00000000000..2f8a26f8ec8 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/OperationServerR4Test.java @@ -0,0 +1,768 @@ +package ca.uhn.fhir.rest.server; + +import static org.hamcrest.Matchers.containsInRelativeOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.*; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.*; +import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestOperationComponent; +import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class OperationServerR4Test { + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx; + + private static IdType ourLastId; + private static String ourLastMethod; + private static StringType ourLastParam1; + private static Patient ourLastParam2; + private static List ourLastParam3; + private static Money ourLastParamMoney1; + private static UnsignedIntType ourLastParamUnsignedInt1; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(OperationServerR4Test.class); + private static int ourPort; + private static Server ourServer; + private IGenericClient myFhirClient; + + @Before + public void before() { + ourLastParam1 = null; + ourLastParam2 = null; + ourLastParam3 = null; + ourLastParamUnsignedInt1 = null; + ourLastParamMoney1 = null; + ourLastId = null; + ourLastMethod = ""; + + myFhirClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort); + } + + + @Test + public void testConformance() throws Exception { + LoggingInterceptor loggingInterceptor = new LoggingInterceptor(); + loggingInterceptor.setLogResponseBody(true); + myFhirClient.registerInterceptor(loggingInterceptor); + + CapabilityStatement p = myFhirClient.fetchConformance().ofType(CapabilityStatement.class).prettyPrint().execute(); + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p)); + + List ops = p.getRest().get(0).getOperation(); + assertThat(ops.size(), greaterThan(1)); + + List opNames = toOpNames(ops); + assertThat(opNames, containsInRelativeOrder("OP_TYPE")); + +// OperationDefinition def = (OperationDefinition) ops.get(opNames.indexOf("OP_TYPE")).getDefinition().getResource(); + OperationDefinition def = myFhirClient.read().resource(OperationDefinition.class).withId(ops.get(opNames.indexOf("OP_TYPE")).getDefinition().getReferenceElement()).execute(); + assertEquals("OP_TYPE", def.getCode()); + } + + /** + * See #380 + */ + @Test + public void testOperationDefinition() { + OperationDefinition def = myFhirClient.read().resource(OperationDefinition.class).withId("OperationDefinition/Patient--OP_TYPE").execute(); + + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(def)); + +// @OperationParam(name="PARAM1") StringType theParam1, +// @OperationParam(name="PARAM2") Patient theParam2, +// @OperationParam(name="PARAM3", min=2, max=5) List theParam3, +// @OperationParam(name="PARAM4", min=1) List theParam4, + + assertEquals(4, def.getParameter().size()); + assertEquals("PARAM1", def.getParameter().get(0).getName()); + assertEquals(OperationParameterUse.IN, def.getParameter().get(0).getUse()); + assertEquals(0, def.getParameter().get(0).getMin()); + assertEquals("1", def.getParameter().get(0).getMax()); + + assertEquals("PARAM2", def.getParameter().get(1).getName()); + assertEquals(OperationParameterUse.IN, def.getParameter().get(1).getUse()); + assertEquals(0, def.getParameter().get(1).getMin()); + assertEquals("1", def.getParameter().get(1).getMax()); + + assertEquals("PARAM3", def.getParameter().get(2).getName()); + assertEquals(OperationParameterUse.IN, def.getParameter().get(2).getUse()); + assertEquals(2, def.getParameter().get(2).getMin()); + assertEquals("5", def.getParameter().get(2).getMax()); + + assertEquals("PARAM4", def.getParameter().get(3).getName()); + assertEquals(OperationParameterUse.IN, def.getParameter().get(3).getUse()); + assertEquals(1, def.getParameter().get(3).getMin()); + assertEquals("*", def.getParameter().get(3).getMax()); + + } + + private List toOpNames(List theOps) { + ArrayList retVal = new ArrayList(); + for (CapabilityStatementRestOperationComponent next : theOps) { + retVal.add(next.getName()); + } + return retVal; + } + + @Test + public void testInstanceEverythingGet() throws Exception { + + // Try with a GET + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$everything"); + CloseableHttpResponse status = ourClient.execute(httpGet); + + assertEquals(200, status.getStatusLine().getStatusCode()); + String response = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + assertEquals("instance $everything", ourLastMethod); + assertThat(response, startsWith(" getResourceType() { + return Patient.class; + } + + //@formatter:off + @Operation(name="$OP_INSTANCE") + public Parameters opInstance( + @IdParam IdType theId, + @OperationParam(name="PARAM1") StringType theParam1, + @OperationParam(name="PARAM2") Patient theParam2 + ) { + //@formatter:on + + ourLastMethod = "$OP_INSTANCE"; + ourLastId = theId; + ourLastParam1 = theParam1; + ourLastParam2 = theParam2; + + Parameters retVal = new Parameters(); + retVal.addParameter().setName("RET1").setValue(new StringType("RETVAL1")); + return retVal; + } + + //@formatter:off + @Operation(name="$OP_INSTANCE_OR_TYPE") + public Parameters opInstanceOrType( + @IdParam(optional=true) IdType theId, + @OperationParam(name="PARAM1") StringType theParam1, + @OperationParam(name="PARAM2") Patient theParam2 + ) { + //@formatter:on + + ourLastMethod = "$OP_INSTANCE_OR_TYPE"; + ourLastId = theId; + ourLastParam1 = theParam1; + ourLastParam2 = theParam2; + + Parameters retVal = new Parameters(); + retVal.addParameter().setName("RET1").setValue(new StringType("RETVAL1")); + return retVal; + } + + //@formatter:off + @Operation(name="$OP_PROFILE_DT2", idempotent=true) + public Bundle opProfileType( + @OperationParam(name="PARAM1") Money theParam1 + ) { + //@formatter:on + + ourLastMethod = "$OP_PROFILE_DT2"; + ourLastParamMoney1 = theParam1; + + Bundle retVal = new Bundle(); + retVal.addEntry().getResponse().setStatus("100"); + return retVal; + } + + //@formatter:off + @Operation(name="$OP_PROFILE_DT", idempotent=true) + public Bundle opProfileType( + @OperationParam(name="PARAM1") UnsignedIntType theParam1 + ) { + //@formatter:on + + ourLastMethod = "$OP_PROFILE_DT"; + ourLastParamUnsignedInt1 = theParam1; + + Bundle retVal = new Bundle(); + retVal.addEntry().getResponse().setStatus("100"); + return retVal; + } + + //@formatter:off + @SuppressWarnings("unused") + @Operation(name="$OP_TYPE", idempotent=true) + public Parameters opType( + @OperationParam(name="PARAM1") StringType theParam1, + @OperationParam(name="PARAM2") Patient theParam2, + @OperationParam(name="PARAM3", min=2, max=5) List theParam3, + @OperationParam(name="PARAM4", min=1) List theParam4 + ) { + //@formatter:on + + ourLastMethod = "$OP_TYPE"; + ourLastParam1 = theParam1; + ourLastParam2 = theParam2; + + Parameters retVal = new Parameters(); + retVal.addParameter().setName("RET1").setValue(new StringType("RETVAL1")); + return retVal; + } + + //@formatter:off + @Operation(name="$OP_TYPE_ONLY_STRING", idempotent=true) + public Parameters opTypeOnlyString( + @OperationParam(name="PARAM1") StringType theParam1 + ) { + //@formatter:on + + ourLastMethod = "$OP_TYPE"; + ourLastParam1 = theParam1; + + Parameters retVal = new Parameters(); + retVal.addParameter().setName("RET1").setValue(new StringType("RETVAL1")); + return retVal; + } + + //@formatter:off + @Operation(name="$OP_TYPE_RET_BUNDLE") + public Bundle opTypeRetBundle( + @OperationParam(name="PARAM1") StringType theParam1, + @OperationParam(name="PARAM2") Patient theParam2 + ) { + //@formatter:on + + ourLastMethod = "$OP_TYPE_RET_BUNDLE"; + ourLastParam1 = theParam1; + ourLastParam2 = theParam2; + + Bundle retVal = new Bundle(); + retVal.addEntry().getResponse().setStatus("100"); + return retVal; + } + + @Operation(name = "$everything", idempotent=true) + public Bundle patientEverything(@IdParam IdType thePatientId) { + ourLastMethod = "instance $everything"; + ourLastId = thePatientId; + return new Bundle(); + } + + /** + * Just to make sure this method doesn't "steal" calls + */ + @Read + public Patient read(@IdParam IdType theId) { + ourLastMethod = "read"; + Patient retVal = new Patient(); + retVal.setId(theId); + return retVal; + } + + } + + public static class PlainProvider { + + //@formatter:off + @Operation(name="$OP_INSTANCE_BUNDLE_PROVIDER", idempotent=true) + public IBundleProvider opInstanceReturnsBundleProvider() { + ourLastMethod = "$OP_INSTANCE_BUNDLE_PROVIDER"; + + List resources = new ArrayList(); + for (int i =0; i < 100;i++) { + Patient p = new Patient(); + p.setId("Patient/" + i); + p.addName().setFamily("Patient " + i); + resources.add(p); + } + + return new SimpleBundleProvider(resources); + } + + //@formatter:off + @Operation(name="$OP_SERVER") + public Parameters opServer( + @OperationParam(name="PARAM1") StringType theParam1, + @OperationParam(name="PARAM2") Patient theParam2 + ) { + //@formatter:on + + ourLastMethod = "$OP_SERVER"; + ourLastParam1 = theParam1; + ourLastParam2 = theParam2; + + Parameters retVal = new Parameters(); + retVal.addParameter().setName("RET1").setValue(new StringType("RETVAL1")); + return retVal; + } + + //@formatter:off + @Operation(name="$OP_SERVER_LIST_PARAM") + public Parameters opServerListParam( + @OperationParam(name="PARAM2") Patient theParam2, + @OperationParam(name="PARAM3") List theParam3 + ) { + //@formatter:on + + ourLastMethod = "$OP_SERVER_LIST_PARAM"; + ourLastParam2 = theParam2; + ourLastParam3 = theParam3; + + Parameters retVal = new Parameters(); + retVal.addParameter().setName("RET1").setValue(new StringType("RETVAL1")); + return retVal; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchBundleProviderWithNoSizeR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchBundleProviderWithNoSizeR4Test.java new file mode 100644 index 00000000000..3c023bfb794 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchBundleProviderWithNoSizeR4Test.java @@ -0,0 +1,187 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Bundle.BundleLinkComponent; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.google.common.collect.Lists; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.TokenAndListParam; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class SearchBundleProviderWithNoSizeR4Test { + + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static TokenAndListParam ourIdentifiers; + private static IBundleProvider ourLastBundleProvider; + private static String ourLastMethod; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchBundleProviderWithNoSizeR4Test.class); + private static int ourPort; + + private static Server ourServer; + + @Before + public void before() { + ourLastMethod = null; + ourIdentifiers = null; + } + + @Test + public void testBundleProviderReturnsNoSize() throws Exception { + Bundle respBundle; + + ourLastBundleProvider = mock(IBundleProvider.class); + when(ourLastBundleProvider.size()).thenReturn(null); + when(ourLastBundleProvider.getResources(any(int.class), any(int.class))).then(new Answer>() { + @Override + public List answer(InvocationOnMock theInvocation) throws Throwable { + int from =(Integer)theInvocation.getArguments()[0]; + int to =(Integer)theInvocation.getArguments()[1]; + ArrayList retVal = Lists.newArrayList(); + for (int i = from; i < to; i++) { + Patient p = new Patient(); + p.setId(Integer.toString(i)); + retVal.add(p); + } + return retVal; + }}); + + HttpGet httpGet; + CloseableHttpResponse status = null; + BundleLinkComponent linkNext; + + try { + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=json"); + status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("searchAll", ourLastMethod); + respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, responseContent); + + assertEquals(10, respBundle.getEntry().size()); + assertEquals("Patient/0", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue()); + linkNext = respBundle.getLink("next"); + assertNotNull(linkNext); + + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + + + when(ourLastBundleProvider.size()).thenReturn(25); + + try { + httpGet = new HttpGet(linkNext.getUrl()); + status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("searchAll", ourLastMethod); + respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, responseContent); + + assertEquals(10, respBundle.getEntry().size()); + assertEquals("Patient/10", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue()); + linkNext = respBundle.getLink("next"); + assertNotNull(linkNext); + + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + + try { + httpGet = new HttpGet(linkNext.getUrl()); + status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("searchAll", ourLastMethod); + respBundle = ourCtx.newJsonParser().parseResource(Bundle.class, responseContent); + + assertEquals(5, respBundle.getEntry().size()); + assertEquals("Patient/20", respBundle.getEntry().get(0).getResource().getIdElement().toUnqualifiedVersionless().getValue()); + linkNext = respBundle.getLink("next"); + assertNull(linkNext); + + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.setPagingProvider(new FifoMemoryPagingProvider(10)); + + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class DummyPatientResourceProvider implements IResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Search() + public IBundleProvider searchAll() { + ourLastMethod = "searchAll"; + return ourLastBundleProvider; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchHasParamR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchHasParamR4Test.java new file mode 100644 index 00000000000..cc7f07419b8 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchHasParamR4Test.java @@ -0,0 +1,119 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.HumanName; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; + +import com.google.common.base.Charsets; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.OptionalParam; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.param.*; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class SearchHasParamR4Test { + + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchHasParamR4Test.class); + private static int ourPort; + private static Server ourServer; + private static String ourLastMethod; + private static HasAndListParam ourLastParam; + + @Before + public void before() { + ourLastMethod = null; + ourLastParam = null; + } + + @Test + public void testSearch() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_has:Encounter:patient:type=SURG"); + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("search", ourLastMethod); + + HasParam param = ourLastParam.getValuesAsQueryTokens().get(0).getValuesAsQueryTokens().get(0); + assertEquals("Encounter", param.getTargetResourceType()); + assertEquals("patient", param.getOwningFieldName()); + assertEquals("type", param.getParameterName()); + assertEquals("SURG", param.getParameterValue()); + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.setPagingProvider(new FifoMemoryPagingProvider(10)); + + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class DummyPatientResourceProvider implements IResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } + + //@formatter:off + @SuppressWarnings("rawtypes") + @Search() + public List search( + @OptionalParam(name=Patient.SP_IDENTIFIER) TokenParam theIdentifier, + @OptionalParam(name="_has") HasAndListParam theParam + ) { + ourLastMethod = "search"; + ourLastParam = theParam; + ArrayList retVal = new ArrayList(); + retVal.add((Patient) new Patient().addName(new HumanName().setFamily("FAMILY")).setId("1")); + return retVal; + } + //@formatter:on + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchR4Test.java new file mode 100644 index 00000000000..e42c6769101 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchR4Test.java @@ -0,0 +1,368 @@ +package ca.uhn.fhir.rest.server; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.*; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.RequiredParam; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.EncodingEnum; +import ca.uhn.fhir.rest.api.SearchStyleEnum; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; +import ca.uhn.fhir.rest.gclient.StringClientParam; +import ca.uhn.fhir.rest.param.TokenAndListParam; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.util.*; + +public class SearchR4Test { + + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static TokenAndListParam ourIdentifiers; + private static String ourLastMethod; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchR4Test.class); + private static int ourPort; + + private static Server ourServer; + + @Before + public void before() { + ourLastMethod = null; + ourIdentifiers = null; + } + + @Test + public void testSearchNormal() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar"); + CloseableHttpResponse status = ourClient.execute(httpGet); + try { + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("search", ourLastMethod); + + assertEquals("foo", ourIdentifiers.getValuesAsQueryTokens().get(0).getValuesAsQueryTokens().get(0).getSystem()); + assertEquals("bar", ourIdentifiers.getValuesAsQueryTokens().get(0).getValuesAsQueryTokens().get(0).getValue()); + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + + } + + @Test + public void testSearchWithInvalidChain() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier.chain=foo%7Cbar"); + CloseableHttpResponse status = ourClient.execute(httpGet); + try { + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(responseContent); + assertEquals(400, status.getStatusLine().getStatusCode()); + + OperationOutcome oo = (OperationOutcome) ourCtx.newJsonParser().parseResource(responseContent); + assertEquals( + "Invalid search parameter \"identifier.chain\". Parameter contains a chain (.chain) and chains are not supported for this parameter (chaining is only allowed on reference parameters)", + oo.getIssueFirstRep().getDiagnostics()); + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + + } + + + @Test + public void testPagingPreservesEncodingJson() throws Exception { + HttpGet httpGet; + String linkNext; + Bundle bundle; + + // Initial search + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar&_format=json"); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=json")); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=json")); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=json")); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=json")); + + } + + @Test + public void testPagingPreservesEncodingApplicationJsonFhir() throws Exception { + HttpGet httpGet; + String linkNext; + Bundle bundle; + + // Initial search + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar&_format=" + Constants.CT_FHIR_JSON_NEW); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW))); + + } + + @Test + public void testPagingPreservesEncodingXml() throws Exception { + HttpGet httpGet; + String linkNext; + Bundle bundle; + + // Initial search + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar&_format=xml"); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=xml")); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=xml")); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=xml")); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, containsString("_format=xml")); + + } + + @Test + public void testPagingPreservesEncodingNone() throws Exception { + HttpGet httpGet; + String linkNext; + Bundle bundle; + + // Initial search + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar"); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + } + + @Test + public void testPagingPreservesEncodingNoneWithBrowserAcceptHeader() throws Exception { + HttpGet httpGet; + String linkNext; + Bundle bundle; + + // Initial search + httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar"); + httpGet.addHeader(Constants.HEADER_ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + httpGet.addHeader(Constants.HEADER_ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + httpGet.addHeader(Constants.HEADER_ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + // Fetch the next page + httpGet = new HttpGet(linkNext); + httpGet.addHeader(Constants.HEADER_ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); + bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.XML); + linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertThat(linkNext, not(containsString("_format"))); + + } + + private Bundle executeAndReturnLinkNext(HttpGet httpGet, EncodingEnum theExpectEncoding) throws IOException, ClientProtocolException { + CloseableHttpResponse status = ourClient.execute(httpGet); + Bundle bundle; + try { + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + EncodingEnum ct = EncodingEnum.forContentType(status.getEntity().getContentType().getValue().replaceAll(";.*", "").trim()); + assertEquals(theExpectEncoding, ct); + bundle = ct.newParser(ourCtx).parseResource(Bundle.class, responseContent); + assertEquals(10, bundle.getEntry().size()); + String linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl(); + assertNotNull(linkNext); + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + return bundle; + } + + + @Test + public void testSearchWithPostAndInvalidParameters() throws Exception { + IGenericClient client = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort); + LoggingInterceptor interceptor = new LoggingInterceptor(); + interceptor.setLogRequestSummary(true); + interceptor.setLogRequestBody(true); + interceptor.setLogRequestHeaders(false); + interceptor.setLogResponseBody(false); + interceptor.setLogResponseHeaders(false); + interceptor.setLogResponseSummary(false); + client.registerInterceptor(interceptor); + try { + client + .search() + .forResource(Patient.class) + .where(new StringClientParam("foo").matches().value("bar")) + .encodedJson() + .prettyPrint() + .usingStyle(SearchStyleEnum.POST) + .returnBundle(org.hl7.fhir.r4.model.Bundle.class) + .execute(); + fail(); + } catch (InvalidRequestException e) { + assertThat(e.getMessage(), containsString("Invalid request: The FHIR endpoint on this server does not know how to handle POST operation[Patient/_search] with parameters [[_pretty, foo]]")); + } + + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.setDefaultResponseEncoding(EncodingEnum.JSON); + servlet.setPagingProvider(new FifoMemoryPagingProvider(10)); + + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class DummyPatientResourceProvider implements IResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } + + @SuppressWarnings("rawtypes") + @Search() + public List search( + @RequiredParam(name = Patient.SP_IDENTIFIER) TokenAndListParam theIdentifiers) { + ourLastMethod = "search"; + ourIdentifiers = theIdentifiers; + ArrayList retVal = new ArrayList(); + + for (int i = 0; i < 200; i++) { + Patient patient = new Patient(); + patient.addName(new HumanName().setFamily("FAMILY")); + patient.getIdElement().setValue("Patient/" + i); + retVal.add((Patient) patient); + } + return retVal; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchSortR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchSortR4Test.java new file mode 100644 index 00000000000..d712dc52e20 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/SearchSortR4Test.java @@ -0,0 +1,130 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.HumanName; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.annotation.Sort; +import ca.uhn.fhir.rest.api.SortOrderEnum; +import ca.uhn.fhir.rest.api.SortSpec; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class SearchSortR4Test { + + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchSortR4Test.class); + private static int ourPort; + private static Server ourServer; + private static String ourLastMethod; + private static SortSpec ourLastSortSpec; + + @Before + public void before() { + ourLastMethod = null; + ourLastSortSpec = null; + } + + @Test + public void testSearch() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_sort=param1,-param2,param3,-param4"); + CloseableHttpResponse status = ourClient.execute(httpGet); + try { + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("search", ourLastMethod); + + assertEquals("param1", ourLastSortSpec.getParamName()); + assertEquals(SortOrderEnum.ASC, ourLastSortSpec.getOrder()); + + assertEquals("param2", ourLastSortSpec.getChain().getParamName()); + assertEquals(SortOrderEnum.DESC, ourLastSortSpec.getChain().getOrder()); + + assertEquals("param3", ourLastSortSpec.getChain().getChain().getParamName()); + assertEquals(SortOrderEnum.ASC, ourLastSortSpec.getChain().getChain().getOrder()); + + assertEquals("param4", ourLastSortSpec.getChain().getChain().getChain().getParamName()); + assertEquals(SortOrderEnum.DESC, ourLastSortSpec.getChain().getChain().getChain().getOrder()); + + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + servlet.setPagingProvider(new FifoMemoryPagingProvider(10)); + + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class DummyPatientResourceProvider implements IResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } + + //@formatter:off + @SuppressWarnings("rawtypes") + @Search() + public List search( + @Sort SortSpec theSortSpec + ) { + ourLastMethod = "search"; + ourLastSortSpec = theSortSpec; + ArrayList retVal = new ArrayList(); + for (int i = 1; i < 100; i++) { + retVal.add((Patient) new Patient().addName(new HumanName().setFamily("FAMILY")).setId("" + i)); + } + return retVal; + } + //@formatter:on + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerMimetypeR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerMimetypeR4Test.java new file mode 100644 index 00000000000..836c580f266 --- /dev/null +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerMimetypeR4Test.java @@ -0,0 +1,395 @@ +package ca.uhn.fhir.rest.server; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.*; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.*; +import org.junit.*; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.client.MyPatientWithExtensions; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; + +public class ServerMimetypeR4Test { + private static CloseableHttpClient ourClient; + + private static FhirContext ourCtx = FhirContext.forR4(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerMimetypeR4Test.class); + private static int ourPort; + private static Server ourServer; + + @Test + public void testConformanceMetadataUsesNewMimetypes() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata"); + CloseableHttpResponse status = ourClient.execute(httpGet); + try { + String content = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + CapabilityStatement conf = ourCtx.newXmlParser().parseResource(CapabilityStatement.class, content); + List strings = toStrings(conf.getFormat()); + assertThat(strings, contains(Constants.CT_FHIR_XML_NEW, Constants.CT_FHIR_JSON_NEW)); + } finally { + status.close(); + } + } + + + + private List toStrings(List theFormat) { + ArrayList retVal = new ArrayList(); + for (CodeType next : theFormat) { + retVal.add(next.asStringValue()); + } + return retVal; + } + + + + @Test + public void testCreateWithXmlLegacyNoAcceptHeader() throws Exception { + Patient p = new Patient(); + p.addName().setFamily("FAMILY"); + String enc = ourCtx.newXmlParser().encodeResourceToString(p); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_XML, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals("", responseContent); + } + + @Test + public void testHttpTraceNotEnabled() throws Exception { + HttpTrace req = new HttpTrace("http://localhost:" + ourPort + "/Patient"); + CloseableHttpResponse status = ourClient.execute(req); + try { + ourLog.info(status.toString()); + assertEquals(400, status.getStatusLine().getStatusCode()); + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + } + + @Test + public void testHttpTrackNotEnabled() throws Exception { + HttpRequestBase req = new HttpRequestBase() { + @Override + public String getMethod() { + return "TRACK"; + }}; + req.setURI(new URI("http://localhost:" + ourPort + "/Patient")); + + CloseableHttpResponse status = ourClient.execute(req); + try { + ourLog.info(status.toString()); + assertEquals(400, status.getStatusLine().getStatusCode()); + } finally { + IOUtils.closeQuietly(status.getEntity().getContent()); + } + } + + @Test + public void testCreateWithXmlNewNoAcceptHeader() throws Exception { + Patient p = new Patient(); + p.addName().setFamily("FAMILY"); + String enc = ourCtx.newXmlParser().encodeResourceToString(p); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML_NEW + "; charset=utf-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals("", responseContent); + } + + @Test + public void testCreateWithXmlNewWithAcceptHeader() throws Exception { + Patient p = new Patient(); + p.addName().setFamily("FAMILY"); + String enc = ourCtx.newXmlParser().encodeResourceToString(p); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8"))); + httpPost.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_XML_NEW); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals("", responseContent); + } + + @Test + public void testCreateWithJsonLegacyNoAcceptHeader() throws Exception { + Patient p = new Patient(); + p.addName().setFamily("FAMILY"); + String enc = ourCtx.newJsonParser().encodeResourceToString(p); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON + "; charset=utf-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_JSON, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent); + } + + @Test + public void testCreateWithJsonNewNoAcceptHeader() throws Exception { + Patient p = new Patient(); + p.addName().setFamily("FAMILY"); + String enc = ourCtx.newJsonParser().encodeResourceToString(p); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON_NEW + "; charset=utf-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent); + } + + @Test + public void testCreateWithJsonNewWithAcceptHeader() throws Exception { + Patient p = new Patient(); + p.addName().setFamily("FAMILY"); + String enc = ourCtx.newJsonParser().encodeResourceToString(p); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON + "; charset=utf-8"))); + httpPost.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_JSON_NEW); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent); + } + + @Test + public void testSearchWithFormatXmlSimple() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=xml"); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("")); + assertThat(responseContent, not(containsString("http://hl7.org/fhir/"))); + assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + } + + @Test + public void testSearchWithFormatXmlLegacy() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_XML); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("")); + assertThat(responseContent, not(containsString("http://hl7.org/fhir/"))); + assertEquals(Constants.CT_FHIR_XML, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + } + + @Test + public void testSearchWithFormatXmlNew() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_XML_NEW); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("")); + assertThat(responseContent, not(containsString("http://hl7.org/fhir/"))); + assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + } + + + + @Test + public void testSearchWithFormatJsonSimple() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=json"); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("\"resourceType\"")); + assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + } + + @Test + public void testSearchWithFormatJsonLegacy() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_JSON); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("\"resourceType\"")); + assertEquals(Constants.CT_FHIR_JSON, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + } + + @Test + public void testSearchWithFormatJsonNew() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_JSON_NEW); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("\"resourceType\"")); + assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", "")); + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + PatientProvider patientProvider = new PatientProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(ourCtx); + + servlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class PatientProvider implements IResourceProvider { + + @Create() + public MethodOutcome create(@ResourceParam Patient theIdParam) { + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setDiagnostics(theIdParam.getNameFirstRep().getFamily()); + return new MethodOutcome(new IdType("Patient", "1"), true).setOperationOutcome(oo); + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Read() + public MyPatientWithExtensions read(@IdParam IdType theIdParam) { + MyPatientWithExtensions p0 = new MyPatientWithExtensions(); + p0.setId(theIdParam); + p0.setDateExt(new DateType("2011-01-01")); + return p0; + } + + @Search + public List search() { + ArrayList retVal = new ArrayList(); + + MyPatientWithExtensions p0 = new MyPatientWithExtensions(); + p0.setId(new IdType("Patient/0")); + p0.setDateExt(new DateType("2011-01-01")); + retVal.add(p0); + + Patient p1 = new Patient(); + p1.setId(new IdType("Patient/1")); + p1.addName().setFamily("The Family"); + retVal.add(p1); + + return retVal; + } + + } + +} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/AllTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/AllTests.java deleted file mode 100644 index c09bf8c6c7c..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/AllTests.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.hl7.fhir.r4.test; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ FluentPathTests.class, NarrativeGeneratorTests.class, /*ShexGeneratorTests.class, StructureMapTests.class, */ TurtleTests.class, GraphQLParserTests.class }) -public class AllTests { - -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/FluentPathTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/FluentPathTests.java deleted file mode 100644 index 48138d27ff4..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/FluentPathTests.java +++ /dev/null @@ -1,135 +0,0 @@ -package org.hl7.fhir.r4.test; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; - -import org.hl7.fhir.r4.context.SimpleWorkerContext; -import org.hl7.fhir.r4.formats.XmlParser; -import org.hl7.fhir.r4.model.Base; -import org.hl7.fhir.r4.model.BooleanType; -import org.hl7.fhir.r4.model.ExpressionNode; -import org.hl7.fhir.r4.model.PrimitiveType; -import org.hl7.fhir.r4.model.Resource; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.r4.utils.FHIRPathEngine; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.xml.XMLUtil; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - -import junit.framework.Assert; - -@RunWith(Parameterized.class) -public class FluentPathTests { - - private static FHIRPathEngine fp; - - @Parameters(name = "{index}: file {0}") - public static Iterable data() throws ParserConfigurationException, SAXException, IOException { - Document dom = XMLUtil.parseFileToDom(Utilities.path(TestingUtilities. home(), "tests", "resources", "tests-fhir-r4.xml")); - - List list = new ArrayList(); - List groups = new ArrayList(); - XMLUtil.getNamedChildren(dom.getDocumentElement(), "group", groups); - for (Element g : groups) { - XMLUtil.getNamedChildren(g, "test", list); - } - - List objects = new ArrayList(list.size()); - - for (Element e : list) { - objects.add(new Object[] { getName(e), e }); - } - - return objects; - } - - private static Object getName(Element e) { - String s = e.getAttribute("name"); - if (Utilities.noString(s)) { - Element p = (Element) e.getParentNode(); - int ndx = 0; - for (int i = 0; i < p.getChildNodes().getLength(); i++) { - Node c = p.getChildNodes().item(i); - if (c == e) - break; - else if (c instanceof Element) - ndx++; - } - s = p.getAttribute("name")+" - "+Integer.toString(ndx+1); - } - return s; - } - - private final Element test; - private final String name; - - public FluentPathTests(String name, Element e) { - this.name = name; - this.test = e; - } - - @SuppressWarnings("deprecation") - @Test - public void test() throws FileNotFoundException, IOException, FHIRException, org.hl7.fhir.exceptions.FHIRException { - if (TestingUtilities.context == null) - TestingUtilities.context = SimpleWorkerContext.fromPack(Utilities.path(TestingUtilities.home(), "publish", "definitions.xml.zip")); - if (fp == null) - fp = new FHIRPathEngine(TestingUtilities.context); - String input = test.getAttribute("inputfile"); - String expression = XMLUtil.getNamedChild(test, "expression").getTextContent(); - boolean fail = "true".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid")); - Resource res = null; - - List outcome = new ArrayList(); - - ExpressionNode node = fp.parse(expression); - try { - if (Utilities.noString(input)) - fp.check(null, null, node); - else { - res = new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "publish", input))); - fp.check(res, res.getResourceType().toString(), res.getResourceType().toString(), node); - } - outcome = fp.evaluate(res, node); - Assert.assertTrue(String.format("Expected exception parsing %s", expression), !fail); - } catch (Exception e) { - Assert.assertTrue(String.format("Unexpected exception parsing %s: "+e.getMessage(), expression), fail); - } - - if ("true".equals(test.getAttribute("predicate"))) { - boolean ok = fp.convertToBoolean(outcome); - outcome.clear(); - outcome.add(new BooleanType(ok)); - } - if (fp.hasLog()) - System.out.println(fp.takeLog()); - - List expected = new ArrayList(); - XMLUtil.getNamedChildren(test, "output", expected); - Assert.assertTrue(String.format("Expected %d objects but found %d", expected.size(), outcome.size()), outcome.size() == expected.size()); - for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) { - String tn = expected.get(i).getAttribute("type"); - if (!Utilities.noString(tn)) { - Assert.assertTrue(String.format("Outcome %d: Type should be %s but was %s", i, tn, outcome.get(i).fhirType()), tn.equals(outcome.get(i).fhirType())); - } - String v = expected.get(i).getTextContent(); - if (!Utilities.noString(v)) { - Assert.assertTrue(String.format("Outcome %d: Value should be a primitive type but was %s", i, outcome.get(i).fhirType()), outcome.get(i) instanceof PrimitiveType); - Assert.assertTrue(String.format("Outcome %d: Value should be %s but was %s", i, v, outcome.get(i).toString()), v.equals(((PrimitiveType)outcome.get(i)).asStringValue())); - } - } - } -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/GraphQLEngineTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/GraphQLEngineTests.java deleted file mode 100644 index 13608d946ec..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/GraphQLEngineTests.java +++ /dev/null @@ -1,200 +0,0 @@ -package org.hl7.fhir.r4.test; - -import static org.junit.Assert.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; - -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.exceptions.FHIRFormatError; -import org.hl7.fhir.r4.context.SimpleWorkerContext; -import org.hl7.fhir.r4.formats.XmlParser; -import org.hl7.fhir.r4.model.Bundle; -import org.hl7.fhir.r4.model.DomainResource; -import org.hl7.fhir.r4.model.Reference; -import org.hl7.fhir.r4.model.Resource; -import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; -import org.hl7.fhir.r4.model.Bundle.BundleLinkComponent; -import org.hl7.fhir.r4.model.Bundle.SearchEntryMode; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.r4.utils.GraphQLEngine; -import org.hl7.fhir.r4.utils.GraphQLEngine.IGraphQLStorageServices; -import org.hl7.fhir.utilities.TextFile; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.graphql.Argument; -import org.hl7.fhir.utilities.graphql.EGraphEngine; -import org.hl7.fhir.utilities.graphql.EGraphQLException; -import org.hl7.fhir.utilities.graphql.NameValue; -import org.hl7.fhir.utilities.graphql.Package; -import org.hl7.fhir.utilities.graphql.Parser; -import org.hl7.fhir.utilities.xml.XMLUtil; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -@RunWith(Parameterized.class) -public class GraphQLEngineTests implements IGraphQLStorageServices { - - @Parameters(name = "{index}: {0}") - public static Iterable data() throws FileNotFoundException, IOException, ParserConfigurationException, SAXException { - Document tests = XMLUtil.parseFileToDom(Utilities.path(TestingUtilities.home(), "tests", "graphql", "manifest.xml")); - Element test = XMLUtil.getFirstChild(tests.getDocumentElement()); - List objects = new ArrayList(); - while (test != null && test.getNodeName().equals("test")) { - objects.add(new Object[] { test.getAttribute("name"), test.getAttribute("source"), test.getAttribute("output"), - test.getAttribute("context"), test.getAttribute("resource"), test.getAttribute("operation")} ); - test = XMLUtil.getNextSibling(test); - } - return objects; - } - - private final String name; - private String source; - private String output; - private String context; - private String resource; - private String operation; - - public GraphQLEngineTests(String name, String source, String output, String context, String resource, String operation) { - this.name = name; - this.source = source; - this.output = output; - this.context = context; - this.resource = resource; - this.operation = operation; - } - - @Test - public void test() throws Exception { - String filename = null; - if (!Utilities.noString(context)) { - String[] parts = context.split("/"); - if (parts.length != 3) - throw new Exception("not done yet "+source+" "+output+" "+context); - if (!Utilities.noString(resource)) - filename = Utilities.path(TestingUtilities.home(), "publish", resource+".xml"); - else - filename = Utilities.path(TestingUtilities.home(), "publish", parts[0].toLowerCase()+"-"+parts[1].toLowerCase()+".xml"); - } - - if (TestingUtilities.context == null) - TestingUtilities.context = SimpleWorkerContext.fromPack(Utilities.path(TestingUtilities.home(), "publish", "definitions.xml.zip")); - - GraphQLEngine gql = new GraphQLEngine(TestingUtilities.context); - gql.setServices(this); - if (!Utilities.noString(filename)) - gql.setFocus(new XmlParser().parse(new FileInputStream(filename))); - gql.setGraphQL(Parser.parseFile(Utilities.path(TestingUtilities.home(), "tests", "graphql", source))); - gql.getGraphQL().setOperationName(operation); - gql.getGraphQL().getVariables().add(new Argument("var", new NameValue("true"))); - boolean ok = false; - String msg = null; - try { - gql.execute(); - ok = true; - } catch (Exception e) { - if (!output.equals("$error")) - e.printStackTrace(); - ok = false; - msg = e.getMessage(); - } - if (ok) { - Assert.assertTrue("Expected to fail, but didn't", !output.equals("$error")); - StringBuilder str = new StringBuilder(); - gql.getOutput().write(str, 0); - TextFile.stringToFile(str.toString(), Utilities.path(TestingUtilities.home(), "tests", "graphql", output+".out")); - msg = TestingUtilities.checkJsonIsSame(Utilities.path(TestingUtilities.home(), "tests", "graphql", output+".out"),Utilities.path(TestingUtilities.home(), "tests", "graphql", output)); - Assert.assertTrue(msg, Utilities.noString(msg)); - } - else - Assert.assertTrue("Error, but proper output was expected ("+msg+")", output.equals("$error")); - } - - @Override - public Resource lookup(Object appInfo, String type, String id) throws FHIRException { - try { - String filename = Utilities.path(TestingUtilities.home(), "publish", type.toLowerCase()+'-'+id.toLowerCase()+".xml"); - if (new File(filename).exists()) - return new XmlParser().parse(new FileInputStream(filename)); - else - return null; - } catch (Exception e) { - throw new FHIRException(e); - } - } - - @Override - public ReferenceResolution lookup(Object appInfo, Resource context, Reference reference) throws FHIRException { - try { - if (reference.getReference().startsWith("#")) { - if (!(context instanceof DomainResource)) - return null; - for (Resource r : ((DomainResource)context).getContained()) { - if (('#'+r.getId()).equals(reference.getReference())) { - return new ReferenceResolution(context, r); - } - } - } else { - String[] parts = reference.getReference().split("/"); - String filename = Utilities.path(TestingUtilities.home(), "publish", parts[0].toLowerCase()+'-'+parts[1].toLowerCase()+".xml"); - if (new File(filename).exists()) - return new ReferenceResolution(null, new XmlParser().parse(new FileInputStream(filename))); - } - return null; - } catch (Exception e) { - throw new FHIRException(e); - } - } - - @Override - public void listResources(Object appInfo, String type, List searchParams, List matches) throws FHIRException { - try { - if (type.equals("Condition")) - matches.add(new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "publish", "condition-example.xml")))); - else if (type.equals("Patient")) { - matches.add(new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "publish", "patient-example.xml")))); - matches.add(new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "publish", "patient-example-xds.xml")))); - } - } catch (Exception e) { - throw new FHIRException(e); - } - } - - @Override - public Bundle search(Object appInfo, String type, List searchParams) throws FHIRException { - try { - Bundle bnd = new Bundle(); - BundleLinkComponent bl = bnd.addLink(); - bl.setRelation("next"); - bl.setUrl("http://test.fhir.org/r3/Patient?_format=text/xhtml&search-id=77c97e03-8a6c-415f-a63d-11c80cf73f&&active=true&_sort=_id&search-offset=50&_count=50"); - bl = bnd.addLink(); - bl.setRelation("self"); - bl.setUrl("http://test.fhir.org/r3/Patient?_format=text/xhtml&search-id=77c97e03-8a6c-415f-a63d-11c80cf73f&&active=true&_sort=_id&search-offset=0&_count=50"); - BundleEntryComponent be = bnd.addEntry(); - be.setFullUrl("http://hl7.org/fhir/Patient/example"); - be.setResource(new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "publish", "patient-example.xml")))); - be = bnd.addEntry(); - be.setFullUrl("http://hl7.org/fhir/Patient/example"); - be.setResource(new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "publish", "patient-example-xds.xml")))); - be.getSearch().setScore(0.5); - be.getSearch().setMode(SearchEntryMode.MATCH); - bnd.setTotal(50); - return bnd; - } catch (Exception e) { - throw new FHIRException(e); - } - } - -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/GraphQLParserTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/GraphQLParserTests.java deleted file mode 100644 index 2bb0aba384a..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/GraphQLParserTests.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.hl7.fhir.r4.test; - -import static org.junit.Assert.*; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; - -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.utilities.TextFile; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.graphql.EGraphEngine; -import org.hl7.fhir.utilities.graphql.EGraphQLException; -import org.hl7.fhir.utilities.graphql.Package; -import org.hl7.fhir.utilities.graphql.Parser; -import org.hl7.fhir.utilities.xml.XMLUtil; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -@RunWith(Parameterized.class) -public class GraphQLParserTests { - - @Parameters(name = "{index}: {0}") - public static Iterable data() throws FileNotFoundException, IOException { - String src = TextFile.fileToString(Utilities.path(TestingUtilities.home(), "tests", "graphql", "parser-tests.gql")); - String[] tests = src.split("###"); - int i = 0; - for (String s : tests) - if (!Utilities.noString(s.trim())) - i++; - List objects = new ArrayList(i); - i = 0; - for (String s : tests) { - if (!Utilities.noString(s.trim())) { - int l = s.indexOf('\r'); - objects.add(new Object[] { s.substring(0, l), s.substring(l+2).trim()}); - } - } - return objects; - } - - private final String test; - private final String name; - - public GraphQLParserTests(String name, String test) { - this.name = name; - this.test = test; - } - - @Test - public void test() throws IOException, EGraphQLException, EGraphEngine { - Package doc = Parser.parse(test); - Assert.assertTrue(doc != null); - } - - -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/NarrativeGeneratorTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/NarrativeGeneratorTests.java deleted file mode 100644 index 2204b756416..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/NarrativeGeneratorTests.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.hl7.fhir.r4.test; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.hl7.fhir.r4.context.SimpleWorkerContext; -import org.hl7.fhir.r4.formats.XmlParser; -import org.hl7.fhir.r4.model.DomainResource; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.r4.utils.EOperationOutcome; -import org.hl7.fhir.r4.utils.NarrativeGenerator; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.exceptions.FHIRException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.xmlpull.v1.XmlPullParserException; - -public class NarrativeGeneratorTests { - - private NarrativeGenerator gen; - - @Before - public void setUp() throws FileNotFoundException, IOException, FHIRException { - if (TestingUtilities.context == null) - TestingUtilities.context = SimpleWorkerContext.fromPack(Utilities.path(TestingUtilities.home(), "publish", "definitions.xml.zip")); - if (gen == null) - gen = new NarrativeGenerator("", null, TestingUtilities.context); - } - - @After - public void tearDown() { - } - - @Test - public void test() throws FileNotFoundException, IOException, XmlPullParserException, EOperationOutcome, FHIRException { - process(Utilities.path(TestingUtilities.home(), "source", "questionnaireresponse", "questionnaireresponse-example-f201-lifelines.xml")); - } - - private void process(String path) throws FileNotFoundException, IOException, XmlPullParserException, EOperationOutcome, FHIRException { - XmlParser p = new XmlParser(); - DomainResource r = (DomainResource) p.parse(new FileInputStream(path)); - gen.generate(r); - FileOutputStream s = new FileOutputStream(Utilities.path(TestingUtilities.temp(), "gen.xml")); - new XmlParser().compose(s, r, true); - s.close(); - - } - -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ProfileUtilitiesTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ProfileUtilitiesTests.java deleted file mode 100644 index eb93be56ff1..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ProfileUtilitiesTests.java +++ /dev/null @@ -1,940 +0,0 @@ -package org.hl7.fhir.r4.test; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.hl7.fhir.r4.conformance.ProfileComparer; -import org.hl7.fhir.r4.conformance.ProfileComparer.ProfileComparison; -import org.hl7.fhir.r4.conformance.ProfileUtilities; -import org.hl7.fhir.r4.context.SimpleWorkerContext; -import org.hl7.fhir.r4.formats.IParser.OutputStyle; -import org.hl7.fhir.r4.formats.XmlParser; -import org.hl7.fhir.r4.model.Base; -import org.hl7.fhir.r4.model.CodeType; -import org.hl7.fhir.r4.model.ElementDefinition; -import org.hl7.fhir.r4.model.ElementDefinition.DiscriminatorType; -import org.hl7.fhir.r4.model.ElementDefinition.SlicingRules; -import org.hl7.fhir.r4.model.Enumerations.BindingStrength; -import org.hl7.fhir.r4.model.Reference; -import org.hl7.fhir.r4.model.StructureDefinition; -import org.hl7.fhir.r4.model.StructureDefinition.TypeDerivationRule; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.r4.utils.EOperationOutcome; -import org.hl7.fhir.exceptions.DefinitionException; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.exceptions.FHIRFormatError; -import org.hl7.fhir.utilities.CSFile; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.validation.ValidationMessage; -import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; -import static org.junit.Assert.*; - -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.r4.utils.SnomedExpressions; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - - -public class ProfileUtilitiesTests { - -// private String root; -// private SimpleWorkerContext context; -// private ProfileComparer comp; -// -//// public ProfileUtilitiesTests(String root) { -//// super(); -//// this.root = root; -//// } -// -//// public ProfileUtilitiesTests() { -//// super(); -//// root = TestingUtilities.home(); -//// -//// } -// -// public static void main(String[] args) throws EOperationOutcome, Exception { -// // new ProfileUtilitiesTests().execute(args); -// ProfileUtilitiesTests put = new ProfileUtilitiesTests(); -// put.root = "C:\\work\\org.hl7.fhir\\build\\publish"; -// put.testSnapshotGeneration(); -// // StructureDefinition p = (StructureDefinition) new XmlParser().parse(new FileInputStream("C:\\work\\org.hl7.fhir\\build\\publish\\lipid-report-cholesterol.profile.xml")); -// // new ProfileUtilities(context, messages, null).generateSchematrons(new FileOutputStream("c:\\temp\\test.sch"), p); -// } -// -// public void execute(String[] args) throws FileNotFoundException, IOException, FHIRException { -// System.out.println("loading context"); -// context = SimpleWorkerContext.fromPack(Utilities.path(root, "validation.zip")); -// comp = new ProfileComparer(context); -// -// compare("patient-daf-dafpatient.profile.xml", "patient-qicore-qicore-patient.profile.xml"); -// compare("encounter-daf-dafencounter.profile.xml", "encounter-qicore-qicore-encounter.profile.xml"); -// compare("substance-daf-dafsubstance.profile.xml", "substance-qicore-qicore-substance.profile.xml"); -// compare("medication-daf-dafmedication.profile.xml", "medication-qicore-qicore-medication.profile.xml"); -// compare("procedure-daf-dafprocedure.profile.xml", "procedure-qicore-qicore-procedure.profile.xml"); -// compare("familymemberhistory-daf-daffamilymemberhistory.profile.xml", "familymemberhistory-qicore-qicore-familymemberhistory.profile.xml"); -// compare("immunization-daf-dafimmunization.profile.xml", "immunization-qicore-qicore-immunization.profile.xml"); -// compare("condition-daf-dafcondition.profile.xml", "condition-qicore-qicore-condition.profile.xml"); -// compare("allergyintolerance-daf-dafallergyintolerance.profile.xml", "allergyintolerance-qicore-qicore-allergyintolerance.profile.xml"); -// compare("medicationadministration-daf-dafmedicationadministration.profile.xml", "medicationadministration-qicore-qicore-medicationadministration.profile.xml"); -// compare("medicationdispense-daf-dafmedicationdispense.profile.xml", "medicationdispense-qicore-qicore-medicationdispense.profile.xml"); -// compare("medicationprescription-daf-dafmedicationprescription.profile.xml", "medicationprescription-qicore-qicore-medicationprescription.profile.xml"); -// compare("medicationstatement-daf-dafmedicationstatement.profile.xml", "medicationstatement-qicore-qicore-medicationstatement.profile.xml"); -// compare("observation-daf-smokingstatus-dafsmokingstatus.profile.xml", "observation-qicore-qicore-observation.profile.xml"); -// compare("observation-daf-vitalsigns-dafvitalsigns.profile.xml", "observation-qicore-qicore-observation.profile.xml"); -//// compare("observation-daf-results-dafresultobs.profile.xml", "observation-qicore-qicore-observation.profile.xml"); -//// compare("diagnosticorder-daf-dafdiagnosticorder.profile.xml", "diagnosticorder-qicore-qicore-diagnosticorder.profile.xml"); -//// compare("diagnosticreport-daf-dafdiagnosticreport.profile.xml", "diagnosticreport-qicore-qicore-diagnosticreport.profile.xml"); -// -// System.out.println("processing output"); -// for (ProfileComparison outcome : comp.getComparisons()) { -// if (outcome.getSubset() != null) -// new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream("C:\\temp\\intersection-"+outcome.getId()+".xml"), outcome.getSubset()); -// if (outcome.getSuperset() != null) -// new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream("C:\\temp\\union-"+outcome.getId()+".xml"), outcome.getSuperset()); -// -// System.out.println("\r\n"+outcome.getId()+": Comparison of "+outcome.getLeft().getUrl()+" and "+outcome.getRight().getUrl()); -// for (ValidationMessage vm : outcome.getMessages()) -// if (vm.getLevel() == IssueSeverity.INFORMATION) -// System.out.println(vm.summary()); -// for (ValidationMessage vm : outcome.getMessages()) -// if (vm.getLevel() == IssueSeverity.WARNING) -// System.out.println(vm.summary()); -// for (ValidationMessage vm : outcome.getMessages()) -// if (vm.getLevel() == IssueSeverity.ERROR) -// System.out.println(vm.summary()); -// for (ValidationMessage vm : outcome.getMessages()) -// if (vm.getLevel() == IssueSeverity.FATAL) -// System.out.println(vm.summary()); -// System.out.println("done. "+Integer.toString(outcome.getMessages().size())+" messages"); -// System.out.println("================================================================="); -// } -// } -// -// private void compare(String fn1, String fn2) throws FHIRFormatError, FileNotFoundException, IOException, DefinitionException { -// System.out.println("Compare "+fn1+" to "+fn2); -// System.out.println(" .. load"); -// StructureDefinition left = (StructureDefinition) new XmlParser().parse(new FileInputStream(Utilities.path(root, fn1))); -// StructureDefinition right = (StructureDefinition) new XmlParser().parse(new FileInputStream(Utilities.path(root, fn2))); -// System.out.println(" .. compare"); -// comp.compareProfiles(left, right); -// -// } -// -// public void testSnapshotGeneration() throws EOperationOutcome, Exception { -// System.out.println("Loading"); -// context = SimpleWorkerContext.fromPack(Utilities.path(root, "definitions.xml.zip")); -// System.out.println("Loaded "+Integer.toString(context.totalCount())+" resources"); -// -// // simple tests -// testSimple(); -// testSimple2(); -// testCardinalityChange(); -// testDocumentationAppend(); -// textTypeNarrowing1(); -// textTypeNarrowing2(); -// testMapping(); -// -// // ok, now we test walking into a new type: -// testTypeWalk(); -// // todo: testTypeWalk2(); -// -// // slicing tests -// testSlicingSimple(); -// testSlicingExtension(false); -// testSlicingExtension(true); -// testSlicingExtensionComplex(true); -// testSlicingExtensionComplex(false); -// testSlicingTask8742(); -// System.out.println("Success"); -// } -// -// /** -// * This is simple: we just create an empty differential, generate the snapshot, and then insist it must match the base -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ - @Test - public void testSimple() throws FHIRException, FileNotFoundException, IOException { - if (TestingUtilities.context == null) - TestingUtilities.context = SimpleWorkerContext.fromPack(Utilities.path(TestingUtilities.home(), "publish", "definitions.xml.zip")); - - StructureDefinition focus = new StructureDefinition(); - StructureDefinition base = TestingUtilities.context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); - focus.setUrl(Utilities.makeUuidUrn()); - focus.setBaseDefinition(base.getUrl()); - focus.setType("Patient"); - focus.setDerivation(TypeDerivationRule.CONSTRAINT); - List messages = new ArrayList(); - new ProfileUtilities(TestingUtilities.context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test"); - - boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size(); - for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { - ElementDefinition b = base.getSnapshot().getElement().get(i); - ElementDefinition f = focus.getSnapshot().getElement().get(i); - if (ok) { - if (!f.hasBase()) - ok = false; - else if (!b.getPath().equals(f.getPath())) - ok = false; - else { - b.setBase(null); - f.setBase(null); - ok = Base.compareDeep(b, f, true); - } - } - } - - if (!ok) { - compareXml(base, focus); - throw new FHIRException("Snap shot generation simple test failed"); - } else - System.out.println("Snap shot generation simple test passed"); - } - - -// -// /** -// * This is simple: we just create an empty differential, generate the snapshot, and then insist it must match the base. for a different resource with recursion -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ - @Test - public void testSimple2() throws EOperationOutcome, Exception { - if (TestingUtilities.context == null) - TestingUtilities.context = SimpleWorkerContext.fromPack(Utilities.path(TestingUtilities.home(), "publish", "definitions.xml.zip")); - - StructureDefinition focus = new StructureDefinition(); - StructureDefinition base = TestingUtilities.context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/ValueSet").copy(); - focus.setUrl(Utilities.makeUuidUrn()); - focus.setBaseDefinition(base.getUrl()); - focus.setType(base.getType()); - focus.setDerivation(TypeDerivationRule.CONSTRAINT); - List messages = new ArrayList(); - new ProfileUtilities(TestingUtilities.context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); - - boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size(); - for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { - if (ok) { - ElementDefinition b = base.getSnapshot().getElement().get(i); - ElementDefinition f = focus.getSnapshot().getElement().get(i); - if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) - ok = false; - else { - f.setBase(null); - ok = Base.compareDeep(b, f, true); - } - } - } - - if (!ok) { - compareXml(base, focus); - throw new FHIRException("Snap shot generation simple test failed"); - } else - System.out.println("Snap shot generation simple test passed"); - } - -// /** -// * Change one cardinality. -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ -// private void testCardinalityChange() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier"); -// id.setMin(1); -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size(); -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.identifier")) { -// ok = f.getMin() == 1; -// if (ok) -// f.setMin(0); -// } -// ok = ok && Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation chenge cardinality test failed"); -// } else -// System.out.println("Snap shot generation chenge cardinality test passed"); -// } -// -// /** -// * check that documentation appending is working -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ -// private void testDocumentationAppend() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier"); -// id.setDefinition("... some more doco"); -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size(); -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.identifier")) { -// ok = f.getDefinition().length() > b.getDefinition().length(); -// if (ok) { -// f.setDefinition(null); -// b.setDefinition(null); -// } -// } -// ok = ok && Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation documentation append failed"); -// } else -// System.out.println("Snap shot generation documentation append test passed"); -// } -// -// -// /** -// * check that narrowing types is working -// * this one doesn't rename the path -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ -// private void textTypeNarrowing1() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.deceased[x]"); -// id.addType().setCode("dateTime"); -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size(); -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.deceasedDateTime")) { -// ok = f.getType().size() == 1 && f.getType().get(0).getCode().equals("dateTime"); -// if (ok) { -// f.getType().clear(); -// b.getType().clear(); -// f.setPath(b.getPath()); -// } -// } -// ok = ok && Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation narrow type 1 failed"); -// } else -// System.out.println("Snap shot generation narrow type 1 test passed"); -// } -// -// /** -// * check that narrowing types is working -// * this one renames the path -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ -// private void textTypeNarrowing2() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.deceasedDateTime"); -// id.addType().setCode("dateTime"); -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size(); -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.deceasedDateTime")) { -// ok = f.getType().size() == 1 && f.getType().get(0).getCode().equals("dateTime"); -// if (ok) { -// f.getType().clear(); -// b.getType().clear(); -// f.setPath(b.getPath()); -// } -// } -// ok = ok && Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation narrow type 2 failed"); -// } else -// System.out.println("Snap shot generation narrow type 2 test passed"); -// } -// -// /** -// * check that mapping resolution is working -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ -// private void testMapping() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier"); -// id.addMapping().setIdentity("rim").setMap("test"); -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size(); -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.identifier")) { -// ok = f.getMapping().size() > b.getMapping().size(); -// if (ok) { -// f.getMapping().clear(); -// b.getMapping().clear(); -// } -// } -// ok = ok && Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation mapping changes failed"); -// } else -// System.out.println("Snap shot generation mapping changes test passed"); -// } -// -// /** -// * Walking into a type -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ -// private void testTypeWalk() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier"); -// id.setMustSupport(true); -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier.system"); -// id.setMustSupport(true); -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// // the derived should be 8 longer -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size() - 8; -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i <= 9 ? i : i + 8); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.identifier")) { -// ok = f.getMustSupport() && !b.getMustSupport(); -// if (ok) { -// f.setMustSupportElement(null); -// } -// } -// ok = Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation simple test failed"); -// } else -// System.out.println("Snap shot generation simple test passed"); -// } -// -// /** -// * Walking into a type, without explicitly doing so -// * -// * note: this currently fails. -// * -// * @param context2 -// * @ -// * @throws EOperationOutcome -// */ -// private void testTypeWalk2() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier.system"); -// id.setMustSupport(true); -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// // the derived should be 8 longer -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size() - 8; -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i <= 9 ? i : i + 8); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.identifier")) { -// ok = f.getMustSupport() && !b.getMustSupport(); -// if (ok) { -// f.setMustSupportElement(null); -// } -// } -// ok = Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation simple test failed"); -// } else -// System.out.println("Snap shot generation simple test passed"); -// } -// -// -// /** -// * we're going to slice Patient.identifier -// */ -// private void testSlicingSimple() throws EOperationOutcome, Exception { -// -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// -// // set the slice up -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier"); -// id.getSlicing().setOrdered(false).setRules(SlicingRules.OPEN).addDiscriminator().setPath("use").setType(DiscriminatorType.VALUE); -// -// // first slice: -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier"); -// id.setSliceName("name1"); -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier.use"); -// id.setFixed(new CodeType("usual")); -// -// // second slice: -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier"); -// id.setSliceName("name2"); -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.identifier.use"); -// id.setFixed(new CodeType("official")); -// -// -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// // 18 different: identifier + 8 inner children * 2 -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size() - 18; -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i <= 9 ? i : i + 18); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.identifier")) { -// ok = f.hasSlicing(); -// if (ok) -// f.setSlicing(null); -// } -// ok = Base.compareDeep(b, f, true); -// } -// } -// } -// // now, check that the slices we skipped are correct: -// for (int i = 10; i <= 18; i++) { -// if (ok) { -// ElementDefinition d1 = focus.getSnapshot().getElement().get(i); -// ElementDefinition d2 = focus.getSnapshot().getElement().get(i+9); -// if (d1.getPath().equals("Patient.identifier.use")) { -// ok = d1.hasFixed() && d2.hasFixed() && !Base.compareDeep(d1.getFixed(), d2.getFixed(), true); -// if (ok) { -// d1.setFixed(null); -// d2.setFixed(null); -// } -// } -// if (d1.getPath().equals("Patient.identifier")) { -// ok = d1.hasSliceName() && d2.hasSliceName() && !Base.compareDeep(d1.getSliceNameElement(), d2.getSliceNameElement(), true); -// if (ok) { -// d1.setSliceName(null); -// d2.setSliceName(null); -// } -// } -// ok = Base.compareDeep(d1, d2, true); -// } -// } -// // for throughness, we could check against identifier too, but this is not done now. -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation slicing failed"); -// } else -// System.out.println("Snap shot generation slicing passed"); -// -// } -// -// /** -// * we're going to slice Patient.extension and refer to extension by profile -// * -// * implicit: whether to rely on implicit extension slicing -// */ -// private void testSlicingExtension(boolean implicit) throws EOperationOutcome, Exception { -// -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// -// // set the slice up -// ElementDefinition id; -// if (!implicit) { -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension"); -// id.getSlicing().setOrdered(false).setRules(SlicingRules.OPEN).addDiscriminator().setPath("url").setType(DiscriminatorType.VALUE); -// id.setMax("3"); -// } -// // first slice: -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension"); -// id.setSliceName("name1"); -// id.addType().setCode("Extension").setProfile("http://hl7.org/fhir/StructureDefinition/patient-birthTime"); -// id.setMin(1); -// -// // second slice: -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension"); -// id.setSliceName("name2"); -// id.addType().setCode("Extension").setProfile("http://hl7.org/fhir/StructureDefinition/patient-mothersMaidenName"); -// -// List messages = new ArrayList(); -// ProfileUtilities pu = new ProfileUtilities(context, messages, null); -// pu.generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// // 2 different: extension slices -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size() - 2; -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i <= 7 ? i : i + 2); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.extension")) { -// ok = f.hasSlicing() && (implicit || f.getMax().equals("3")); -// if (ok) { -// f.setSlicing(null); -// f.setMaxElement(b.getMaxElement()); -// } -// } -// if (!f.getPath().equals("Patient.extension")) // no compare that because the definitions get overwritten -// ok = Base.compareDeep(b, f, true); -// } -// } -// } -// // now, check that the slices we skipped are correct: -// if (ok) { -// ElementDefinition d1 = focus.getSnapshot().getElement().get(8); -// ElementDefinition d2 = focus.getSnapshot().getElement().get(9); -// ok = d1.hasType() && d1.getType().get(0).hasProfile() && d2.hasType() && d2.getType().get(0).hasProfile() && !Base.compareDeep(d1.getType(), d2.getType(), true) && -// d1.getMin() == 1 && d2.getMin() == 0 && d1.getMax().equals("1") && d2.getMax().equals("1"); -// if (ok) { -// d1.getType().clear(); -// d2.getType().clear(); -// d1.setSliceName("x"); -// d2.setSliceName("x"); -// d1.setMin(0); -// } -// ok = Base.compareDeep(d1, d2, true); -// // for throughness, we could check against extension too, but this is not done now. -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation slicing extensions simple ("+(implicit ? "implicit" : "not implicit")+") failed"); -// } else -// System.out.println("Snap shot generation slicing extensions simple ("+(implicit ? "implicit" : "not implicit")+") passed"); -// } -// -// /** -// * we're going to slice Patient.extension and refer to extension by profile. one of the extensions is complex, and we're going to walk into -// * it and make it must support -// * -// * implicit: whether to rely on implicit extension slicing -// */ -// private void testSlicingExtensionComplex(boolean implicit) throws EOperationOutcome, Exception { -// -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Patient").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// -// // set the slice up -// ElementDefinition id; -// if (!implicit) { -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension"); -// id.getSlicing().setOrdered(false).setRules(SlicingRules.OPEN).addDiscriminator().setPath("url").setType(DiscriminatorType.VALUE); -// } -// // first slice - a simple one to get us going: -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension"); -// id.setSliceName("simple"); -// id.addType().setCode("Extension").setProfile("http://hl7.org/fhir/StructureDefinition/patient-birthTime"); -// -// // second slice - the complex one -// // we walk into this and fix properties on the inner extensions -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension"); -// id.setSliceName("complex"); -// id.addType().setCode("Extension").setProfile("http://hl7.org/fhir/StructureDefinition/patient-nationality"); -// if (!implicit) { -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension.extension"); -// id.getSlicing().setOrdered(false).setRules(SlicingRules.OPEN).addDiscriminator().setPath("url").setType(DiscriminatorType.VALUE); -// } -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension.extension"); -// id.setSliceName("code"); -// id.setMustSupport(true); -// id.addType().setCode("Extension").setProfile("http://hl7.org/fhir/StructureDefinition/patient-nationality#code"); -// -// id = focus.getDifferential().addElement(); -// id.setPath("Patient.extension.extension"); -// id.setSliceName("period"); -// id.addType().setCode("Extension").setProfile("http://hl7.org/fhir/StructureDefinition/patient-nationality#period"); -// id.setMax("0"); // prohibit this one.... -// -// List messages = new ArrayList(); -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// // ok, there's going to 1 (simple) + complex: 1 + id + extnesion.slice + extension.code + (4 inside from that) + extension.period + (4 inside from that) + value + url = 16 -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size() - 16; -// -// // custom checks -// ok = ok && rule(focus.getSnapshot().getElement().get(7).getPath().equals("Patient.extension"), "element 7 (base) path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(7).hasSlicing(), "element 7 slicing"); -// ok = ok && rule(focus.getSnapshot().getElement().get(8).getPath().equals("Patient.extension"), "element 8 (1st slice) path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(8).getSliceName().equals("simple"), "element 8 (1st slice) name"); -// ok = ok && rule(focus.getSnapshot().getElement().get(8).getType().get(0).getProfile().equals("http://hl7.org/fhir/StructureDefinition/patient-birthTime"), "element 9 (2nd slice) profile name"); -// ok = ok && rule(focus.getSnapshot().getElement().get(9).getPath().equals("Patient.extension"), "element 9 (2nd slice) path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(9).getSliceName().equals("complex"), "element 8 (1st slice) name"); -// ok = ok && rule(focus.getSnapshot().getElement().get(9).getType().get(0).getProfile().equals("http://hl7.org/fhir/StructureDefinition/patient-nationality"), "element 9 (2nd slice) profile name"); -// ok = ok && rule(focus.getSnapshot().getElement().get(10).getPath().equals("Patient.extension.id"), "element 10 (2nd slice).id path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(11).getPath().equals("Patient.extension.extension"), "element 11 (2nd slice).extension path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(12).getPath().equals("Patient.extension.extension"), "element 12 (2nd slice).extension path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(12).getMustSupport(), "element 12 (2nd slice).extension must support"); -// ok = ok && rule(focus.getSnapshot().getElement().get(13).getPath().equals("Patient.extension.extension.id"), "element 13 (2nd slice).extension.id path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(14).getPath().equals("Patient.extension.extension.extension"), "element 14 (2nd slice).extension.extension path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(15).getPath().equals("Patient.extension.extension.url"), "element 15 (2nd slice).extension.url path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(16).getPath().equals("Patient.extension.extension.valueCodeableConcept"), "element 16 (2nd slice).extension.valueCodeableConcept path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(17).getPath().equals("Patient.extension.extension"), "element 17 (2nd slice).extension path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(17).getMax().equals("0"), "element 17 (2nd slice).extension cardinality"); -// ok = ok && rule(focus.getSnapshot().getElement().get(18).getPath().equals("Patient.extension.extension.id"), "element 18 (2nd slice).extension.id path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(19).getPath().equals("Patient.extension.extension.extension"), "element 19 (2nd slice).extension.extension path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(20).getPath().equals("Patient.extension.extension.url"), "element 20 (2nd slice).extension.url path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(21).getPath().equals("Patient.extension.extension.valuePeriod"), "element 21 (2nd slice).extension.valuePeriod path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(22).getPath().equals("Patient.extension.url"), "element 22 (2nd slice).url path"); -// ok = ok && rule(focus.getSnapshot().getElement().get(23).getPath().equals("Patient.extension.value[x]"), "element 23 (2nd slice).url path"); -// -// for (int i = 0; i < base.getSnapshot().getElement().size(); i++) { -// if (ok) { -// ElementDefinition b = base.getSnapshot().getElement().get(i); -// ElementDefinition f = focus.getSnapshot().getElement().get(i <= 7 ? i : i + 16); -// if (!f.hasBase() || !b.getPath().equals(f.getBase().getPath())) -// ok = false; -// else { -// f.setBase(null); -// if (f.getPath().equals("Patient.extension")) { -// ok = f.hasSlicing(); -// if (ok) -// f.setSlicing(null); -// } -// if (!f.getPath().equals("Patient.extension")) // no compare that because the definitions get overwritten -// ok = Base.compareDeep(b, f, true); -// } -// } -// } -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation slicing extensions complex ("+(implicit ? "implicit" : "not implicit")+") failed"); -// } else -// System.out.println("Snap shot generation slicing extensions complex ("+(implicit ? "implicit" : "not implicit")+") passed"); -// } -// -// private void testSlicingTask8742() throws EOperationOutcome, Exception { -// StructureDefinition focus = new StructureDefinition(); -// StructureDefinition base = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/Organization").copy(); -// focus.setUrl(Utilities.makeUuidUrn()); -// focus.setBaseDefinition(base.getUrl()); -// focus.setType(base.getType()); -// focus.setDerivation(TypeDerivationRule.CONSTRAINT); -// -// ElementDefinition id = focus.getDifferential().addElement(); -// id.setPath("Organization.address"); -// id.setMin(1); -// id.setMax("1"); -// id.setMustSupport(true); -// -// id = focus.getDifferential().addElement(); -// id.setPath("Organization.address.extension"); -// id.setSliceName("USLabCountycodes"); -// id.getSlicing().setOrdered(false).setRules(SlicingRules.OPEN).addDiscriminator().setPath("url").setType(DiscriminatorType.VALUE); -// id.setShort("County/Parish FIPS codes"); -// id.setDefinition("County/Parish FIPS codes."); -// id.setRequirements("County/Parish Code SHALL use FIPS 6-4 ( INCITS 31:2009)."); -// id.setMin(0); -// id.setMax("1"); -// id.addType().setCode("Extension").setProfile("http://hl7.org/fhir/StructureDefinition/us-core-county"); -// id.setMustSupport(true); -// id.getBinding().setStrength(BindingStrength.REQUIRED).setDescription("FIPS codes for US counties and county equivalent entities.").setValueSet(new Reference().setReference("http://hl7.org/fhir/ValueSet/fips-county")); -// List messages = new ArrayList(); -// -// new ProfileUtilities(context, messages, null).generateSnapshot(base, focus, focus.getUrl(), "Simple Test" ); -// -// // 14 for address with one sliced extension -// boolean ok = base.getSnapshot().getElement().size() == focus.getSnapshot().getElement().size() - 13; -// -// if (!ok) { -// compareXml(base, focus); -// throw new FHIRException("Snap shot generation test 8742 failed"); -// } else -// System.out.println("Snap shot generation test 8742 passed"); -// } -// -// -// private boolean rule(boolean ok, String message) { -// if (!ok) -// System.out.println("Test failed: " + message); -// return ok; -// } -// - - private void compareXml(StructureDefinition base, StructureDefinition focus) throws FileNotFoundException, IOException { - base.setText(null); - focus.setText(null); - base.setDifferential(null); -// focus.setDifferential(null); - String f1 = Utilities.path("c:", "temp", "base.xml"); - String f2 = Utilities.path("c:", "temp", "derived.xml"); - new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f1), base);; - new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f2), focus);; - String diff = Utilities.path(System.getenv("ProgramFiles(X86)"), "WinMerge", "WinMergeU.exe"); - List command = new ArrayList(); - command.add("\"" + diff + "\" \"" + f1 + "\" \"" + f2 + "\""); - - ProcessBuilder builder = new ProcessBuilder(command); - builder.directory(new CSFile("c:\\temp")); - builder.start(); - } - - - -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ResourceRoundTripTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ResourceRoundTripTests.java deleted file mode 100644 index 980022e7fa2..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ResourceRoundTripTests.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.hl7.fhir.r4.test; - -import static org.junit.Assert.*; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.hl7.fhir.r4.context.IWorkerContext; -import org.hl7.fhir.r4.context.SimpleWorkerContext; -import org.hl7.fhir.r4.formats.IParser.OutputStyle; -import org.hl7.fhir.r4.formats.XmlParser; -import org.hl7.fhir.r4.model.DomainResource; -import org.hl7.fhir.r4.model.Resource; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.r4.utils.EOperationOutcome; -import org.hl7.fhir.r4.utils.NarrativeGenerator; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.exceptions.FHIRException; -import org.junit.Before; -import org.junit.Test; - -public class ResourceRoundTripTests { - - @Before - public void setUp() throws Exception { - } - - @Test - public void test() throws FileNotFoundException, IOException, FHIRException, EOperationOutcome { - if (TestingUtilities.context == null) - TestingUtilities.context = SimpleWorkerContext.fromPack(Utilities.path(TestingUtilities.home(), "publish", "definitions.xml.zip")); - Resource res = new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "tests", "resources", "unicode.xml"))); - new NarrativeGenerator("", "", TestingUtilities.context).generate((DomainResource) res); - new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(TestingUtilities.home(), "tests", "resources","unicode.out.xml")), res); - } - -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ShexGeneratorTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ShexGeneratorTests.java deleted file mode 100644 index fe7fbca31ee..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/ShexGeneratorTests.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.hl7.fhir.r4.test; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Path; - -import org.hl7.fhir.r4.conformance.ShExGenerator; -import org.hl7.fhir.r4.conformance.ShExGenerator.HTMLLinkPolicy; -import org.hl7.fhir.r4.context.SimpleWorkerContext; -import org.hl7.fhir.r4.model.StructureDefinition; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.utilities.TextFile; -import org.junit.Test; - -public class ShexGeneratorTests { - - private void doTest(String name) throws FileNotFoundException, IOException, FHIRException { - String workingDirectory = "C:\\work\\org.hl7.fhir\\build\\publish"; // FileSystems.getDefault().getPath(System.getProperty("user.dir"), "data").toString(); - // String workingDirectory = FileSystems.getDefault().getPath(System.getProperty("user.dir"), "..", "..", "..", "publish").toString(); - if (TestingUtilities.context == null) { - // For the time being, put the validation entry in org/hl7/fhir/r4/data - Path path = FileSystems.getDefault().getPath(workingDirectory, "definitions.xml.zip"); - TestingUtilities.context = SimpleWorkerContext.fromPack(path.toString()); - } - StructureDefinition sd = TestingUtilities.context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+name); - if(sd == null) { - throw new FHIRException("StructuredDefinition for " + name + "was null"); - } - Path outPath = FileSystems.getDefault().getPath(workingDirectory, name.toLowerCase()+".shex"); - TextFile.stringToFile(new ShExGenerator(TestingUtilities.context).generate(HTMLLinkPolicy.NONE, sd), outPath.toString()); - } - - @Test - public void testId() throws FHIRException, IOException { - doTest("id"); - } - - @Test - public void testUri() throws FHIRException, IOException { - doTest("uri"); - } - - - @Test - public void testObservation() throws FHIRException, IOException { - doTest("Observation"); - } - - @Test - public void testRef() throws FHIRException, IOException { - doTest("Reference"); - } - - @Test - public void testAccount() throws FHIRException, IOException { - doTest("Account"); - } - - @Test - public void testMedicationOrder() throws FHIRException, IOException { - doTest("MedicationOrder"); - } - - @Test - public void testAllergyIntolerance() throws FHIRException, IOException { - doTest("AllergyIntolerance"); - } - - @Test - public void testCoding() throws FHIRException, IOException { - doTest("Coding"); - } - - @Test - public void testTiming() throws FHIRException, IOException { - doTest("Timing"); - } - - @Test - public void testSignature() throws FHIRException, IOException { - doTest("Signature"); - } -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java deleted file mode 100644 index ce48cca0090..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java +++ /dev/null @@ -1,338 +0,0 @@ -package org.hl7.fhir.r4.test; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.xml.parsers.ParserConfigurationException; - -import org.hl7.fhir.r4.conformance.ProfileUtilities; -import org.hl7.fhir.r4.context.SimpleWorkerContext; -import org.hl7.fhir.r4.formats.IParser.OutputStyle; -import org.hl7.fhir.r4.formats.XmlParser; -import org.hl7.fhir.r4.model.Base; -import org.hl7.fhir.r4.model.BooleanType; -import org.hl7.fhir.r4.model.Coding; -import org.hl7.fhir.r4.model.ExpressionNode; -import org.hl7.fhir.r4.model.MetadataResource; -import org.hl7.fhir.r4.model.ExpressionNode.CollectionStatus; -import org.hl7.fhir.r4.model.PrimitiveType; -import org.hl7.fhir.r4.model.Resource; -import org.hl7.fhir.r4.model.StructureDefinition; -import org.hl7.fhir.r4.model.TestScript; -import org.hl7.fhir.r4.model.TestScript.SetupActionAssertComponent; -import org.hl7.fhir.r4.model.TestScript.SetupActionComponent; -import org.hl7.fhir.r4.model.TestScript.SetupActionOperationComponent; -import org.hl7.fhir.r4.model.TestScript.TestActionComponent; -import org.hl7.fhir.r4.model.TestScript.TestScriptFixtureComponent; -import org.hl7.fhir.r4.model.TestScript.TestScriptTestComponent; -import org.hl7.fhir.r4.model.TypeDetails; -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.r4.utils.CodingUtilities; -import org.hl7.fhir.r4.utils.FHIRPathEngine; -import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.exceptions.DefinitionException; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.exceptions.FHIRFormatError; -import org.hl7.fhir.exceptions.PathEngineException; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.xml.XMLUtil; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import junit.framework.Assert; - -@RunWith(Parameterized.class) -public class SnapShotGenerationTests { - - private static class SnapShotGenerationTestsContext implements IEvaluationContext { - private Map fixtures; - private Map snapshots = new HashMap(); - public TestScript tests; - - public void checkTestsDetails() { - if (!"http://hl7.org/fhir/tests/snapshotgeneration".equals(tests.getUrl())) - throw new Error("Wrong URL on test script"); - if (!tests.getSetup().isEmpty()) - throw new Error("Setup is not supported"); - if (!tests.getTeardown().isEmpty()) - throw new Error("Teardown is not supported"); - Set ids = new HashSet(); - Set urls = new HashSet(); - for (Resource r : tests.getContained()) { - if (ids.contains(r.getId())) - throw new Error("Unsupported: duplicate contained resource on fixture id "+r.getId()); - ids.add(r.getId()); - if (r instanceof MetadataResource) { - MetadataResource md = (MetadataResource) r; - if (urls.contains(md.getUrl())) - throw new Error("Unsupported: duplicate canonical url "+md.getUrl()+" on fixture id "+r.getId()); - urls.add(md.getUrl()); - } - } - for (TestScriptFixtureComponent r : tests.getFixture()) { - if (ids.contains(r.getId())) - throw new Error("Unsupported: duplicate contained resource or fixture id "+r.getId()); - ids.add(r.getId()); - } - Set names = new HashSet(); - for (TestScriptTestComponent test : tests.getTest()) { - if (names.contains(test.getName())) - throw new Error("Unsupported: duplicate name "+test.getName()); - names.add(test.getName()); - if (test.getAction().size() < 2) - throw new Error("Unsupported: multiple actions required"); - if (!test.getActionFirstRep().hasOperation()) - throw new Error("Unsupported: first action must be an operation"); - for (int i = 0; i < test.getAction().size(); i++) { -// if (!test.getAction().get(i).hasAssert()) -// throw new Error("Unsupported: following actions must be an asserts"); - TestActionComponent action = test.getAction().get(i); - if (action.hasOperation()) { - SetupActionOperationComponent op = test.getActionFirstRep().getOperation(); - if (!CodingUtilities.matches(op.getType(), "http://hl7.org/fhir/testscript-operation-codes", "snapshot") - && !CodingUtilities.matches(op.getType(), "http://hl7.org/fhir/testscript-operation-codes", "sortDifferential")) - throw new Error("Unsupported action operation type "+CodingUtilities.present(op.getType())); - if (!"StructureDefinition".equals(op.getResource())) - throw new Error("Unsupported action operation resource "+op.getResource()); - if (!op.hasResponseId()) - throw new Error("Unsupported action operation: no response id"); - if (!op.hasSourceId()) - throw new Error("Unsupported action operation: no source id"); - if (!hasSource(op.getSourceId())) - throw new Error("Unsupported action operation: source id could not be resolved"); - } else if (action.hasAssert()) { - SetupActionAssertComponent a = action.getAssert(); - if (!a.hasLabel()) - throw new Error("Unsupported: actions must have a label"); - if (!a.hasDescription()) - throw new Error("Unsupported: actions must have a description"); - if (!a.hasExpression()) - throw new Error("Unsupported: actions must have an expression"); - } else { - throw new Error("Unsupported: Unrecognized action type"); - } - } - } - } - - private boolean hasSource(String sourceId) { - for (TestScriptFixtureComponent ds : tests.getFixture()) { - if (sourceId.equals(ds.getId())) - return true; - } - for (Resource r : tests.getContained()) { - if (sourceId.equals(r.getId())) - return true; - } - return false; - } - - public Resource fetchFixture(String id) { - if (fixtures.containsKey(id)) - return fixtures.get(id); - - for (TestScriptFixtureComponent ds : tests.getFixture()) { - if (id.equals(ds.getId())) - throw new Error("not done yet"); - } - for (Resource r : tests.getContained()) { - if (id.equals(r.getId())) - return r; - } - return null; - } - - // FHIRPath methods - @Override - public Base resolveConstant(Object appContext, String name) throws PathEngineException { - return null; - } - - @Override - public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException { - return null; - } - - @Override - public boolean log(String argument, List focus) { - System.out.println(argument+": "+fp.convertToString(focus)); - return true; - } - - @Override - public FunctionDetails resolveFunction(String functionName) { - if ("fixture".equals(functionName)) - return new FunctionDetails("Access a fixture defined in the testing context", 0, 1); - return null; - } - - @Override - public TypeDetails checkFunction(Object appContext, String functionName, List parameters) throws PathEngineException { - if ("fixture".equals(functionName)) - return new TypeDetails(CollectionStatus.SINGLETON, TestingUtilities.context.getResourceNamesAsSet()); - return null; - } - - @Override - public List executeFunction(Object appContext, String functionName, List> parameters) { - if ("fixture".equals(functionName)) { - String id = fp.convertToString(parameters.get(0)); - Resource res = fetchFixture(id); - if (res != null) { - List list = new ArrayList(); - list.add(res); - return list; - } - } - return null; - } - - @Override - public Base resolveReference(Object appContext, String url) { - // TODO Auto-generated method stub - return null; - } - - } - - - private static FHIRPathEngine fp; - - @Parameters(name = "{index}: file {0}") - public static Iterable data() throws ParserConfigurationException, IOException, FHIRFormatError { - SnapShotGenerationTestsContext context = new SnapShotGenerationTestsContext(); - context.tests = (TestScript) new XmlParser().parse(new FileInputStream(Utilities.path(TestingUtilities.home(), "tests", "resources", "snapshot-generation-tests.xml"))); - - context.checkTestsDetails(); - - List objects = new ArrayList(context.tests.getTest().size()); - - for (TestScriptTestComponent e : context.tests.getTest()) { - objects.add(new Object[] { e.getName(), e, context }); - } - return objects; - } - - - private final TestScriptTestComponent test; - private final String name; - private SnapShotGenerationTestsContext context; - - public SnapShotGenerationTests(String name, TestScriptTestComponent e, SnapShotGenerationTestsContext context) { - this.name = name; - this.test = e; - this.context = context; - } - - @SuppressWarnings("deprecation") - @Test - public void test() throws FileNotFoundException, IOException, FHIRException, org.hl7.fhir.exceptions.FHIRException { - if (TestingUtilities.context == null) - TestingUtilities.context = SimpleWorkerContext.fromPack(Utilities.path(TestingUtilities.home(), "publish", "definitions.xml.zip")); - if (fp == null) - fp = new FHIRPathEngine(TestingUtilities.context); - fp.setHostServices(context); - - resolveFixtures(); - - for (int i = 0; i < test.getAction().size(); i++) { - TestActionComponent action = test.getAction().get(i); - if (action.hasOperation()) { - SetupActionOperationComponent op = action.getOperation(); - Coding opType = op.getType(); - if (opType.getSystem().equals("http://hl7.org/fhir/testscript-operation-codes") && opType.getCode().equals("snapshot")) { - StructureDefinition source = (StructureDefinition) context.fetchFixture(op.getSourceId()); - StructureDefinition base = getSD(source.getBaseDefinition()); - StructureDefinition output = source.copy(); - ProfileUtilities pu = new ProfileUtilities(TestingUtilities.context, null, null); - pu.setIds(source, false); - if ("sort=true".equals(op.getParams())) { - List errors = new ArrayList(); - pu.sortDifferential(base, output, source.getName(), errors); - if (errors.size() > 0) - throw new FHIRException("Sort failed: "+errors.toString()); - } - pu.generateSnapshot(base, output, source.getUrl(), source.getName()); - context.fixtures.put(op.getResponseId(), output); - context.snapshots.put(output.getUrl(), output); - - new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(System.getProperty("java.io.tmpdir"), op.getResponseId()+".xml")), output); - - } else if (opType.getSystem().equals("http://hl7.org/fhir/testscript-operation-codes") && opType.getCode().equals("sortDifferential")) { - StructureDefinition source = (StructureDefinition) context.fetchFixture(op.getSourceId()); - StructureDefinition base = getSD(source.getBaseDefinition()); - StructureDefinition output = source.copy(); - ProfileUtilities pu = new ProfileUtilities(TestingUtilities.context, null, null); - pu.setIds(source, false); - List errors = new ArrayList(); - pu.sortDifferential(base, output, output.getUrl(), errors); - if (!errors.isEmpty()) - throw new FHIRException(errors.get(0)); - context.fixtures.put(op.getResponseId(), output); - context.snapshots.put(output.getUrl(), output); - - new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(System.getProperty("java.io.tmpdir"), op.getResponseId()+".xml")), output); - - } else { - throw new Error("Unsupported operation: " + opType.getSystem() + " : " + opType.getCode()); - } - } else if (action.hasAssert()) { - SetupActionAssertComponent a = action.getAssert(); - Assert.assertTrue(a.getLabel()+": "+a.getDescription(), fp.evaluateToBoolean(new StructureDefinition(), new StructureDefinition(), a.getExpression())); - } - } - } - - - private StructureDefinition getSD(String url) throws DefinitionException, FHIRException { - StructureDefinition sd = TestingUtilities.context.fetchResource(StructureDefinition.class, url); - if (sd == null) - sd = context.snapshots.get(url); - if (sd == null) - sd = findContainedProfile(url); - return sd; - } - - private StructureDefinition findContainedProfile(String url) throws DefinitionException, FHIRException { - for (Resource r : context.tests.getContained()) { - if (r instanceof StructureDefinition) { - StructureDefinition sd = (StructureDefinition) r; - if (sd.getUrl().equals(url)) { - StructureDefinition p = sd.copy(); - ProfileUtilities pu = new ProfileUtilities(TestingUtilities.context, null, null); - pu.setIds(p, false); - List errors = new ArrayList(); - pu.sortDifferential(getSD(p.getBaseDefinition()), p, url, errors); - if (!errors.isEmpty()) - throw new FHIRException(errors.get(0)); - pu.generateSnapshot(getSD(p.getBaseDefinition()), p, p.getUrl(), p.getName()); - return p; - } - } - } - return null; - } - - private void resolveFixtures() { - if (context.fixtures == null) { - context.fixtures = new HashMap(); - for (TestScriptFixtureComponent fd : context.tests.getFixture()) { - Resource r = TestingUtilities.context.fetchResource(Resource.class, fd.getResource().getReference()); - context.fixtures.put(fd.getId(), r); - } - } - - } -} diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/TurtleTests.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/TurtleTests.java deleted file mode 100644 index 88b99ac074c..00000000000 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/test/TurtleTests.java +++ /dev/null @@ -1,3552 +0,0 @@ -package org.hl7.fhir.r4.test; - -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.hl7.fhir.r4.test.support.TestingUtilities; -import org.hl7.fhir.r4.utils.formats.Turtle; -import org.hl7.fhir.utilities.TextFile; -import org.hl7.fhir.utilities.Utilities; -import org.junit.Test; - -import junit.framework.Assert; - -public class TurtleTests { - - - - private void doTest(String filename, boolean ok) throws Exception { - try { - String s = TextFile.fileToString(filename); - Turtle ttl = new Turtle(); - ttl.parse(s); - Assert.assertTrue(ok); - } catch (Exception e) { - Assert.assertTrue(e.getMessage(), !ok); - } - } - - @Test - public void test_double_lower_case_e1() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "double_lower_case_e.nt"), true); - } - @Test - public void test_double_lower_case_e2() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "double_lower_case_e.ttl"), true); - } - @Test - public void test_empty_collection1() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "empty_collection.nt"), true); - } - @Test - public void test_empty_collection2() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "empty_collection.ttl"), true); - } - @Test - public void test_first1() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "first.nt"), true); - } -// @Test -// public void test_first2() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "first.ttl"), true); -// } -// @Test - public void test_HYPHEN_MINUS_in_localNameNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "HYPHEN_MINUS_in_localName.nt"), true); - } - @Test - public void test_HYPHEN_MINUS_in_localName() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "HYPHEN_MINUS_in_localName.ttl"), true); - } - @Test - public void test_IRI_spoNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRI_spo.nt"), true); - } - @Test - public void test_IRI_subject() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRI_subject.ttl"), true); - } - @Test - public void test_IRI_with_all_punctuationNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRI_with_all_punctuation.nt"), true); - } - @Test - public void test_IRI_with_all_punctuation() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRI_with_all_punctuation.ttl"), true); - } - @Test - public void test_IRI_with_eight_digit_numeric_escape() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRI_with_eight_digit_numeric_escape.ttl"), true); - } - @Test - public void test_IRI_with_four_digit_numeric_escape() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRI_with_four_digit_numeric_escape.ttl"), true); - } - @Test - public void test_IRIREF_datatypeNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRIREF_datatype.nt"), true); - } - @Test - public void test_IRIREF_datatype() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "IRIREF_datatype.ttl"), true); - } - @Test - public void test_labeled_blank_node_objectNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_object.nt"), true); - } - @Test - public void test_labeled_blank_node_object() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_object.ttl"), true); - } - @Test - public void test_labeled_blank_node_subjectNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_subject.nt"), true); - } - @Test - public void test_labeled_blank_node_subject() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_subject.ttl"), true); - } - @Test - public void test_labeled_blank_node_with_leading_digit() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_with_leading_digit.ttl"), true); - } - @Test - public void test_labeled_blank_node_with_leading_underscore() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_with_leading_underscore.ttl"), true); - } - @Test - public void test_labeled_blank_node_with_non_leading_extras() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_with_non_leading_extras.ttl"), true); - } - @Test - public void test_labeled_blank_node_with_PN_CHARS_BASE_character_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "labeled_blank_node_with_PN_CHARS_BASE_character_boundaries.ttl"), false); - } - @Test - public void test_langtagged_LONG() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "langtagged_LONG.ttl"), true); - } - @Test - public void test_langtagged_LONG_with_subtagNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "langtagged_LONG_with_subtag.nt"), true); - } - @Test - public void test_langtagged_LONG_with_subtag() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "langtagged_LONG_with_subtag.ttl"), true); - } - @Test - public void test_langtagged_non_LONGNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "langtagged_non_LONG.nt"), true); - } - @Test - public void test_langtagged_non_LONG() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "langtagged_non_LONG.ttl"), true); - } - @Test - public void test_lantag_with_subtagNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "lantag_with_subtag.nt"), true); - } - @Test - public void test_lantag_with_subtag() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "lantag_with_subtag.ttl"), true); - } - @Test - public void test_lastNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "last.nt"), true); - } - @Test - public void test_last() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "last.ttl"), false); - } - @Test - public void test_literal_falseNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_false.nt"), true); - } - @Test - public void test_literal_false() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_false.ttl"), true); - } - @Test - public void test_LITERAL_LONG1() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1.ttl"), true); - } - @Test - public void test_LITERAL_LONG1_ascii_boundariesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1_ascii_boundaries.nt"), false); - } - @Test - public void test_LITERAL_LONG1_ascii_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1_ascii_boundaries.ttl"), true); - } - @Test - public void test_LITERAL_LONG1_with_1_squoteNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1_with_1_squote.nt"), true); - } - @Test - public void test_LITERAL_LONG1_with_1_squote() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1_with_1_squote.ttl"), true); - } - @Test - public void test_LITERAL_LONG1_with_2_squotesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1_with_2_squotes.nt"), true); - } - @Test - public void test_LITERAL_LONG1_with_2_squotes() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1_with_2_squotes.ttl"), true); - } - @Test - public void test_LITERAL_LONG1_with_UTF8_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG1_with_UTF8_boundaries.ttl"), true); - } - @Test - public void test_LITERAL_LONG2() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2.ttl"), true); - } - @Test - public void test_LITERAL_LONG2_ascii_boundariesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_ascii_boundaries.nt"), false); - } - @Test - public void test_LITERAL_LONG2_ascii_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_ascii_boundaries.ttl"), true); - } - @Test - public void test_LITERAL_LONG2_with_1_squoteNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_with_1_squote.nt"), true); - } - @Test - public void test_LITERAL_LONG2_with_1_squote() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_with_1_squote.ttl"), true); - } - @Test - public void test_LITERAL_LONG2_with_2_squotesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_with_2_squotes.nt"), true); - } - @Test - public void test_LITERAL_LONG2_with_2_squotes() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_with_2_squotes.ttl"), true); - } - @Test - public void test_LITERAL_LONG2_with_REVERSE_SOLIDUSNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_with_REVERSE_SOLIDUS.nt"), false); - } - @Test - public void test_LITERAL_LONG2_with_REVERSE_SOLIDUS() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_with_REVERSE_SOLIDUS.ttl"), false); - } - @Test - public void test_LITERAL_LONG2_with_UTF8_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_LONG2_with_UTF8_boundaries.ttl"), true); - } - @Test - public void test_literal_trueNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_true.nt"), true); - } - @Test - public void test_literal_true() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_true.ttl"), true); - } - @Test - public void test_literal_with_BACKSPACENT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_BACKSPACE.nt"), false); - } - @Test - public void test_literal_with_BACKSPACE() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_BACKSPACE.ttl"), true); - } - @Test - public void test_literal_with_CARRIAGE_RETURNNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_CARRIAGE_RETURN.nt"), true); - } - @Test - public void test_literal_with_CARRIAGE_RETURN() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_CARRIAGE_RETURN.ttl"), true); - } - @Test - public void test_literal_with_CHARACTER_TABULATIONNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_CHARACTER_TABULATION.nt"), true); - } - @Test - public void test_literal_with_CHARACTER_TABULATION() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_CHARACTER_TABULATION.ttl"), true); - } - @Test - public void test_literal_with_escaped_BACKSPACE() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_escaped_BACKSPACE.ttl"), false); - } - @Test - public void test_literal_with_escaped_CARRIAGE_RETURN() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_escaped_CARRIAGE_RETURN.ttl"), true); - } - @Test - public void test_literal_with_escaped_CHARACTER_TABULATION() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_escaped_CHARACTER_TABULATION.ttl"), true); - } - @Test - public void test_literal_with_escaped_FORM_FEED() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_escaped_FORM_FEED.ttl"), true); - } - @Test - public void test_literal_with_escaped_LINE_FEED() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_escaped_LINE_FEED.ttl"), true); - } -// @Test -// public void test_literal_with_FORM_FEEDNT() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_FORM_FEED.nt"), true); -// } - @Test - public void test_literal_with_FORM_FEED() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_FORM_FEED.ttl"), true); - } - @Test - public void test_literal_with_LINE_FEEDNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_LINE_FEED.nt"), true); - } - @Test - public void test_literal_with_LINE_FEED() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_LINE_FEED.ttl"), true); - } - @Test - public void test_literal_with_numeric_escape4NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_numeric_escape4.nt"), true); - } - @Test - public void test_literal_with_numeric_escape4() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_numeric_escape4.ttl"), true); - } - @Test - public void test_literal_with_numeric_escape8() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_numeric_escape8.ttl"), true); - } - @Test - public void test_literal_with_REVERSE_SOLIDUSNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_REVERSE_SOLIDUS.nt"), false); - } - @Test - public void test_literal_with_REVERSE_SOLIDUS() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "literal_with_REVERSE_SOLIDUS.ttl"), true); - } - @Test - public void test_LITERAL_with_UTF8_boundariesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL_with_UTF8_boundaries.nt"), true); - } - @Test - public void test_LITERAL1NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1.nt"), true); - } - @Test - public void test_LITERAL1() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1.ttl"), true); - } - @Test - public void test_LITERAL1_all_controlsNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1_all_controls.nt"), false); - } - @Test - public void test_LITERAL1_all_controls() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1_all_controls.ttl"), true); - } - @Test - public void test_LITERAL1_all_punctuationNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1_all_punctuation.nt"), true); - } - @Test - public void test_LITERAL1_all_punctuation() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1_all_punctuation.ttl"), true); - } -// @Test -// public void test_LITERAL1_ascii_boundariesNT() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1_ascii_boundaries.nt"), true); -// } - @Test - public void test_LITERAL1_ascii_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1_ascii_boundaries.ttl"), true); - } - @Test - public void test_LITERAL1_with_UTF8_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL1_with_UTF8_boundaries.ttl"), true); - } - @Test - public void test_LITERAL2() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL2.ttl"), true); - } - @Test - public void test_LITERAL2_ascii_boundariesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL2_ascii_boundaries.nt"), false); - } - @Test - public void test_LITERAL2_ascii_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL2_ascii_boundaries.ttl"), true); - } - @Test - public void test_LITERAL2_with_UTF8_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "LITERAL2_with_UTF8_boundaries.ttl"), true); - } - @Test - public void test_localName_with_assigned_nfc_bmp_PN_CHARS_BASE_character_boundariesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_assigned_nfc_bmp_PN_CHARS_BASE_character_boundaries.nt"), true); - } - @Test - public void test_localName_with_assigned_nfc_bmp_PN_CHARS_BASE_character_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_assigned_nfc_bmp_PN_CHARS_BASE_character_boundaries.ttl"), true); - } - @Test - public void test_localName_with_assigned_nfc_PN_CHARS_BASE_character_boundariesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_assigned_nfc_PN_CHARS_BASE_character_boundaries.nt"), true); - } - @Test - public void test_localName_with_assigned_nfc_PN_CHARS_BASE_character_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_assigned_nfc_PN_CHARS_BASE_character_boundaries.ttl"), false); - } -// don't need to support property names with ':' -// @Test -// public void test_localname_with_COLONNT() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localname_with_COLON.nt"), true); -// } -// @Test -// public void test_localname_with_COLON() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localname_with_COLON.ttl"), true); -// } - @Test - public void test_localName_with_leading_digitNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_leading_digit.nt"), true); - } - @Test - public void test_localName_with_leading_digit() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_leading_digit.ttl"), true); - } - @Test - public void test_localName_with_leading_underscoreNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_leading_underscore.nt"), true); - } - @Test - public void test_localName_with_leading_underscore() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_leading_underscore.ttl"), true); - } - @Test - public void test_localName_with_nfc_PN_CHARS_BASE_character_boundariesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_nfc_PN_CHARS_BASE_character_boundaries.nt"), true); - } - @Test - public void test_localName_with_nfc_PN_CHARS_BASE_character_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_nfc_PN_CHARS_BASE_character_boundaries.ttl"), false); - } - @Test - public void test_localName_with_non_leading_extrasNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_non_leading_extras.nt"), true); - } - @Test - public void test_localName_with_non_leading_extras() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "localName_with_non_leading_extras.ttl"), true); - } - @Test - public void test_negative_numericNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "negative_numeric.nt"), true); - } - @Test - public void test_negative_numeric() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "negative_numeric.ttl"), true); - } - @Test - public void test_nested_blankNodePropertyListsNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "nested_blankNodePropertyLists.nt"), true); - } - @Test - public void test_nested_blankNodePropertyLists() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "nested_blankNodePropertyLists.ttl"), true); - } - @Test - public void test_nested_collectionNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "nested_collection.nt"), true); - } - @Test - public void test_nested_collection() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "nested_collection.ttl"), false); - } - @Test - public void test_number_sign_following_localNameNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "number_sign_following_localName.nt"), true); - } - @Test - public void test_number_sign_following_localName() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "number_sign_following_localName.ttl"), true); - } - @Test - public void test_number_sign_following_PNAME_NSNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "number_sign_following_PNAME_NS.nt"), true); - } -// @Test -// public void test_number_sign_following_PNAME_NS() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "number_sign_following_PNAME_NS.ttl"), true); -// } - @Test - public void test_numeric_with_leading_0NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "numeric_with_leading_0.nt"), true); - } - @Test - public void test_numeric_with_leading_0() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "numeric_with_leading_0.ttl"), true); - } - @Test - public void test_objectList_with_two_objectsNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "objectList_with_two_objects.nt"), true); - } - @Test - public void test_objectList_with_two_objects() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "objectList_with_two_objects.ttl"), true); - } - @Test - public void test_old_style_base() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "old_style_base.ttl"), true); - } - @Test - public void test_old_style_prefix() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "old_style_prefix.ttl"), true); - } - @Test - public void test_percent_escaped_localNameNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "percent_escaped_localName.nt"), true); - } -// @Test -// public void test_percent_escaped_localName() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "percent_escaped_localName.ttl"), true); -// } - @Test - public void test_positive_numericNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "positive_numeric.nt"), true); - } - @Test - public void test_positive_numeric() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "positive_numeric.ttl"), true); - } - @Test - public void test_predicateObjectList_with_two_objectListsNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "predicateObjectList_with_two_objectLists.nt"), true); - } - @Test - public void test_predicateObjectList_with_two_objectLists() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "predicateObjectList_with_two_objectLists.ttl"), true); - } -// @Test -// public void test_prefix_only_IRI() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefix_only_IRI.ttl"), true); -// } - @Test - public void test_prefix_reassigned_and_usedNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefix_reassigned_and_used.nt"), true); - } - @Test - public void test_prefix_reassigned_and_used() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefix_reassigned_and_used.ttl"), true); - } - @Test - public void test_prefix_with_non_leading_extras() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefix_with_non_leading_extras.ttl"), true); - } - @Test - public void test_prefix_with_PN_CHARS_BASE_character_boundaries() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefix_with_PN_CHARS_BASE_character_boundaries.ttl"), true); - } - @Test - public void test_prefixed_IRI_object() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefixed_IRI_object.ttl"), true); - } - @Test - public void test_prefixed_IRI_predicate() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefixed_IRI_predicate.ttl"), true); - } - @Test - public void test_prefixed_name_datatype() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "prefixed_name_datatype.ttl"), true); - } - @Test - public void test_repeated_semis_at_end() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "repeated_semis_at_end.ttl"), true); - } - @Test - public void test_repeated_semis_not_at_endNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "repeated_semis_not_at_end.nt"), true); - } - @Test - public void test_repeated_semis_not_at_end() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "repeated_semis_not_at_end.ttl"), true); - } - @Test - public void test_reserved_escaped_localNameNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "reserved_escaped_localName.nt"), true); - } -// @Test -// public void test_reserved_escaped_localName() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "reserved_escaped_localName.ttl"), true); -// } - @Test - public void test_sole_blankNodePropertyList() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "sole_blankNodePropertyList.ttl"), true); - } - @Test - public void test_SPARQL_style_base() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "SPARQL_style_base.ttl"), true); - } - @Test - public void test_SPARQL_style_prefix() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "SPARQL_style_prefix.ttl"), true); - } - @Test - public void test_turtle_eval_bad_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-bad-01.ttl"), false); - } - @Test - public void test_turtle_eval_bad_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-bad-02.ttl"), false); - } - @Test - public void test_turtle_eval_bad_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-bad-03.ttl"), false); - } -// @Test -// public void test_turtle_eval_bad_04() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-bad-04.ttl"), false); -// } - @Test - public void test_turtle_eval_struct_01NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-struct-01.nt"), true); - } - @Test - public void test_turtle_eval_struct_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-struct-01.ttl"), true); - } - @Test - public void test_turtle_eval_struct_02NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-struct-02.nt"), true); - } - @Test - public void test_turtle_eval_struct_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-eval-struct-02.ttl"), true); - } - @Test - public void test_turtle_subm_01NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-01.nt"), true); - } - @Test - public void test_turtle_subm_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-01.ttl"), true); - } - @Test - public void test_turtle_subm_02NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-02.nt"), true); - } - @Test - public void test_turtle_subm_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-02.ttl"), true); - } - @Test - public void test_turtle_subm_03NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-03.nt"), true); - } - @Test - public void test_turtle_subm_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-03.ttl"), false); - } - @Test - public void test_turtle_subm_04NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-04.nt"), true); - } - @Test - public void test_turtle_subm_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-04.ttl"), true); - } - @Test - public void test_turtle_subm_05NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-05.nt"), true); - } - @Test - public void test_turtle_subm_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-05.ttl"), true); - } - @Test - public void test_turtle_subm_06NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-06.nt"), true); - } - @Test - public void test_turtle_subm_06() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-06.ttl"), true); - } - @Test - public void test_turtle_subm_07NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-07.nt"), true); - } - @Test - public void test_turtle_subm_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-07.ttl"), false); - } - @Test - public void test_NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-08.nt"), true); - } - @Test - public void test_turtle_subm_08() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-08.ttl"), true); - } - @Test - public void test_turtle_subm_09NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-09.nt"), true); - } - @Test - public void test_turtle_subm_09() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-09.ttl"), true); - } - @Test - public void test_turtle_subm_10NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-10.nt"), true); - } - @Test - public void test_turtle_subm_10() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-10.ttl"), true); - } - @Test - public void test_turtle_subm_11NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-11.nt"), true); - } - @Test - public void test_turtle_subm_11() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-11.ttl"), true); - } - @Test - public void test_turtle_subm_12NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-12.nt"), true); - } - @Test - public void test_turtle_subm_12() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-12.ttl"), true); - } - @Test - public void test_turtle_subm_13NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-13.nt"), true); - } - @Test - public void test_turtle_subm_13() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-13.ttl"), true); - } - @Test - public void test_turtle_subm_14NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-14.nt"), true); - } - @Test - public void test_turtle_subm_14() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-14.ttl"), false); - } - @Test - public void test_turtle_subm_15NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-15.nt"), true); - } - @Test - public void test_turtle_subm_15() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-15.ttl"), true); - } - @Test - public void test_turtle_subm_16NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-16.nt"), true); - } - @Test - public void test_turtle_subm_16() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-16.ttl"), true); - } - @Test - public void test_turtle_subm_17NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-17.nt"), true); - } - @Test - public void test_turtle_subm_17() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-17.ttl"), true); - } - @Test - public void test_turtle_subm_18NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-18.nt"), false); - } - @Test - public void test_turtle_subm_18() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-18.ttl"), false); - } - @Test - public void test_turtle_subm_19NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-19.nt"), true); - } - @Test - public void test_turtle_subm_19() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-19.ttl"), true); - } - @Test - public void test_turtle_subm_20NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-20.nt"), true); - } - @Test - public void test_turtle_subm_20() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-20.ttl"), true); - } - @Test - public void test_turtle_subm_21NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-21.nt"), true); - } - @Test - public void test_turtle_subm_21() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-21.ttl"), true); - } - @Test - public void test_turtle_subm_22NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-22.nt"), true); - } - @Test - public void test_turtle_subm_22() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-22.ttl"), true); - } - @Test - public void test_turtle_subm_23NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-23.nt"), true); - } - @Test - public void test_turtle_subm_23() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-23.ttl"), false); - } - @Test - public void test_turtle_subm_24NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-24.nt"), true); - } - @Test - public void test_turtle_subm_24() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-24.ttl"), true); - } - @Test - public void test_turtle_subm_25NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-25.nt"), true); - } - @Test - public void test_turtle_subm_25() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-25.ttl"), true); - } - @Test - public void test_turtle_subm_26NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-26.nt"), true); - } - @Test - public void test_turtle_subm_26() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-26.ttl"), true); - } - @Test - public void test_turtle_subm_27NT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-27.nt"), true); - } - @Test - public void test_turtle_subm_27() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-subm-27.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_base_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-base-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_base_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-base-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_base_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-base-03.ttl"), false); - } -// @Test -// public void test_turtle_syntax_bad_blank_label_dot_end() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-blank-label-dot-end.ttl"), false); -// } - @Test - public void test_turtle_syntax_bad_esc_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-esc-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_esc_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-esc-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_esc_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-esc-03.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_esc_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-esc-04.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_kw_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-kw-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_kw_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-kw-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_kw_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-kw-03.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_kw_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-kw-04.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_kw_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-kw-05.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_lang_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-lang-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_LITERAL2_with_langtag_and_datatype() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-LITERAL2_with_langtag_and_datatype.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_ln_dash_start() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-ln-dash-start.ttl"), true); - } - @Test - public void test_turtle_syntax_bad_ln_escape() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-ln-escape.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_ln_escape_start() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-ln-escape-start.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_missing_ns_dot_end() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-missing-ns-dot-end.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_missing_ns_dot_start() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-missing-ns-dot-start.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-03.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-04.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-05.ttl"), false); - } -// @Test -// public void test_turtle_syntax_bad_n3_extras_06() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-06.ttl"), false); -// } - @Test - public void test_turtle_syntax_bad_n3_extras_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-07.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_08() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-08.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_09() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-09.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_10() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-10.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_11() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-11.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_12() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-12.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_n3_extras_13() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-n3-extras-13.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_ns_dot_end() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-ns-dot-end.ttl"), true); - } - @Test - public void test_turtle_syntax_bad_ns_dot_start() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-ns-dot-start.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_num_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-num-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_num_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-num-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_num_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-num-03.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_num_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-num-04.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_num_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-num-05.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_number_dot_in_anon() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-number-dot-in-anon.ttl"), true); - } - @Test - public void test_turtle_syntax_bad_pname_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-pname-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_pname_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-pname-02.ttl"), false); - } -// @Test -// public void test_turtle_syntax_bad_pname_03() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-pname-03.ttl"), false); -// } - @Test - public void test_turtle_syntax_bad_prefix_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-prefix-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_prefix_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-prefix-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_prefix_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-prefix-03.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_prefix_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-prefix-04.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_prefix_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-prefix-05.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_string_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-string-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_string_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-string-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_string_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-string-03.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_string_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-string-04.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_string_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-string-05.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_string_06() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-string-06.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_string_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-string-07.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-01.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-03.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-04.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-05.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_06() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-06.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-07.ttl"), true); - } - @Test - public void test_turtle_syntax_bad_struct_08() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-08.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_09() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-09.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_10() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-10.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_11() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-11.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_12() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-12.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_13() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-13.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_14() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-14.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_15() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-15.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_16() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-16.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_struct_17() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-struct-17.ttl"), true); - } -// @Test -// public void test_turtle_syntax_bad_uri_01() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-uri-01.ttl"), false); -// } - @Test - public void test_turtle_syntax_bad_uri_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-uri-02.ttl"), false); - } - @Test - public void test_turtle_syntax_bad_uri_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-uri-03.ttl"), false); - } -// @Test -// public void test_turtle_syntax_bad_uri_04() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-uri-04.ttl"), false); -// } -// @Test -// public void test_turtle_syntax_bad_uri_05() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bad-uri-05.ttl"), false); -// } - @Test - public void test_turtle_syntax_base_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-base-01.ttl"), true); - } - @Test - public void test_turtle_syntax_base_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-base-02.ttl"), true); - } - @Test - public void test_turtle_syntax_base_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-base-03.ttl"), true); - } - @Test - public void test_turtle_syntax_base_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-base-04.ttl"), true); - } - @Test - public void test_turtle_syntax_blank_label() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-blank-label.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-01.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-02.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-03.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-04.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-05.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_06() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-06.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-07.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_08() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-08.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_09() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-09.ttl"), true); - } - @Test - public void test_turtle_syntax_bnode_10() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-bnode-10.ttl"), true); - } - @Test - public void test_turtle_syntax_datatypes_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-datatypes-01.ttl"), true); - } - @Test - public void test_turtle_syntax_datatypes_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-datatypes-02.ttl"), true); - } - @Test - public void test_turtle_syntax_file_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-file-01.ttl"), true); - } - @Test - public void test_turtle_syntax_file_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-file-02.ttl"), true); - } - @Test - public void test_turtle_syntax_file_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-file-03.ttl"), true); - } - @Test - public void test_turtle_syntax_kw_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-kw-01.ttl"), true); - } - @Test - public void test_turtle_syntax_kw_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-kw-02.ttl"), true); - } - @Test - public void test_turtle_syntax_kw_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-kw-03.ttl"), false); - } - @Test - public void test_turtle_syntax_lists_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-lists-01.ttl"), true); - } - @Test - public void test_turtle_syntax_lists_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-lists-02.ttl"), true); - } -// @Test -// public void test_turtle_syntax_lists_03() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-lists-03.ttl"), true); -// } -// @Test -// public void test_turtle_syntax_lists_04() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-lists-04.ttl"), true); -// } -// @Test -// public void test_turtle_syntax_lists_05() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-lists-05.ttl"), true); -// } -// @Test -// public void test_turtle_syntax_ln_colons() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-ln-colons.ttl"), true); -// } - @Test - public void test_turtle_syntax_ln_dots() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-ln-dots.ttl"), false); - } - @Test - public void test_turtle_syntax_ns_dots() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-ns-dots.ttl"), true); - } - @Test - public void test_turtle_syntax_number_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-01.ttl"), true); - } - @Test - public void test_turtle_syntax_number_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-02.ttl"), true); - } - @Test - public void test_turtle_syntax_number_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-03.ttl"), true); - } - @Test - public void test_turtle_syntax_number_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-04.ttl"), true); - } -// @Test -// public void test_turtle_syntax_number_05() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-05.ttl"), true); -// } - @Test - public void test_turtle_syntax_number_06() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-06.ttl"), true); - } - @Test - public void test_turtle_syntax_number_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-07.ttl"), true); - } -// @Test -// public void test_turtle_syntax_number_08() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-08.ttl"), true); -// } - @Test - public void test_turtle_syntax_number_09() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-09.ttl"), true); - } - @Test - public void test_turtle_syntax_number_10() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-10.ttl"), true); - } - @Test - public void test_turtle_syntax_number_11() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-number-11.ttl"), true); - } - @Test - public void test_turtle_syntax_pname_esc_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-pname-esc-01.ttl"), false); - } - @Test - public void test_turtle_syntax_pname_esc_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-pname-esc-02.ttl"), false); - } - @Test - public void test_turtle_syntax_pname_esc_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-pname-esc-03.ttl"), false); - } - @Test - public void test_turtle_syntax_prefix_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-01.ttl"), true); - } -// @Test -// public void test_turtle_syntax_prefix_02() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-02.ttl"), true); -// } - @Test - public void test_turtle_syntax_prefix_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-03.ttl"), true); - } - @Test - public void test_turtle_syntax_prefix_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-04.ttl"), true); - } -// @Test -// public void test_turtle_syntax_prefix_05() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-05.ttl"), true); -// } -// @Test -// public void test_turtle_syntax_prefix_06() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-06.ttl"), true); -// } - @Test - public void test_turtle_syntax_prefix_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-07.ttl"), true); - } - @Test - public void test_turtle_syntax_prefix_08() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-08.ttl"), true); - } - @Test - public void test_turtle_syntax_prefix_09() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-prefix-09.ttl"), true); - } - @Test - public void test_turtle_syntax_str_esc_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-str-esc-01.ttl"), true); - } - @Test - public void test_turtle_syntax_str_esc_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-str-esc-02.ttl"), true); - } - @Test - public void test_turtle_syntax_str_esc_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-str-esc-03.ttl"), true); - } - @Test - public void test_turtle_syntax_string_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-01.ttl"), true); - } - @Test - public void test_turtle_syntax_string_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-02.ttl"), true); - } - @Test - public void test_turtle_syntax_string_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-03.ttl"), true); - } - @Test - public void test_turtle_syntax_string_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-04.ttl"), true); - } - @Test - public void test_turtle_syntax_string_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-05.ttl"), true); - } - @Test - public void test_turtle_syntax_string_06() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-06.ttl"), true); - } - @Test - public void test_turtle_syntax_string_07() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-07.ttl"), true); - } - @Test - public void test_turtle_syntax_string_08() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-08.ttl"), true); - } - @Test - public void test_turtle_syntax_string_09() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-09.ttl"), true); - } - @Test - public void test_turtle_syntax_string_10() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-10.ttl"), true); - } - @Test - public void test_turtle_syntax_string_11() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-string-11.ttl"), true); - } - @Test - public void test_turtle_syntax_struct_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-struct-01.ttl"), true); - } - @Test - public void test_turtle_syntax_struct_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-struct-02.ttl"), true); - } - @Test - public void test_turtle_syntax_struct_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-struct-03.ttl"), true); - } - @Test - public void test_turtle_syntax_struct_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-struct-04.ttl"), true); - } - @Test - public void test_turtle_syntax_struct_05() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-struct-05.ttl"), true); - } - @Test - public void test_turtle_syntax_uri_01() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-uri-01.ttl"), true); - } - @Test - public void test_turtle_syntax_uri_02() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-uri-02.ttl"), true); - } - @Test - public void test_turtle_syntax_uri_03() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-uri-03.ttl"), true); - } - @Test - public void test_turtle_syntax_uri_04() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "turtle-syntax-uri-04.ttl"), true); - } - @Test - public void test_two_LITERAL_LONG2sNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "two_LITERAL_LONG2s.nt"), true); - } - @Test - public void test_two_LITERAL_LONG2s() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "two_LITERAL_LONG2s.ttl"), true); - } - @Test - public void test_underscore_in_localNameNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "underscore_in_localName.nt"), true); - } - @Test - public void test_underscore_in_localName() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "underscore_in_localName.ttl"), true); - } - @Test - public void test_anonymous_blank_node_object() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "anonymous_blank_node_object.ttl"), true); - } - @Test - public void test_anonymous_blank_node_subject() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "anonymous_blank_node_subject.ttl"), true); - } - @Test - public void test_bareword_a_predicateNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "bareword_a_predicate.nt"), true); - } - @Test - public void test_bareword_a_predicate() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "bareword_a_predicate.ttl"), true); - } - @Test - public void test_bareword_decimalNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "bareword_decimal.nt"), true); - } - @Test - public void test_bareword_decimal() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "bareword_decimal.ttl"), true); - } - @Test - public void test_bareword_doubleNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "bareword_double.nt"), true); - } - @Test - public void test_bareword_double() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "bareword_double.ttl"), true); - } - @Test - public void test_bareword_integer() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "bareword_integer.ttl"), true); - } - @Test - public void test_blankNodePropertyList_as_objectNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_as_object.nt"), true); - } - @Test - public void test_blankNodePropertyList_as_object() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_as_object.ttl"), true); - } - @Test - public void test_blankNodePropertyList_as_subjectNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_as_subject.nt"), true); - } -// @Test -// public void test_blankNodePropertyList_as_subject() throws Exception { -// doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_as_subject.ttl"), true); -// } - - @Test - public void test_blankNodePropertyList_containing_collectionNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_containing_collection.nt"), true); - } - @Test - public void test_blankNodePropertyList_containing_collection() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_containing_collection.ttl"), true); - } - @Test - public void test_blankNodePropertyList_with_multiple_triplesNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_with_multiple_triples.nt"), true); - } - @Test - public void test_blankNodePropertyList_with_multiple_triples() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "blankNodePropertyList_with_multiple_triples.ttl"), true); - } - @Test - public void test_collection_objectNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "collection_object.nt"), true); - } - @Test - public void test_collection_object() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "collection_object.ttl"), true); - } - @Test - public void test_collection_subjectNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "collection_subject.nt"), true); - } - @Test - public void test_collection_subject() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "collection_subject.ttl"), false); - } - @Test - public void test_comment_following_localName() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "comment_following_localName.ttl"), true); - } - @Test - public void test_comment_following_PNAME_NSNT() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "comment_following_PNAME_NS.nt"), true); - } - @Test - public void test_comment_following_PNAME_NS() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "comment_following_PNAME_NS.ttl"), false); - } - @Test - public void test__default_namespace_IRI() throws Exception { - doTest(Utilities.path(TestingUtilities.home(), "tests", "turtle", "default_namespace_IRI.ttl"), true); - } -// - - @Test - public void test_audit_event_example_pixQuery() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("audit-event-example-pixQuery.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "audit-event-example-pixQuery.ttl"))); - } - @Test - public void test_audit_event_example_media() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("audit-event-example-media.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "audit-event-example-media.ttl"))); - } - @Test - public void test_audit_event_example_logout() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("audit-event-example-logout.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "audit-event-example-logout.ttl"))); - } - @Test - public void test_audit_event_example_login() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("audit-event-example-login.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "audit-event-example-login.ttl"))); - } - @Test - public void test_appointmentresponse_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("appointmentresponse-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "appointmentresponse-example.ttl"))); - } - @Test - public void test_appointmentresponse_example_req() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("appointmentresponse-example-req.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "appointmentresponse-example-req.ttl"))); - } - @Test - public void test_appointment_example2doctors() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("appointment-example2doctors.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "appointment-example2doctors.ttl"))); - } - @Test - public void test_appointment_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("appointment-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "appointment-example.ttl"))); - } - @Test - public void test_appointment_example_request() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("appointment-example-request.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "appointment-example-request.ttl"))); - } - @Test - public void test_allergyintolerance_medication() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("allergyintolerance-medication.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "allergyintolerance-medication.ttl"))); - } - @Test - public void test_allergyintolerance_fishallergy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("allergyintolerance-fishallergy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "allergyintolerance-fishallergy.ttl"))); - } - @Test - public void test_allergyintolerance_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("allergyintolerance-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "allergyintolerance-example.ttl"))); - } - @Test - public void test_account_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("account-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "account-example.ttl"))); - } - @Test - public void test_xds_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("xds-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "xds-example.ttl"))); - } - @Test - public void test_visionprescription_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("visionprescription-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "visionprescription-example.ttl"))); - } - @Test - public void test_visionprescription_example_1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("visionprescription-example-1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "visionprescription-example-1.ttl"))); - } - @Test - public void test_valueset_ucum_common() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("valueset-ucum-common.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "valueset-ucum-common.ttl"))); - } - @Test - public void test_valueset_nhin_purposeofuse() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("valueset-nhin-purposeofuse.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "valueset-nhin-purposeofuse.ttl"))); - } - @Test - public void test_valueset_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("valueset-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "valueset-example.ttl"))); - } - @Test - public void test_valueset_example_yesnodontknow() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("valueset-example-yesnodontknow.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "valueset-example-yesnodontknow.ttl"))); - } - @Test - public void test_valueset_example_intensional() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("valueset-example-intensional.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "valueset-example-intensional.ttl"))); - } - @Test - public void test_valueset_example_expansion() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("valueset-example-expansion.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "valueset-example-expansion.ttl"))); - } - @Test - public void test_valueset_cpt_all() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("valueset-cpt-all.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "valueset-cpt-all.ttl"))); - } - @Test - public void test_testscript_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("testscript-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "testscript-example.ttl"))); - } - @Test - public void test_testscript_example_rule() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("testscript-example-rule.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "testscript-example-rule.ttl"))); - } - @Test - public void test_supplydelivery_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("supplydelivery-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "supplydelivery-example.ttl"))); - } - @Test - public void test_substance_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("substance-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "substance-example.ttl"))); - } - @Test - public void test_substance_example_silver_nitrate_product() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("substance-example-silver-nitrate-product.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "substance-example-silver-nitrate-product.ttl"))); - } - @Test - public void test_substance_example_f203_potassium() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("substance-example-f203-potassium.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "substance-example-f203-potassium.ttl"))); - } - @Test - public void test_substance_example_f202_staphylococcus() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("substance-example-f202-staphylococcus.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "substance-example-f202-staphylococcus.ttl"))); - } - @Test - public void test_substance_example_f201_dust() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("substance-example-f201-dust.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "substance-example-f201-dust.ttl"))); - } - @Test - public void test_substance_example_amoxicillin_clavulanate() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("substance-example-amoxicillin-clavulanate.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "substance-example-amoxicillin-clavulanate.ttl"))); - } - @Test - public void test_subscription_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("subscription-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "subscription-example.ttl"))); - } - @Test - public void test_subscription_example_error() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("subscription-example-error.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "subscription-example-error.ttl"))); - } - @Test - public void test_structuremap_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("structuremap-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "structuremap-example.ttl"))); - } - @Test - public void test_structuredefinition_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("structuredefinition-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "structuredefinition-example.ttl"))); - } - @Test - public void test_specimen_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("specimen-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "specimen-example.ttl"))); - } - @Test - public void test_specimen_example_urine() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("specimen-example-urine.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "specimen-example-urine.ttl"))); - } - @Test - public void test_specimen_example_isolate() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("specimen-example-isolate.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "specimen-example-isolate.ttl"))); - } - @Test - public void test_slot_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("slot-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "slot-example.ttl"))); - } - @Test - public void test_slot_example_unavailable() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("slot-example-unavailable.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "slot-example-unavailable.ttl"))); - } - @Test - public void test_slot_example_tentative() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("slot-example-tentative.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "slot-example-tentative.ttl"))); - } - @Test - public void test_slot_example_busy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("slot-example-busy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "slot-example-busy.ttl"))); - } - @Test - public void test_sequence_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("sequence-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "sequence-example.ttl"))); - } - @Test - public void test_searchparameter_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("searchparameter-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "searchparameter-example.ttl"))); - } - @Test - public void test_searchparameter_example_extension() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("searchparameter-example-extension.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "searchparameter-example-extension.ttl"))); - } - @Test - public void test_schedule_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("schedule-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "schedule-example.ttl"))); - } - @Test - public void test_riskassessment_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("riskassessment-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "riskassessment-example.ttl"))); - } - @Test - public void test_riskassessment_example_prognosis() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("riskassessment-example-prognosis.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "riskassessment-example-prognosis.ttl"))); - } - @Test - public void test_riskassessment_example_population() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("riskassessment-example-population.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "riskassessment-example-population.ttl"))); - } - @Test - public void test_riskassessment_example_cardiac() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("riskassessment-example-cardiac.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "riskassessment-example-cardiac.ttl"))); - } - @Test - public void test_relatedperson_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("relatedperson-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "relatedperson-example.ttl"))); - } - @Test - public void test_relatedperson_example_peter() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("relatedperson-example-peter.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "relatedperson-example-peter.ttl"))); - } - @Test - public void test_relatedperson_example_f002_ariadne() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("relatedperson-example-f002-ariadne.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "relatedperson-example-f002-ariadne.ttl"))); - } - @Test - public void test_relatedperson_example_f001_sarah() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("relatedperson-example-f001-sarah.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "relatedperson-example-f001-sarah.ttl"))); - } - @Test - public void test_provenance_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("provenance-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "provenance-example.ttl"))); - } - @Test - public void test_provenance_example_sig() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("provenance-example-sig.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "provenance-example-sig.ttl"))); - } - @Test - public void test_processresponse_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processresponse-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processresponse-example.ttl"))); - } - @Test - public void test_processrequest_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example.ttl"))); - } - @Test - public void test_processrequest_example_status() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-status.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-status.ttl"))); - } - @Test - public void test_processrequest_example_reverse() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-reverse.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-reverse.ttl"))); - } - @Test - public void test_processrequest_example_reprocess() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-reprocess.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-reprocess.ttl"))); - } - @Test - public void test_processrequest_example_poll_specific() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-poll-specific.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-poll-specific.ttl"))); - } - @Test - public void test_processrequest_example_poll_payrec() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-poll-payrec.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-poll-payrec.ttl"))); - } - @Test - public void test_processrequest_example_poll_inclusive() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-poll-inclusive.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-poll-inclusive.ttl"))); - } - @Test - public void test_processrequest_example_poll_exclusive() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-poll-exclusive.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-poll-exclusive.ttl"))); - } - @Test - public void test_processrequest_example_poll_eob() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("processrequest-example-poll-eob.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "processrequest-example-poll-eob.ttl"))); - } - @Test - public void test_procedurerequest_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedurerequest-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedurerequest-example.ttl"))); - } - @Test - public void test_procedure_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example.ttl"))); - } - @Test - public void test_procedure_example_implant() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example-implant.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example-implant.ttl"))); - } - @Test - public void test_procedure_example_f201_tpf() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example-f201-tpf.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example-f201-tpf.ttl"))); - } - @Test - public void test_procedure_example_f004_tracheotomy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example-f004-tracheotomy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example-f004-tracheotomy.ttl"))); - } - @Test - public void test_procedure_example_f003_abscess() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example-f003-abscess.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example-f003-abscess.ttl"))); - } - @Test - public void test_procedure_example_f002_lung() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example-f002-lung.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example-f002-lung.ttl"))); - } - @Test - public void test_procedure_example_f001_heart() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example-f001-heart.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example-f001-heart.ttl"))); - } - @Test - public void test_procedure_example_biopsy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("procedure-example-biopsy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "procedure-example-biopsy.ttl"))); - } - @Test - public void test_practitionerrole_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitionerrole-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitionerrole-example.ttl"))); - } - @Test - public void test_practitioner_examples_general() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-examples-general.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-examples-general.ttl"))); - } - @Test - public void test_practitioner_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example.ttl"))); - } - @Test - public void test_practitioner_example_xcda1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-xcda1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-xcda1.ttl"))); - } - @Test - public void test_practitioner_example_xcda_author() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-xcda-author.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-xcda-author.ttl"))); - } - @Test - public void test_practitioner_example_f204_ce() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f204-ce.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f204-ce.ttl"))); - } - @Test - public void test_practitioner_example_f203_jvg() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f203-jvg.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f203-jvg.ttl"))); - } - @Test - public void test_practitioner_example_f202_lm() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f202-lm.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f202-lm.ttl"))); - } - @Test - public void test_practitioner_example_f201_ab() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f201-ab.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f201-ab.ttl"))); - } - @Test - public void test_practitioner_example_f007_sh() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f007-sh.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f007-sh.ttl"))); - } - @Test - public void test_practitioner_example_f006_rvdb() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f006-rvdb.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f006-rvdb.ttl"))); - } - @Test - public void test_practitioner_example_f005_al() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f005-al.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f005-al.ttl"))); - } - @Test - public void test_practitioner_example_f004_rb() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f004-rb.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f004-rb.ttl"))); - } - @Test - public void test_practitioner_example_f003_mv() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f003-mv.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f003-mv.ttl"))); - } - @Test - public void test_practitioner_example_f002_pv() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f002-pv.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f002-pv.ttl"))); - } - @Test - public void test_practitioner_example_f001_evdb() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("practitioner-example-f001-evdb.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "practitioner-example-f001-evdb.ttl"))); - } - @Test - public void test_person_provider_directory() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("person-provider-directory.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "person-provider-directory.ttl"))); - } - @Test - public void test_person_patient_portal() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("person-patient-portal.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "person-patient-portal.ttl"))); - } - @Test - public void test_person_grahame() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("person-grahame.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "person-grahame.ttl"))); - } - @Test - public void test_person_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("person-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "person-example.ttl"))); - } - @Test - public void test_person_example_f002_ariadne() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("person-example-f002-ariadne.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "person-example-f002-ariadne.ttl"))); - } - @Test - public void test_paymentreconciliation_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("paymentreconciliation-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "paymentreconciliation-example.ttl"))); - } - @Test - public void test_paymentnotice_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("paymentnotice-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "paymentnotice-example.ttl"))); - } - @Test - public void test_patient_glossy_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-glossy-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-glossy-example.ttl"))); - } - @Test - public void test_patient_examples_general() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-examples-general.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-examples-general.ttl"))); - } - @Test - public void test_patient_examples_cypress_template() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-examples-cypress-template.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-examples-cypress-template.ttl"))); - } - @Test - public void test_patient_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example.ttl"))); - } - @Test - public void test_patient_example_xds() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-xds.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-xds.ttl"))); - } - @Test - public void test_patient_example_xcda() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-xcda.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-xcda.ttl"))); - } - @Test - public void test_patient_example_proband() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-proband.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-proband.ttl"))); - } - @Test - public void test_patient_example_ihe_pcd() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-ihe-pcd.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-ihe-pcd.ttl"))); - } - @Test - public void test_patient_example_f201_roel() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-f201-roel.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-f201-roel.ttl"))); - } - @Test - public void test_patient_example_f001_pieter() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-f001-pieter.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-f001-pieter.ttl"))); - } - @Test - public void test_patient_example_dicom() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-dicom.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-dicom.ttl"))); - } - @Test - public void test_patient_example_d() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-d.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-d.ttl"))); - } - @Test - public void test_patient_example_c() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-c.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-c.ttl"))); - } - @Test - public void test_patient_example_b() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-b.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-b.ttl"))); - } - @Test - public void test_patient_example_animal() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-animal.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-animal.ttl"))); - } - @Test - public void test_patient_example_a() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("patient-example-a.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "patient-example-a.ttl"))); - } - @Test - public void test_parameters_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("parameters-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "parameters-example.ttl"))); - } - @Test - public void test_organization_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example.ttl"))); - } - @Test - public void test_organization_example_lab() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-lab.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-lab.ttl"))); - } - @Test - public void test_organization_example_insurer() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-insurer.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-insurer.ttl"))); - } - @Test - public void test_organization_example_good_health_care() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-good-health-care.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-good-health-care.ttl"))); - } - @Test - public void test_organization_example_gastro() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-gastro.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-gastro.ttl"))); - } - @Test - public void test_organization_example_f203_bumc() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-f203-bumc.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-f203-bumc.ttl"))); - } - @Test - public void test_organization_example_f201_aumc() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-f201-aumc.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-f201-aumc.ttl"))); - } - @Test - public void test_organization_example_f003_burgers_ENT() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-f003-burgers-ENT.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-f003-burgers-ENT.ttl"))); - } - @Test - public void test_organization_example_f002_burgers_card() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-f002-burgers-card.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-f002-burgers-card.ttl"))); - } - @Test - public void test_organization_example_f001_burgers() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("organization-example-f001-burgers.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "organization-example-f001-burgers.ttl"))); - } - @Test - public void test_operationoutcome_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("operationoutcome-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "operationoutcome-example.ttl"))); - } - @Test - public void test_operationoutcome_example_validationfail() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("operationoutcome-example-validationfail.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "operationoutcome-example-validationfail.ttl"))); - } - @Test - public void test_operationoutcome_example_searchfail() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("operationoutcome-example-searchfail.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "operationoutcome-example-searchfail.ttl"))); - } - @Test - public void test_operationoutcome_example_exception() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("operationoutcome-example-exception.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "operationoutcome-example-exception.ttl"))); - } - @Test - public void test_operationoutcome_example_break_the_glass() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("operationoutcome-example-break-the-glass.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "operationoutcome-example-break-the-glass.ttl"))); - } - @Test - public void test_operationoutcome_example_allok() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("operationoutcome-example-allok.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "operationoutcome-example-allok.ttl"))); - } - @Test - public void test_operationdefinition_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("operationdefinition-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "operationdefinition-example.ttl"))); - } - @Test - public void test_observation_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example.ttl"))); - } - @Test - public void test_observation_example_unsat() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-unsat.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-unsat.ttl"))); - } - @Test - public void test_observation_example_satO2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-satO2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-satO2.ttl"))); - } - @Test - public void test_observation_example_sample_data() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-sample-data.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-sample-data.ttl"))); - } - @Test - public void test_observation_example_glasgow() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-glasgow.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-glasgow.ttl"))); - } - @Test - public void test_observation_example_glasgow_qa() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-glasgow-qa.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-glasgow-qa.ttl"))); - } - @Test - public void test_observation_example_genetics_5() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-genetics-5.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-genetics-5.ttl"))); - } - @Test - public void test_observation_example_genetics_4() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-genetics-4.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-genetics-4.ttl"))); - } - @Test - public void test_observation_example_genetics_3() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-genetics-3.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-genetics-3.ttl"))); - } - @Test - public void test_observation_example_genetics_2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-genetics-2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-genetics-2.ttl"))); - } - @Test - public void test_observation_example_genetics_1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-genetics-1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-genetics-1.ttl"))); - } - @Test - public void test_observation_example_f206_staphylococcus() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f206-staphylococcus.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f206-staphylococcus.ttl"))); - } - @Test - public void test_observation_example_f205_egfr() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f205-egfr.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f205-egfr.ttl"))); - } - @Test - public void test_observation_example_f204_creatinine() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f204-creatinine.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f204-creatinine.ttl"))); - } - @Test - public void test_observation_example_f203_bicarbonate() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f203-bicarbonate.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f203-bicarbonate.ttl"))); - } - @Test - public void test_observation_example_f202_temperature() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f202-temperature.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f202-temperature.ttl"))); - } - @Test - public void test_observation_example_f005_hemoglobin() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f005-hemoglobin.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f005-hemoglobin.ttl"))); - } - @Test - public void test_observation_example_f004_erythrocyte() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f004-erythrocyte.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f004-erythrocyte.ttl"))); - } - @Test - public void test_observation_example_f003_co2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f003-co2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f003-co2.ttl"))); - } - @Test - public void test_observation_example_f002_excess() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f002-excess.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f002-excess.ttl"))); - } - @Test - public void test_observation_example_f001_glucose() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-f001-glucose.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-f001-glucose.ttl"))); - } - @Test - public void test_observation_example_bloodpressure() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-bloodpressure.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-bloodpressure.ttl"))); - } - @Test - public void test_observation_example_bloodpressure_cancel() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("observation-example-bloodpressure-cancel.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "observation-example-bloodpressure-cancel.ttl"))); - } - @Test - public void test_nutritionorder_example_texture_modified() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-texture-modified.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-texture-modified.ttl"))); - } - @Test - public void test_nutritionorder_example_renaldiet() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-renaldiet.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-renaldiet.ttl"))); - } - @Test - public void test_nutritionorder_example_pureeddiet() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-pureeddiet.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-pureeddiet.ttl"))); - } - @Test - public void test_nutritionorder_example_pureeddiet_simple() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-pureeddiet-simple.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-pureeddiet-simple.ttl"))); - } - @Test - public void test_nutritionorder_example_proteinsupplement() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-proteinsupplement.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-proteinsupplement.ttl"))); - } - @Test - public void test_nutritionorder_example_infantenteral() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-infantenteral.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-infantenteral.ttl"))); - } - @Test - public void test_nutritionorder_example_fiberrestricteddiet() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-fiberrestricteddiet.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-fiberrestricteddiet.ttl"))); - } - @Test - public void test_nutritionorder_example_enteralcontinuous() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-enteralcontinuous.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-enteralcontinuous.ttl"))); - } - @Test - public void test_nutritionorder_example_enteralbolus() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-enteralbolus.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-enteralbolus.ttl"))); - } - @Test - public void test_nutritionorder_example_energysupplement() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-energysupplement.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-energysupplement.ttl"))); - } - @Test - public void test_nutritionorder_example_diabeticsupplement() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-diabeticsupplement.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-diabeticsupplement.ttl"))); - } - @Test - public void test_nutritionorder_example_diabeticdiet() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-diabeticdiet.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-diabeticdiet.ttl"))); - } - @Test - public void test_nutritionorder_example_cardiacdiet() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("nutritionorder-example-cardiacdiet.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "nutritionorder-example-cardiacdiet.ttl"))); - } - @Test - public void test_namingsystem_registry() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("namingsystem-registry.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "namingsystem-registry.ttl"))); - } - @Test - public void test_namingsystem_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("namingsystem-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "namingsystem-example.ttl"))); - } - @Test - public void test_namingsystem_example_replaced() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("namingsystem-example-replaced.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "namingsystem-example-replaced.ttl"))); - } - @Test - public void test_namingsystem_example_id() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("namingsystem-example-id.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "namingsystem-example-id.ttl"))); - } - @Test - public void test_messageheader_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("messageheader-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "messageheader-example.ttl"))); - } - @Test - public void test_message_response_link() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("message-response-link.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "message-response-link.ttl"))); - } - @Test - public void test_message_request_link() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("message-request-link.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "message-request-link.ttl"))); - } - @Test - public void test_medicationstatementexample7() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationstatementexample7.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationstatementexample7.ttl"))); - } - @Test - public void test_medicationstatementexample6() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationstatementexample6.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationstatementexample6.ttl"))); - } - @Test - public void test_medicationstatementexample5() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationstatementexample5.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationstatementexample5.ttl"))); - } - @Test - public void test_medicationstatementexample4() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationstatementexample4.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationstatementexample4.ttl"))); - } - @Test - public void test_medicationstatementexample2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationstatementexample2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationstatementexample2.ttl"))); - } - @Test - public void test_medicationstatementexample1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationstatementexample1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationstatementexample1.ttl"))); - } - @Test - public void test_medicationrequestexample2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationrequestexample2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationrequestexample2.ttl"))); - } - @Test - public void test_medicationrequestexample1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationrequestexample1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationrequestexample1.ttl"))); - } - @Test - public void test_medicationexample15() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationexample15.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationexample15.ttl"))); - } - @Test - public void test_medicationexample1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationexample1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationexample1.ttl"))); - } - @Test - public void test_medicationdispenseexample8() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationdispenseexample8.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationdispenseexample8.ttl"))); - } - @Test - public void test_medicationadministrationexample3() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationadministrationexample3.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationadministrationexample3.ttl"))); - } - @Test - public void test_medication_example_f203_paracetamol() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("medicationexample0312.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "medicationexample0312.ttl"))); - } - @Test - public void test_media_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("media-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "media-example.ttl"))); - } - @Test - public void test_media_example_sound() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("media-example-sound.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "media-example-sound.ttl"))); - } - @Test - public void test_media_example_dicom() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("media-example-dicom.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "media-example-dicom.ttl"))); - } - @Test - public void test_measurereport_cms146_cat3_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("measurereport-cms146-cat3-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "measurereport-cms146-cat3-example.ttl"))); - } - @Test - public void test_measurereport_cms146_cat2_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("measurereport-cms146-cat2-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "measurereport-cms146-cat2-example.ttl"))); - } - @Test - public void test_measurereport_cms146_cat1_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("measurereport-cms146-cat1-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "measurereport-cms146-cat1-example.ttl"))); - } - @Test - public void test_measure_exclusive_breastfeeding() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("measure-exclusive-breastfeeding.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "measure-exclusive-breastfeeding.ttl"))); - } - @Test - public void test_location_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("location-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "location-example.ttl"))); - } - @Test - public void test_location_example_ukpharmacy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("location-example-ukpharmacy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "location-example-ukpharmacy.ttl"))); - } - @Test - public void test_location_example_room() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("location-example-room.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "location-example-room.ttl"))); - } - @Test - public void test_location_example_patients_home() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("location-example-patients-home.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "location-example-patients-home.ttl"))); - } - @Test - public void test_location_example_hl7hq() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("location-example-hl7hq.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "location-example-hl7hq.ttl"))); - } - @Test - public void test_location_example_ambulance() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("location-example-ambulance.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "location-example-ambulance.ttl"))); - } - @Test - public void test_list_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("list-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "list-example.ttl"))); - } - @Test - public void test_list_example_medlist() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("list-example-medlist.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "list-example-medlist.ttl"))); - } - @Test - public void test_list_example_familyhistory_f201_roel() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("list-example-familyhistory-f201-roel.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "list-example-familyhistory-f201-roel.ttl"))); - } - @Test - public void test_list_example_empty() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("list-example-empty.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "list-example-empty.ttl"))); - } - @Test - public void test_list_example_allergies() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("list-example-allergies.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "list-example-allergies.ttl"))); - } - @Test - public void test_linkage_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("linkage-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "linkage-example.ttl"))); - } - @Test - public void test_library_exclusive_breastfeeding_cqm_logic() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("library-exclusive-breastfeeding-cqm-logic.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "library-exclusive-breastfeeding-cqm-logic.ttl"))); - } - @Test - public void test_library_exclusive_breastfeeding_cds_logic() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("library-exclusive-breastfeeding-cds-logic.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "library-exclusive-breastfeeding-cds-logic.ttl"))); - } - @Test - public void test_library_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("library-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "library-example.ttl"))); - } - @Test - public void test_library_cms146_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("library-cms146-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "library-cms146-example.ttl"))); - } - @Test - public void test_implementationguide_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("implementationguide-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "implementationguide-example.ttl"))); - } - @Test - public void test_immunizationrecommendation_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("immunizationrecommendation-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "immunizationrecommendation-example.ttl"))); - } - @Test - public void test_immunization_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("immunization-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "immunization-example.ttl"))); - } - @Test - public void test_immunization_example_refused() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("immunization-example-refused.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "immunization-example-refused.ttl"))); - } - @Test - public void test_imagingstudy_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("imagingstudy-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "imagingstudy-example.ttl"))); - } - @Test - public void test_healthcareservice_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("healthcareservice-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "healthcareservice-example.ttl"))); - } - @Test - public void test_guidanceresponse_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("guidanceresponse-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "guidanceresponse-example.ttl"))); - } - @Test - public void test_group_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("group-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "group-example.ttl"))); - } - @Test - public void test_group_example_member() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("group-example-member.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "group-example-member.ttl"))); - } - @Test - public void test_goal_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("goal-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "goal-example.ttl"))); - } - @Test - public void test_flag_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("flag-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "flag-example.ttl"))); - } - @Test - public void test_flag_example_encounter() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("flag-example-encounter.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "flag-example-encounter.ttl"))); - } - @Test - public void test_familymemberhistory_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("familymemberhistory-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "familymemberhistory-example.ttl"))); - } - @Test - public void test_familymemberhistory_example_mother() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("familymemberhistory-example-mother.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "familymemberhistory-example-mother.ttl"))); - } - @Test - public void test_explanationofbenefit_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("explanationofbenefit-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "explanationofbenefit-example.ttl"))); - } - @Test - public void test_episodeofcare_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("episodeofcare-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "episodeofcare-example.ttl"))); - } - @Test - public void test_enrollmentresponse_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("enrollmentresponse-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "enrollmentresponse-example.ttl"))); - } - @Test - public void test_enrollmentrequest_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("enrollmentrequest-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "enrollmentrequest-example.ttl"))); - } - @Test - public void test_endpoint_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("endpoint-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "endpoint-example.ttl"))); - } - @Test - public void test_encounter_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example.ttl"))); - } - @Test - public void test_encounter_example_xcda() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-xcda.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-xcda.ttl"))); - } - @Test - public void test_encounter_example_home() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-home.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-home.ttl"))); - } - @Test - public void test_encounter_example_f203_20130311() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-f203-20130311.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-f203-20130311.ttl"))); - } - @Test - public void test_encounter_example_f202_20130128() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-f202-20130128.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-f202-20130128.ttl"))); - } - @Test - public void test_encounter_example_f201_20130404() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-f201-20130404.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-f201-20130404.ttl"))); - } - @Test - public void test_encounter_example_f003_abscess() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-f003-abscess.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-f003-abscess.ttl"))); - } - @Test - public void test_encounter_example_f002_lung() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-f002-lung.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-f002-lung.ttl"))); - } - @Test - public void test_encounter_example_f001_heart() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("encounter-example-f001-heart.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "encounter-example-f001-heart.ttl"))); - } - @Test - public void test_eligibilityresponse_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("eligibilityresponse-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "eligibilityresponse-example.ttl"))); - } - @Test - public void test_eligibilityrequest_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("eligibilityrequest-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "eligibilityrequest-example.ttl"))); - } - @Test - public void test_documentreference_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("documentreference-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "documentreference-example.ttl"))); - } - @Test - public void test_documentmanifest_fm_attachment() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("documentmanifest-fm-attachment.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "documentmanifest-fm-attachment.ttl"))); - } - @Test - public void test_document_example_dischargesummary() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("document-example-dischargesummary.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "document-example-dischargesummary.ttl"))); - } - @Test - public void test_diagnosticreport_micro1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-micro1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-micro1.ttl"))); - } - @Test - public void test_diagnosticreport_hla_genetics_results_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-hla-genetics-results-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-hla-genetics-results-example.ttl"))); - } - - @Test - public void test_diagnosticreport_genetics_comprehensive_bone_marrow_report() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-genetics-comprehensive-bone-marrow-report.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-genetics-comprehensive-bone-marrow-report.ttl"))); - } - @Test - public void test_diagnosticreport_examples_general() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-examples-general.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-examples-general.ttl"))); - } - @Test - public void test_diagnosticreport_example_ultrasound() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-example-ultrasound.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-example-ultrasound.ttl"))); - } - @Test - public void test_diagnosticreport_example_lipids() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-example-lipids.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-example-lipids.ttl"))); - } - @Test - public void test_diagnosticreport_example_ghp() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-example-ghp.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-example-ghp.ttl"))); - } - @Test - public void test_diagnosticreport_example_f202_bloodculture() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-example-f202-bloodculture.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-example-f202-bloodculture.ttl"))); - } - @Test - public void test_diagnosticreport_example_f201_brainct() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-example-f201-brainct.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-example-f201-brainct.ttl"))); - } - @Test - public void test_diagnosticreport_example_f001_bloodexam() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-example-f001-bloodexam.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-example-f001-bloodexam.ttl"))); - } - @Test - public void test_diagnosticreport_example_dxa() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("diagnosticreport-example-dxa.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "diagnosticreport-example-dxa.ttl"))); - } - @Test - public void test_deviceusestatement_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("deviceusestatement-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "deviceusestatement-example.ttl"))); - } - @Test - public void test_devicemetric_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("devicemetric-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "devicemetric-example.ttl"))); - } - @Test - public void test_devicecomponent_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("devicecomponent-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "devicecomponent-example.ttl"))); - } - @Test - public void test_devicecomponent_example_prodspec() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("devicecomponent-example-prodspec.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "devicecomponent-example-prodspec.ttl"))); - } - @Test - public void test_device_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("device-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "device-example.ttl"))); - } - @Test - public void test_device_example_udi1() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("device-example-udi1.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "device-example-udi1.ttl"))); - } - @Test - public void test_device_example_software() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("device-example-software.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "device-example-software.ttl"))); - } - @Test - public void test_device_example_pacemaker() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("device-example-pacemaker.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "device-example-pacemaker.ttl"))); - } - @Test - public void test_device_example_ihe_pcd() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("device-example-ihe-pcd.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "device-example-ihe-pcd.ttl"))); - } - @Test - public void test_device_example_f001_feedingtube() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("device-example-f001-feedingtube.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "device-example-f001-feedingtube.ttl"))); - } - @Test - public void test_detectedissue_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("detectedissue-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "detectedissue-example.ttl"))); - } - @Test - public void test_detectedissue_example_lab() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("detectedissue-example-lab.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "detectedissue-example-lab.ttl"))); - } - @Test - public void test_detectedissue_example_dup() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("detectedissue-example-dup.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "detectedissue-example-dup.ttl"))); - } - @Test - public void test_detectedissue_example_allergy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("detectedissue-example-allergy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "detectedissue-example-allergy.ttl"))); - } - @Test - public void test_coverage_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("coverage-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "coverage-example.ttl"))); - } - @Test - public void test_coverage_example_2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("coverage-example-2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "coverage-example-2.ttl"))); - } - @Test - public void test_contract_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("contract-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "contract-example.ttl"))); - } - @Test - public void test_condition_example2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example2.ttl"))); - } - @Test - public void test_condition_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example.ttl"))); - } - @Test - public void test_condition_example_stroke() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-stroke.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-stroke.ttl"))); - } - @Test - public void test_condition_example_f205_infection() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f205-infection.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f205-infection.ttl"))); - } - @Test - public void test_condition_example_f204_renal() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f204-renal.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f204-renal.ttl"))); - } - @Test - public void test_condition_example_f203_sepsis() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f203-sepsis.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f203-sepsis.ttl"))); - } - @Test - public void test_condition_example_f202_malignancy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f202-malignancy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f202-malignancy.ttl"))); - } - @Test - public void test_condition_example_f201_fever() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f201-fever.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f201-fever.ttl"))); - } - @Test - public void test_condition_example_f003_abscess() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f003-abscess.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f003-abscess.ttl"))); - } - @Test - public void test_condition_example_f002_lung() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f002-lung.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f002-lung.ttl"))); - } - @Test - public void test_condition_example_f001_heart() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("condition-example-f001-heart.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "condition-example-f001-heart.ttl"))); - } - @Test - public void test_conceptmap_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("conceptmap-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "conceptmap-example.ttl"))); - } - @Test - public void test_conceptmap_example_specimen_type() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("conceptmap-example-specimen-type.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "conceptmap-example-specimen-type.ttl"))); - } - @Test - public void test_conceptmap_103() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("conceptmap-103.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "conceptmap-103.ttl"))); - } - @Test - public void test_composition_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("composition-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "composition-example.ttl"))); - } - @Test - public void test_communicationrequest_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("communicationrequest-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "communicationrequest-example.ttl"))); - } - @Test - public void test_communication_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("communication-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "communication-example.ttl"))); - } - @Test - public void test_codesystem_nhin_purposeofuse() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("codesystem-nhin-purposeofuse.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "codesystem-nhin-purposeofuse.ttl"))); - } - @Test - public void test_codesystem_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("codesystem-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "codesystem-example.ttl"))); - } - @Test - public void test_clinicalimpression_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("clinicalimpression-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "clinicalimpression-example.ttl"))); - } - @Test - public void test_claimresponse_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claimresponse-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claimresponse-example.ttl"))); - } - @Test - public void test_claim_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example.ttl"))); - } - @Test - public void test_claim_example_vision() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-vision.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-vision.ttl"))); - } - @Test - public void test_claim_example_vision_glasses() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-vision-glasses.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-vision-glasses.ttl"))); - } - @Test - public void test_claim_example_professional() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-professional.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-professional.ttl"))); - } - @Test - public void test_claim_example_pharmacy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-pharmacy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-pharmacy.ttl"))); - } - @Test - public void test_claim_example_oral_orthoplan() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-oral-orthoplan.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-oral-orthoplan.ttl"))); - } - @Test - public void test_claim_example_oral_identifier() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-oral-identifier.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-oral-identifier.ttl"))); - } - @Test - public void test_claim_example_oral_contained() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-oral-contained.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-oral-contained.ttl"))); - } - @Test - public void test_claim_example_oral_contained_identifier() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-oral-contained-identifier.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-oral-contained-identifier.ttl"))); - } - @Test - public void test_claim_example_oral_average() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-oral-average.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-oral-average.ttl"))); - } - @Test - public void test_claim_example_institutional() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("claim-example-institutional.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "claim-example-institutional.ttl"))); - } - @Test - public void test_careteam_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careteam-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careteam-example.ttl"))); - } - @Test - public void test_careplan_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example.ttl"))); - } - @Test - public void test_careplan_example_pregnancy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-pregnancy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-pregnancy.ttl"))); - } - @Test - public void test_careplan_example_integrated() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-integrated.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-integrated.ttl"))); - } - @Test - public void test_careplan_example_GPVisit() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-GPVisit.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-GPVisit.ttl"))); - } - @Test - public void test_careplan_example_f203_sepsis() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-f203-sepsis.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-f203-sepsis.ttl"))); - } - @Test - public void test_careplan_example_f202_malignancy() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-f202-malignancy.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-f202-malignancy.ttl"))); - } - @Test - public void test_careplan_example_f201_renal() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-f201-renal.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-f201-renal.ttl"))); - } - @Test - public void test_careplan_example_f003_pharynx() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-f003-pharynx.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-f003-pharynx.ttl"))); - } - @Test - public void test_careplan_example_f002_lung() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-f002-lung.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-f002-lung.ttl"))); - } - @Test - public void test_careplan_example_f001_heart() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("careplan-example-f001-heart.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "careplan-example-f001-heart.ttl"))); - } - @Test - public void test_bundle_transaction() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("bundle-transaction.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "bundle-transaction.ttl"))); - } - @Test - public void test_bundle_response() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("bundle-response.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "bundle-response.ttl"))); - } - @Test - public void test_bundle_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("bundle-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "bundle-example.ttl"))); - } - @Test - public void test_binary_f006() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("binary-f006.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "binary-f006.ttl"))); - } - @Test - public void test_binary_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("binary-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "binary-example.ttl"))); - } - @Test - public void test_basic_example2() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("basic-example2.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "basic-example2.ttl"))); - } - @Test - public void test_basic_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("basic-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "basic-example.ttl"))); - } - @Test - public void test_basic_example_narrative() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("basic-example-narrative.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "basic-example-narrative.ttl"))); - } - @Test - public void test_auditevent_example() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("auditevent-example.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "auditevent-example.ttl"))); - } - @Test - public void test_auditevent_example_disclosure() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("auditevent-example-disclosure.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "auditevent-example-disclosure.ttl"))); - } - @Test - public void test_audit_event_example_vread() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("audit-event-example-vread.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "audit-event-example-vread.ttl"))); - } - @Test - public void test_audit_event_example_search() throws FileNotFoundException, IOException, Exception { - if (!TestingUtilities.silent) - System.out.println("audit-event-example-search.ttl"); - new Turtle().parse(TextFile.fileToString(Utilities.path(TestingUtilities.home(), "publish", "audit-event-example-search.ttl"))); - } - - -} diff --git a/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/BaseController.java b/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/BaseController.java index 4ab90ed7c8a..e091ae6b3a8 100644 --- a/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/BaseController.java +++ b/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/BaseController.java @@ -1,31 +1,8 @@ package ca.uhn.fhir.to; -import static org.apache.commons.lang3.StringUtils.defaultString; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.*; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.Header; -import org.apache.http.entity.ContentType; -import org.apache.http.message.BasicHeader; -import org.hl7.fhir.dstu3.model.*; -import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent; -import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.instance.model.api.IDomainResource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.ui.ModelMap; -import org.thymeleaf.TemplateEngine; - -import ca.uhn.fhir.context.*; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; +import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.IResource; @@ -36,6 +13,31 @@ import ca.uhn.fhir.rest.client.api.*; import ca.uhn.fhir.rest.client.impl.GenericClient; import ca.uhn.fhir.to.model.HomeRequest; import ca.uhn.fhir.util.ExtensionConstants; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.Header; +import org.apache.http.entity.ContentType; +import org.apache.http.message.BasicHeader; +import org.hl7.fhir.dstu3.model.CapabilityStatement; +import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent; +import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent; +import org.hl7.fhir.dstu3.model.DecimalType; +import org.hl7.fhir.dstu3.model.Extension; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IDomainResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.ui.ModelMap; +import org.thymeleaf.TemplateEngine; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.*; + +import static org.apache.commons.lang3.StringUtils.defaultString; public class BaseController { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseController.class); @@ -285,7 +287,7 @@ public class BaseController { ourLog.warn("Failed to invoke server", e); if (e != null) { - theModel.put("errorMsg", "Error: " + e.getMessage()); + theModel.put("errorMsg", toDisplayError("Error: " + e.getMessage(), e)); } return returnsResource; @@ -313,8 +315,8 @@ public class BaseController { try { conformance = (ca.uhn.fhir.model.dstu2.resource.Conformance) client.conformance(); } catch (Exception e) { - ourLog.warn("Failed to load conformance statement", e); - theModel.put("errorMsg", "Failed to load conformance statement, error was: " + e.toString()); + ourLog.warn("Failed to load conformance statement, error was: {}", e.toString()); + theModel.put("errorMsg", toDisplayError("Failed to load conformance statement, error was: " + e.toString(), e)); conformance = new ca.uhn.fhir.model.dstu2.resource.Conformance(); } @@ -373,8 +375,8 @@ public class BaseController { try { capabilityStatement = client.fetchConformance().ofType(org.hl7.fhir.dstu3.model.CapabilityStatement.class).execute(); } catch (Exception ex) { - ourLog.warn("Failed to load conformance statement", ex); - theModel.put("errorMsg", "Failed to load conformance statement, error was: " + ex.toString()); + ourLog.warn("Failed to load conformance statement, error was: {}", ex.toString()); + theModel.put("errorMsg", toDisplayError("Failed to load conformance statement, error was: " + ex.toString(), ex)); } theModel.put("jsonEncodedConf", getContext(theRequest).newJsonParser().encodeResourceToString(capabilityStatement)); @@ -602,7 +604,7 @@ public class BaseController { } catch (Exception e) { ourLog.error("Failure during processing", e); - theModelMap.put("errorMsg", "Error during processing: " + e.getMessage()); + theModelMap.put("errorMsg", toDisplayError("Error during processing: " + e.getMessage(), e)); } } @@ -679,4 +681,16 @@ public class BaseController { BUNDLE, NONE, RESOURCE, TAGLIST } -} \ No newline at end of file + /** + * A hook to be overridden by subclasses. The overriding method can modify the error message + * based on its content and/or the related exception. + * + * @param theErrorMsg The original error message to be displayed to the user. + * @param theException The exception that occurred. May be null. + * @return The modified error message to be displayed to the user. + */ + protected String toDisplayError(String theErrorMsg, Exception theException) { + return theErrorMsg; + } + +} diff --git a/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java b/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java index 1f858bdb8cb..fc98a67371c 100644 --- a/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java +++ b/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java @@ -1,6 +1,9 @@ package ca.uhn.fhir.to; -import static org.apache.commons.lang3.StringUtils.*; +import static org.apache.commons.lang3.StringUtils.defaultIfEmpty; +import static org.apache.commons.lang3.StringUtils.defaultString; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.io.IOException; import java.io.StringWriter; @@ -63,15 +66,15 @@ public class Controller extends BaseController { Class type; switch (getContext(theRequest).getVersion().getVersion()) { default: - case DSTU1: - type = Conformance.class; - break; case DSTU2: type = ca.uhn.fhir.model.dstu2.resource.Conformance.class; break; case DSTU3: type = org.hl7.fhir.dstu3.model.CapabilityStatement.class; break; + case R4: + type = org.hl7.fhir.r4.model.CapabilityStatement.class; + break; } client.fetchConformance().ofType(type).execute(); } catch (Exception e) { @@ -103,13 +106,13 @@ public class Controller extends BaseController { try { def = getResourceType(theRequest, theReq); } catch (ServletException e) { - theModel.put("errorMsg", e.toString()); + theModel.put("errorMsg", toDisplayError(e.toString(), e)); return "resource"; } String id = StringUtils.defaultString(theReq.getParameter("resource-delete-id")); if (StringUtils.isBlank(id)) { - theModel.put("errorMsg", "No ID specified"); + theModel.put("errorMsg", toDisplayError("No ID specified", null)); return "resource"; } @@ -148,7 +151,7 @@ public class Controller extends BaseController { try { def = getResourceType(theRequest, theReq); } catch (ServletException e) { - theModel.put("errorMsg", e.toString()); + theModel.put("errorMsg", toDisplayError(e.toString(), e)); return "resource"; } @@ -212,11 +215,11 @@ public class Controller extends BaseController { if (myConfig.isRefuseToFetchThirdPartyUrls()) { if (!url.startsWith(theModel.get("base").toString())) { ourLog.warn(logPrefix(theModel) + "Refusing to load page URL: {}", url); - theModel.put("errorMsg", "Invalid page URL: " + url); + theModel.put("errorMsg", toDisplayError("Invalid page URL: " + url, null)); return "result"; } } - + url = url.replace("&", "&"); ResultType returnsResource = ResultType.BUNDLE; @@ -224,13 +227,9 @@ public class Controller extends BaseController { long start = System.currentTimeMillis(); try { ourLog.info(logPrefix(theModel) + "Loading paging URL: {}", url); - if (context.getVersion().getVersion() == FhirVersionEnum.DSTU1) { - client.loadPage().byUrl(url).andReturnDstu1Bundle().execute(); - } else { - @SuppressWarnings("unchecked") - Class bundleType = (Class) context.getResourceDefinition("Bundle").getImplementingClass(); - client.loadPage().byUrl(url).andReturnBundle(bundleType).execute(); - } + @SuppressWarnings("unchecked") + Class bundleType = (Class) context.getResourceDefinition("Bundle").getImplementingClass(); + client.loadPage().byUrl(url).andReturnBundle(bundleType).execute(); } catch (Exception e) { returnsResource = handleClientException(client, e, theModel); } @@ -254,12 +253,12 @@ public class Controller extends BaseController { try { def = getResourceType(theRequest, theReq); } catch (ServletException e) { - theModel.put("errorMsg", e.toString()); + theModel.put("errorMsg", toDisplayError(e.toString(), e)); return "resource"; } String id = StringUtils.defaultString(theReq.getParameter("id")); if (StringUtils.isBlank(id)) { - theModel.put("errorMsg", "No ID specified"); + theModel.put("errorMsg", toDisplayError("No ID specified", null)); return "resource"; } ResultType returnsResource = ResultType.RESOURCE; @@ -315,13 +314,16 @@ public class Controller extends BaseController { case DSTU3: haveSearchParams = extractSearchParamsDstu3CapabilityStatement(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes); break; + case R4: + haveSearchParams = extractSearchParamsR4CapabilityStatement(conformance, resourceName, includes, revIncludes, sortParams, haveSearchParams, queryIncludes); + break; default: throw new IllegalStateException("Unknown FHIR version: " + theRequest.getFhirVersion(myConfig)); } theModel.put("includes", includes); theModel.put("revincludes", revIncludes); - theModel.put("queries", Collections.emptyList()); //TODO: remove this, it does nothing + theModel.put("queries", Collections.emptyList()); // TODO: remove this, it does nothing theModel.put("haveSearchParams", haveSearchParams); theModel.put("queryIncludes", queryIncludes); theModel.put("sortParams", sortParams); @@ -362,7 +364,7 @@ public class Controller extends BaseController { try { query = search.forResource((Class) getResourceType(theRequest, theReq).getImplementingClass()); } catch (ServletException e) { - theModel.put("errorMsg", e.toString()); + theModel.put("errorMsg", toDisplayError(e.toString(), e)); return "resource"; } clientCodeJsonWriter.name("resource"); @@ -434,7 +436,7 @@ public class Controller extends BaseController { String limit = theReq.getParameter("resource-search-limit"); if (isNotBlank(limit)) { if (!limit.matches("[0-9]+")) { - theModel.put("errorMsg", "Search limit must be a numeric value."); + theModel.put("errorMsg", toDisplayError("Search limit must be a numeric value.", null)); return "resource"; } int limitInt = Integer.parseInt(limit); @@ -463,9 +465,7 @@ public class Controller extends BaseController { } } - if (client.getFhirContext().getVersion().getVersion() != FhirVersionEnum.DSTU1) { - query.returnBundle(client.getFhirContext().getResourceDefinition("Bundle").getImplementingClass()); - } + query.returnBundle(client.getFhirContext().getResourceDefinition("Bundle").getImplementingClass()); long start = System.currentTimeMillis(); ResultType returnsResource; @@ -505,12 +505,13 @@ public class Controller extends BaseController { } else if (body.startsWith("<")) { // XML content } else { - theModel.put("errorMsg", "Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding)."); + theModel.put("errorMsg", + toDisplayError("Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding).", null)); return "home"; } } catch (DataFormatException e) { ourLog.warn("Failed to parse bundle", e); - theModel.put("errorMsg", "Failed to parse transaction bundle body. Error was: " + e.getMessage()); + theModel.put("errorMsg", toDisplayError("Failed to parse transaction bundle body. Error was: " + e.getMessage(), e)); return "home"; } @@ -558,7 +559,7 @@ public class Controller extends BaseController { String body = validate ? theReq.getParameter("resource-validate-body") : theReq.getParameter("resource-create-body"); if (isBlank(body)) { - theModel.put("errorMsg", "No message body specified"); + theModel.put("errorMsg", toDisplayError("No message body specified", null)); return; } @@ -573,12 +574,13 @@ public class Controller extends BaseController { resource = getContext(theRequest).newXmlParser().parseResource(type, body); client.setEncoding(EncodingEnum.XML); } else { - theModel.put("errorMsg", "Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding)."); + theModel.put("errorMsg", + toDisplayError("Message body does not appear to be a valid FHIR resource instance document. Body should start with '<' (for XML encoding) or '{' (for JSON encoding).", null)); return; } } catch (DataFormatException e) { ourLog.warn("Failed to parse resource", e); - theModel.put("errorMsg", "Failed to parse message body. Error was: " + e.getMessage()); + theModel.put("errorMsg", toDisplayError("Failed to parse message body. Error was: " + e.getMessage(), e)); return; } @@ -671,11 +673,7 @@ public class Controller extends BaseController { } IHistoryTyped hist2; - if (client.getFhirContext().getVersion().getVersion() == FhirVersionEnum.DSTU1) { - hist2 = hist1.andReturnDstu1Bundle(); - } else { - hist2 = hist1.andReturnBundle(client.getFhirContext().getResourceDefinition("Bundle").getImplementingClass(IBaseBundle.class)); - } + hist2 = hist1.andReturnBundle(client.getFhirContext().getResourceDefinition("Bundle").getImplementingClass(IBaseBundle.class)); if (since != null) { hist2.since(since); @@ -694,8 +692,8 @@ public class Controller extends BaseController { } - - private boolean extractSearchParamsDstu2(IBaseResource theConformance, String resourceName, TreeSet includes, TreeSet theRevIncludes, TreeSet sortParams, boolean haveSearchParams, List> queryIncludes) { + private boolean extractSearchParamsDstu2(IBaseResource theConformance, String resourceName, TreeSet includes, TreeSet theRevIncludes, TreeSet sortParams, + boolean haveSearchParams, List> queryIncludes) { ca.uhn.fhir.model.dstu2.resource.Conformance conformance = (ca.uhn.fhir.model.dstu2.resource.Conformance) theConformance; for (ca.uhn.fhir.model.dstu2.resource.Conformance.Rest nextRest : conformance.getRest()) { for (ca.uhn.fhir.model.dstu2.resource.Conformance.RestResource nextRes : nextRest.getResource()) { @@ -731,7 +729,8 @@ public class Controller extends BaseController { return haveSearchParams; } - private boolean extractSearchParamsDstu3CapabilityStatement(IBaseResource theConformance, String resourceName, TreeSet includes, TreeSet theRevIncludes, TreeSet sortParams, boolean haveSearchParams, List> queryIncludes) { + private boolean extractSearchParamsDstu3CapabilityStatement(IBaseResource theConformance, String resourceName, TreeSet includes, TreeSet theRevIncludes, TreeSet sortParams, + boolean haveSearchParams, List> queryIncludes) { CapabilityStatement conformance = (org.hl7.fhir.dstu3.model.CapabilityStatement) theConformance; for (CapabilityStatementRestComponent nextRest : conformance.getRest()) { for (CapabilityStatementRestResourceComponent nextRes : nextRest.getResource()) { @@ -754,11 +753,38 @@ public class Controller extends BaseController { // scan for revinclude candidates for (CapabilityStatementRestResourceSearchParamComponent next : nextRes.getSearchParam()) { if (next.getTypeElement().getValue() == org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE) { -// for (CodeType nextTargetType : next.getTarget()) { -// if (nextTargetType.getValue().equals(resourceName)) { -// theRevIncludes.add(nextRes.getTypeElement().getValue() + ":" + next.getName()); -// } -// } + } + } + } + } + } + return haveSearchParams; + } + + private boolean extractSearchParamsR4CapabilityStatement(IBaseResource theConformance, String resourceName, TreeSet includes, TreeSet theRevIncludes, TreeSet sortParams, + boolean haveSearchParams, List> queryIncludes) { + org.hl7.fhir.r4.model.CapabilityStatement conformance = (org.hl7.fhir.r4.model.CapabilityStatement) theConformance; + for (org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestComponent nextRest : conformance.getRest()) { + for (org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent nextRes : nextRest.getResource()) { + if (nextRes.getTypeElement().getValue().equals(resourceName)) { + for (org.hl7.fhir.r4.model.StringType next : nextRes.getSearchInclude()) { + if (next.isEmpty() == false) { + includes.add(next.getValue()); + } + } + for (org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent next : nextRes.getSearchParam()) { + if (next.getTypeElement().getValue() != org.hl7.fhir.r4.model.Enumerations.SearchParamType.COMPOSITE) { + sortParams.add(next.getNameElement().getValue()); + } + } + if (nextRes.getSearchParam().size() > 0) { + haveSearchParams = true; + } + } else { + // It's a different resource from the one we're searching, so + // scan for revinclude candidates + for (org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent next : nextRes.getSearchParam()) { + if (next.getTypeElement().getValue() == org.hl7.fhir.r4.model.Enumerations.SearchParamType.REFERENCE) { } } } diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/profile/profiles-others.xml b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile/profiles-others.xml similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/profile/profiles-others.xml rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile/profiles-others.xml diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/profile/profiles-resources.xml b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile/profiles-resources.xml similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/profile/profiles-resources.xml rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile/profiles-resources.xml diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/profile/profiles-types.xml b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile/profiles-types.xml similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/profile/profiles-types.xml rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/profile/profiles-types.xml diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/account.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/account.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/account.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/account.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/activitydefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/activitydefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/activitydefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/activitydefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/adverseevent.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/adverseevent.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/adverseevent.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/adverseevent.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/allergyintolerance.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/allergyintolerance.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/allergyintolerance.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/allergyintolerance.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/appointment.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/appointment.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/appointment.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/appointment.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/appointmentresponse.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/appointmentresponse.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/appointmentresponse.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/appointmentresponse.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/auditevent.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/auditevent.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/auditevent.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/auditevent.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/basic.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/basic.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/basic.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/basic.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/binary.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/binary.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/binary.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/binary.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bmi.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bmi.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bmi.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bmi.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodyheight.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodyheight.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodyheight.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodyheight.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodylength.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodylength.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodylength.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodylength.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodysite.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodysite.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodysite.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodysite.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodystructure.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodystructure.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodystructure.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodystructure.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodytemp.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodytemp.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodytemp.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodytemp.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodyweight.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodyweight.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bodyweight.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bodyweight.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bp.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bp.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bp.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bp.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bundle.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bundle.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/bundle.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/bundle.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/capabilitystatement.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/capabilitystatement.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/capabilitystatement.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/capabilitystatement.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/careplan.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/careplan.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/careplan.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/careplan.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/careteam.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/careteam.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/careteam.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/careteam.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/catalog.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/catalog.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/catalog.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/catalog.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/chargeitem.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/chargeitem.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/chargeitem.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/chargeitem.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/cholesterol.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/cholesterol.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/cholesterol.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/cholesterol.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/claim.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/claim.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/claim.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/claim.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/claimresponse.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/claimresponse.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/claimresponse.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/claimresponse.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/clinicaldocument.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/clinicaldocument.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/clinicaldocument.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/clinicaldocument.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/clinicalimpression.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/clinicalimpression.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/clinicalimpression.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/clinicalimpression.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/codesystem.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/codesystem.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/codesystem.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/codesystem.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/communication.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/communication.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/communication.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/communication.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/communicationrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/communicationrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/communicationrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/communicationrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/compartmentdefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/compartmentdefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/compartmentdefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/compartmentdefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/composition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/composition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/composition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/composition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/conceptmap.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/conceptmap.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/conceptmap.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/conceptmap.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/condition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/condition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/condition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/condition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/consent.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/consent.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/consent.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/consent.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/consentdirective.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/consentdirective.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/consentdirective.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/consentdirective.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/contract.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/contract.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/contract.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/contract.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/coverage.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/coverage.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/coverage.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/coverage.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/dataelement.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/dataelement.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/dataelement.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/dataelement.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/detectedissue.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/detectedissue.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/detectedissue.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/detectedissue.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/device.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/device.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/device.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/device.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicecomponent.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicecomponent.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicecomponent.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicecomponent.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicemetric.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicemetric.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicemetric.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicemetric.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicemetricobservation.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicemetricobservation.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicemetricobservation.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicemetricobservation.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicerequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicerequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/devicerequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/devicerequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/deviceuserequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/deviceuserequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/deviceuserequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/deviceuserequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/deviceusestatement.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/deviceusestatement.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/deviceusestatement.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/deviceusestatement.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticreport-genetics.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticreport-genetics.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticreport-genetics.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticreport-genetics.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticreport.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticreport.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticreport.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticreport.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticrequest-genetics.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticrequest-genetics.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticrequest-genetics.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticrequest-genetics.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/diagnosticrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/diagnosticrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/documentmanifest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/documentmanifest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/documentmanifest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/documentmanifest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/documentreference.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/documentreference.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/documentreference.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/documentreference.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/elementdefinition-de.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/elementdefinition-de.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/elementdefinition-de.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/elementdefinition-de.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/eligibilityrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/eligibilityrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/eligibilityrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/eligibilityrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/eligibilityresponse.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/eligibilityresponse.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/eligibilityresponse.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/eligibilityresponse.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/encounter.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/encounter.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/encounter.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/encounter.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/endpoint.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/endpoint.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/endpoint.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/endpoint.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/enrollmentrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/enrollmentrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/enrollmentrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/enrollmentrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/enrollmentresponse.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/enrollmentresponse.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/enrollmentresponse.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/enrollmentresponse.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/episodeofcare.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/episodeofcare.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/episodeofcare.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/episodeofcare.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/eventdefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/eventdefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/eventdefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/eventdefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/expansionprofile.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/expansionprofile.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/expansionprofile.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/expansionprofile.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/explanationofbenefit.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/explanationofbenefit.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/explanationofbenefit.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/explanationofbenefit.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/familymemberhistory-genetic.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/familymemberhistory-genetic.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/familymemberhistory-genetic.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/familymemberhistory-genetic.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/familymemberhistory.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/familymemberhistory.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/familymemberhistory.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/familymemberhistory.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/fhir-invariants.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/fhir-invariants.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/fhir-invariants.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/fhir-invariants.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/fhir-single.xsd b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/fhir-single.xsd similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/fhir-single.xsd rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/fhir-single.xsd diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/fhir-xhtml.xsd b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/fhir-xhtml.xsd similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/fhir-xhtml.xsd rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/fhir-xhtml.xsd diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/flag.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/flag.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/flag.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/flag.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/goal.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/goal.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/goal.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/goal.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/graphdefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/graphdefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/graphdefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/graphdefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/group.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/group.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/group.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/group.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/guidanceresponse.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/guidanceresponse.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/guidanceresponse.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/guidanceresponse.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/hdlcholesterol.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/hdlcholesterol.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/hdlcholesterol.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/hdlcholesterol.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/headcircum.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/headcircum.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/headcircum.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/headcircum.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/healthcareservice.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/healthcareservice.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/healthcareservice.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/healthcareservice.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/heartrate.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/heartrate.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/heartrate.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/heartrate.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/hlaresult.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/hlaresult.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/hlaresult.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/hlaresult.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/imagingmanifest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/imagingmanifest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/imagingmanifest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/imagingmanifest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/imagingstudy.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/imagingstudy.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/imagingstudy.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/imagingstudy.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/immunization.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/immunization.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/immunization.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/immunization.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/immunizationrecommendation.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/immunizationrecommendation.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/immunizationrecommendation.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/immunizationrecommendation.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/implementationguide.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/implementationguide.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/implementationguide.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/implementationguide.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/ldlcholesterol.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/ldlcholesterol.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/ldlcholesterol.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/ldlcholesterol.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/library.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/library.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/library.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/library.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/linkage.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/linkage.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/linkage.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/linkage.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/lipidprofile.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/lipidprofile.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/lipidprofile.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/lipidprofile.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/list.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/list.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/list.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/list.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/location.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/location.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/location.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/location.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/mbp.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/mbp.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/mbp.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/mbp.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/measure.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/measure.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/measure.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/measure.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/measurereport.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/measurereport.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/measurereport.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/measurereport.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/media.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/media.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/media.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/media.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medication.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medication.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medication.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medication.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationadministration.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationadministration.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationadministration.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationadministration.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationdispense.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationdispense.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationdispense.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationdispense.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationstatement.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationstatement.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/medicationstatement.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/medicationstatement.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/messagedefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/messagedefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/messagedefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/messagedefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/messageheader.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/messageheader.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/messageheader.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/messageheader.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/namingsystem.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/namingsystem.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/namingsystem.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/namingsystem.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/nutritionorder.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/nutritionorder.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/nutritionorder.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/nutritionorder.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/nutritionrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/nutritionrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/nutritionrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/nutritionrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/observation-genetics.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/observation-genetics.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/observation-genetics.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/observation-genetics.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/observation.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/observation.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/observation.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/observation.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/observationforgenetics.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/observationforgenetics.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/observationforgenetics.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/observationforgenetics.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/operationdefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/operationdefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/operationdefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/operationdefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/operationoutcome.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/operationoutcome.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/operationoutcome.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/operationoutcome.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/orderforgenetics.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/orderforgenetics.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/orderforgenetics.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/orderforgenetics.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/organization.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/organization.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/organization.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/organization.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/oxygensat.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/oxygensat.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/oxygensat.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/oxygensat.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/patient.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/patient.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/patient.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/patient.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/paymentnotice.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/paymentnotice.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/paymentnotice.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/paymentnotice.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/paymentreconciliation.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/paymentreconciliation.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/paymentreconciliation.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/paymentreconciliation.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/person.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/person.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/person.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/person.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/plandefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/plandefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/plandefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/plandefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/practitioner.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/practitioner.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/practitioner.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/practitioner.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/practitionerrole.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/practitionerrole.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/practitionerrole.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/practitionerrole.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/procedure.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/procedure.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/procedure.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/procedure.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/procedurerequest-genetics.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/procedurerequest-genetics.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/procedurerequest-genetics.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/procedurerequest-genetics.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/procedurerequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/procedurerequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/procedurerequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/procedurerequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/processrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/processrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/processrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/processrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/processresponse.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/processresponse.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/processresponse.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/processresponse.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/provenance.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/provenance.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/provenance.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/provenance.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/questionnaire.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/questionnaire.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/questionnaire.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/questionnaire.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/questionnaireresponse.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/questionnaireresponse.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/questionnaireresponse.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/questionnaireresponse.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/referralrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/referralrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/referralrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/referralrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/relatedperson.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/relatedperson.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/relatedperson.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/relatedperson.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/reportforgenetics.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/reportforgenetics.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/reportforgenetics.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/reportforgenetics.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/requestgroup.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/requestgroup.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/requestgroup.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/requestgroup.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/researchstudy.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/researchstudy.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/researchstudy.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/researchstudy.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/researchsubject.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/researchsubject.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/researchsubject.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/researchsubject.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/resprate.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/resprate.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/resprate.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/resprate.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/riskassessment.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/riskassessment.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/riskassessment.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/riskassessment.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/schedule.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/schedule.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/schedule.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/schedule.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/searchparameter.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/searchparameter.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/searchparameter.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/searchparameter.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/sequence.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/sequence.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/sequence.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/sequence.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/servicedefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/servicedefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/servicedefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/servicedefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/shareablecodesystem.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/shareablecodesystem.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/shareablecodesystem.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/shareablecodesystem.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/shareablevalueset.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/shareablevalueset.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/shareablevalueset.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/shareablevalueset.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/slot.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/slot.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/slot.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/slot.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/specimen.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/specimen.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/specimen.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/specimen.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/structuredefinition.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/structuredefinition.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/structuredefinition.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/structuredefinition.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/structuremap.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/structuremap.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/structuremap.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/structuremap.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/subscription.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/subscription.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/subscription.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/subscription.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/substance.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/substance.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/substance.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/substance.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/supplydelivery.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/supplydelivery.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/supplydelivery.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/supplydelivery.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/supplyrequest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/supplyrequest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/supplyrequest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/supplyrequest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/task.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/task.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/task.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/task.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/testreport.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/testreport.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/testreport.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/testreport.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/testscript.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/testscript.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/testscript.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/testscript.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/triglyceride.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/triglyceride.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/triglyceride.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/triglyceride.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/valueset.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/valueset.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/valueset.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/valueset.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/visionprescription.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/visionprescription.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/visionprescription.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/visionprescription.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/vitalsigns.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/vitalsigns.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/vitalsigns.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/vitalsigns.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/vitalspanel.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/vitalspanel.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/vitalspanel.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/vitalspanel.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/xdsdocumentmanifest.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/xdsdocumentmanifest.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/xdsdocumentmanifest.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/xdsdocumentmanifest.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/xdsdocumentreference.sch b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/xdsdocumentreference.sch similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/xdsdocumentreference.sch rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/xdsdocumentreference.sch diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/xml.xsd b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/xml.xsd similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/schema/xml.xsd rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/schema/xml.xsd diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/valueset/v2-tables.xml b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/v2-tables.xml similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/valueset/v2-tables.xml rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/v2-tables.xml diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/valueset/v3-codesystems.xml b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/v3-codesystems.xml similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/valueset/v3-codesystems.xml rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/v3-codesystems.xml diff --git a/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/valueset/valuesets.xml b/hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/valuesets.xml similarity index 100% rename from hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/instance/model/r4/valueset/valuesets.xml rename to hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/valuesets.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index 494c07fffa9..6c31b4095ba 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -99,18 +99,80 @@ true + ca.uhn.hapi.fhir hapi-fhir-converter ${project.version} test + + ca.uhn.hapi.fhir + hapi-fhir-server + ${project.version} + test + + + ca.uhn.hapi.fhir + hapi-fhir-client + ${project.version} + test + ch.qos.logback logback-classic test - + + javax.servlet + javax.servlet-api + test + + + com.google.guava + guava + test + + + org.eclipse.jetty + jetty-servlets + test + + + org.eclipse.jetty + jetty-servlet + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-util + test + + + org.eclipse.jetty + jetty-webapp + test + + + org.eclipse.jetty + jetty-http + test + + + com.phloc + phloc-schematron + test + + + com.phloc + phloc-commons + test + diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/BaseValidatorBridge.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/BaseValidatorBridge.java similarity index 100% rename from hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/BaseValidatorBridge.java rename to hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/BaseValidatorBridge.java diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java similarity index 99% rename from hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java rename to hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java index 75a4d4ea717..852ee862377 100644 --- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java @@ -8,10 +8,12 @@ import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.lang3.Validate; import org.hl7.fhir.exceptions.PathEngineException; +import org.hl7.fhir.r4.hapi.ctx.*; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext; import org.hl7.fhir.r4.utils.IResourceValidator.BestPracticeWarningLevel; import org.hl7.fhir.r4.utils.IResourceValidator.IdStatus; +import org.hl7.fhir.r4.validation.InstanceValidator; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.w3c.dom.Document; diff --git a/hapi-fhir-validation/src/test/java/ca/uhn/fhir/rest/server/RequestValidatingInterceptorR4Test.java b/hapi-fhir-validation/src/test/java/ca/uhn/fhir/rest/server/RequestValidatingInterceptorR4Test.java new file mode 100644 index 00000000000..7c99880afcc --- /dev/null +++ b/hapi-fhir-validation/src/test/java/ca/uhn/fhir/rest/server/RequestValidatingInterceptorR4Test.java @@ -0,0 +1,512 @@ +package ca.uhn.fhir.rest.server; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.*; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator; +import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender; +import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; +import org.mockito.Mockito; + +import com.google.common.base.Charsets; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; +import ca.uhn.fhir.validation.*; + +public class RequestValidatingInterceptorR4Test { + private static CloseableHttpClient ourClient; + + private static FhirContext ourCtx = FhirContext.forR4(); + private static boolean ourLastRequestWasSearch; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RequestValidatingInterceptorR4Test.class); + private static int ourPort; + + private static Server ourServer; + + private static RestfulServer ourServlet; + + private RequestValidatingInterceptor myInterceptor; + + @Before + public void before() { + ourLastRequestWasSearch = false; + while (ourServlet.getInterceptors().size() > 0) { + ourServlet.unregisterInterceptor(ourServlet.getInterceptors().get(0)); + } + + myInterceptor = new RequestValidatingInterceptor(); + // myInterceptor.setFailOnSeverity(ResultSeverityEnum.ERROR); + // myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + // myInterceptor.setResponseHeaderName("X-RESP"); + // myInterceptor.setResponseHeaderValue(RequestValidatingInterceptor.DEFAULT_RESPONSE_HEADER_VALUE); + + ourServlet.registerInterceptor(myInterceptor); + } + + @Test + public void testCreateJsonInvalidNoFailure() throws Exception { + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + String encoded = ourCtx.newJsonParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_JSON, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Request-Validation")); + assertThat(responseContent, not(containsString(""))); + } + + @Test + public void testCreateJsonInvalidNoValidatorsSpecified() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + String encoded = ourCtx.newJsonParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_JSON, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(422, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Request-Validation")); + assertThat(responseContent, containsString("\"severity\":\"error\"")); + } + + @Test + public void testCreateJsonValidNoValidatorsSpecified() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + String encoded = ourCtx.newJsonParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_JSON, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation"))); + } + + @Test + public void testCreateJsonValidNoValidatorsSpecifiedDefaultMessage() throws Exception { + myInterceptor.setResponseHeaderValueNoIssues("NO ISSUES"); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + String encoded = ourCtx.newJsonParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_JSON, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), (containsString("X-FHIR-Request-Validation: NO ISSUES"))); + } + + @Test + public void testCreateXmlInvalidInstanceValidator() throws Exception { + IValidatorModule module = new FhirInstanceValidator(); + myInterceptor.addValidatorModule(module); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(422, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Request-Validation")); + } + + @Test + public void testCreateXmlInvalidNoValidatorsSpecified() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(422, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Request-Validation")); + } + + @Test + public void testCreateXmlInvalidNoValidatorsSpecifiedOutcomeHeader() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Request-Validation: {\"resourceType\":\"OperationOutcome")); + } + + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionNpeNoIgnore() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(false); + + Mockito.doThrow(NullPointerException.class).when(module).validateResource(Mockito.any(IValidationContext.class)); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(500, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("")); + } + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionNpeIgnore() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(true); + + Mockito.doThrow(NullPointerException.class).when(module).validateResource(Mockito.any(IValidationContext.class)); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation"))); + } + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionIseNoIgnore() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(false); + + Mockito.doThrow(new InternalErrorException("FOO")).when(module).validateResource(Mockito.any(IValidationContext.class)); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(500, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("")); + } + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionIseIgnore() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(true); + + Mockito.doThrow(InternalErrorException.class).when(module).validateResource(Mockito.any(IValidationContext.class)); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation"))); + } + + @Test + public void testCreateXmlValidNoValidatorsSpecified() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + String encoded = ourCtx.newXmlParser().encodeResourceToString(patient); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient"); + httpPost.setEntity(new StringEntity(encoded, ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(201, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation"))); + } + + /** + * Test for #345 + */ + @Test + public void testDelete() throws Exception { + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + HttpDelete httpDelete = new HttpDelete("http://localhost:" + ourPort + "/Patient/123"); + + CloseableHttpResponse status = ourClient.execute(httpDelete); + try { + ourLog.info("Response was:\n{}", status); + + assertEquals(204, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation"))); + } finally { + IOUtils.closeQuietly(status); + } + } + + @Test + public void testFetchMetadata() throws Exception { + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata"); + + // This header caused a crash + httpGet.addHeader("Content-Type", "application/xml+fhir"); + + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("CapabilityStatement")); + } + + @Test + public void testSearch() throws Exception { + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation"))); + assertEquals(true, ourLastRequestWasSearch); + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + PatientProvider patientProvider = new PatientProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + ourServlet = new RestfulServer(ourCtx); + ourServlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(ourServlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class PatientProvider implements IResourceProvider { + + @Create() + public MethodOutcome createPatient(@ResourceParam Patient thePatient, @IdParam IdType theIdParam) { + return new MethodOutcome(new IdDt("Patient/001/_history/002")); + } + + @Delete + public MethodOutcome delete(@IdParam IdType theId) { + return new MethodOutcome(theId.withVersion("2")); + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Search + public List search(@OptionalParam(name = "foo") StringParam theString) { + ourLastRequestWasSearch = true; + return new ArrayList(); + } + + } + +} diff --git a/hapi-fhir-validation/src/test/java/ca/uhn/fhir/rest/server/ResponseValidatingInterceptorR4Test.java b/hapi-fhir-validation/src/test/java/ca/uhn/fhir/rest/server/ResponseValidatingInterceptorR4Test.java new file mode 100644 index 00000000000..c5cf604442c --- /dev/null +++ b/hapi-fhir-validation/src/test/java/ca/uhn/fhir/rest/server/ResponseValidatingInterceptorR4Test.java @@ -0,0 +1,518 @@ +package ca.uhn.fhir.rest.server; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.*; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator; +import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender; +import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Patient; +import org.junit.*; +import org.mockito.Mockito; + +import com.google.common.base.Charsets; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.RestOperationTypeEnum; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor; +import ca.uhn.fhir.util.PortUtil; +import ca.uhn.fhir.util.TestUtil; +import ca.uhn.fhir.validation.*; + +public class ResponseValidatingInterceptorR4Test { + public static IBaseResource myReturnResource; + + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx = FhirContext.forR4(); + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResponseValidatingInterceptorR4Test.class); + private static int ourPort; + private static Server ourServer; + private static RestfulServer ourServlet; + private ResponseValidatingInterceptor myInterceptor; + + @Before + public void before() { + myReturnResource = null; + while (ourServlet.getInterceptors().size() > 0) { + ourServlet.unregisterInterceptor(ourServlet.getInterceptors().get(0)); + } + + myInterceptor = new ResponseValidatingInterceptor(); + // myInterceptor.setFailOnSeverity(ResultSeverityEnum.ERROR); + // myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + // myInterceptor.setResponseHeaderName("X-RESP"); + // myInterceptor.setResponseHeaderValue(RequestValidatingInterceptor.DEFAULT_RESPONSE_HEADER_VALUE); + + ourServlet.registerInterceptor(myInterceptor); + } + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionNpeNoIgnore() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(false); + + Mockito.doThrow(NullPointerException.class).when(module).validateResource(Mockito.any(IValidationContext.class)); + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(500, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("")); + } + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionNpeIgnore() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(true); + + Mockito.doThrow(NullPointerException.class).when(module).validateResource(Mockito.any(IValidationContext.class)); + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation"))); + } + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionIseNoIgnore() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(false); + + Mockito.doThrow(new InternalErrorException("FOO")).when(module).validateResource(Mockito.any(IValidationContext.class)); + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(500, status.getStatusLine().getStatusCode()); + assertThat(responseContent, containsString("")); + } + + @SuppressWarnings("unchecked") + @Test + public void testInterceptorExceptionIseIgnore() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + myInterceptor.setAddResponseHeaderOnSeverity(null); + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + IValidatorModule module = mock(IValidatorModule.class); + myInterceptor.addValidatorModule(module); + myInterceptor.setIgnoreValidatorExceptions(true); + + Mockito.doThrow(InternalErrorException.class).when(module).validateResource(Mockito.any(IValidationContext.class)); + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation"))); + } + + + /** + * Test for #345 + */ + @Test + public void testDelete() throws Exception { + myInterceptor.setFailOnSeverity(null); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + HttpDelete httpDelete = new HttpDelete("http://localhost:" + ourPort + "/Patient/123"); + + CloseableHttpResponse status = ourClient.execute(httpDelete); + try { + ourLog.info("Response was:\n{}", status); + + assertEquals(204, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation"))); + } finally { + IOUtils.closeQuietly(status); + } + } + + + @Test + public void testLongHeaderTruncated() throws Exception { + IValidatorModule module = new FhirInstanceValidator(); + myInterceptor.addValidatorModule(module); + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + myInterceptor.setFailOnSeverity(null); + + Patient patient = new Patient(); + for (int i = 0; i < 1000; i++) { + patient.addContact().setGender(AdministrativeGender.MALE); + } + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + { + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), endsWith("...")); + assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), startsWith("{\"resourceType\":\"OperationOutcome\"")); + } + { + myInterceptor.setMaximumHeaderLength(100); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), endsWith("...")); + assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), startsWith("{\"resourceType\":\"OperationOutcome\"")); + } + } + + @Test + public void testOperationOutcome() throws Exception { + myInterceptor.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), (containsString( + "X-FHIR-Response-Validation: {\"resourceType\":\"OperationOutcome\",\"issue\":[{\"severity\":\"information\",\"code\":\"informational\",\"diagnostics\":\"No issues detected\"}]}"))); + } + + /** + * Ignored until #264 is fixed + */ + @Test + @Ignore + public void testSearchJsonInvalidNoValidatorsSpecified() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(422, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Response-Validation")); + assertThat(responseContent, containsString("")); + } + + @Test + public void testSearchJsonValidNoValidatorsSpecified() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation"))); + } + + @Test + public void testSearchJsonValidNoValidatorsSpecifiedDefaultMessage() throws Exception { + myInterceptor.setResponseHeaderValueNoIssues("NO ISSUES"); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), (containsString("X-FHIR-Response-Validation: NO ISSUES"))); + } + + @Test + public void testSearchXmlInvalidInstanceValidator() throws Exception { + IValidatorModule module = new FhirInstanceValidator(); + myInterceptor.addValidatorModule(module); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(422, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Response-Validation")); + } + + /** + * Ignored until #264 is fixed + */ + @Test + @Ignore + public void testSearchXmlInvalidNoValidatorsSpecified() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + patient.addContact().addRelationship().setText("FOO"); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(422, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), containsString("X-FHIR-Response-Validation")); + } + + @Test + public void testSearchXmlValidNoValidatorsSpecified() throws Exception { + Patient patient = new Patient(); + patient.addIdentifier().setValue("002"); + patient.setGender(AdministrativeGender.MALE); + myReturnResource = patient; + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient?foo=bar"); + + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.trace("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation"))); + } + + @Test + public void testSkipEnabled() throws Exception { + IValidatorModule module = new FhirInstanceValidator(); + myInterceptor.addValidatorModule(module); + myInterceptor.addExcludeOperationType(RestOperationTypeEnum.METADATA); + myInterceptor.setResponseHeaderValueNoIssues("No issues"); + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/metadata"); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation"))); + } + + @Test + public void testSkipNotEnabled() throws Exception { + IValidatorModule module = new FhirInstanceValidator(); + myInterceptor.addValidatorModule(module); + myInterceptor.setResponseHeaderValueNoIssues("No issues"); + myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION); + + HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/metadata?_pretty=true"); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent(), Charsets.UTF_8); + ourLog.info(responseContent); + IOUtils.closeQuietly(status.getEntity().getContent()); + + ourLog.info("Response was:\n{}", status); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertThat(status.toString(), (containsString("X-FHIR-Response-Validation"))); + } + + @AfterClass + public static void afterClassClearContext() throws Exception { + ourServer.stop(); + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = PortUtil.findFreePort(); + ourServer = new Server(ourPort); + + PatientProvider patientProvider = new PatientProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + ourServlet = new RestfulServer(ourCtx); + ourServlet.setResourceProviders(patientProvider); + ServletHolder servletHolder = new ServletHolder(ourServlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class PatientProvider implements IResourceProvider { + + @Delete + public MethodOutcome delete(@IdParam IdType theId) { + return new MethodOutcome(theId.withVersion("2")); + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Search + public ArrayList search(@OptionalParam(name = "foo") StringParam theString) { + ArrayList retVal = new ArrayList(); + myReturnResource.setId("1"); + retVal.add(myReturnResource); + return retVal; + } + + } + +} diff --git a/hapi-fhir-validation/src/test/resources/logback-test.xml b/hapi-fhir-validation/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..e5cbbb9c22e --- /dev/null +++ b/hapi-fhir-validation/src/test/resources/logback-test.xml @@ -0,0 +1,30 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] - %msg%n + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 3bb44982293..e5e7eb157e6 100644 --- a/pom.xml +++ b/pom.xml @@ -275,6 +275,7 @@ vadi2 Vadim Peretokin + Furore Informatica lawley @@ -341,6 +342,10 @@ eug48 Eugene Lubarsky + + SarenCurrie + Saren Currie + diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 59777ec89b1..ff774d3a3bf 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -85,10 +85,14 @@ generated. This should not affect most users. - FIx issue in SubscriptionInterceptor that caused interceptor to only + Fix issue in SubscriptionInterceptor that caused interceptor to only actually notify listeners of the first 10 subscriptions. Thanks to Jeff Chung for the pull request! + + Fix potential ConcurrentModificationException when adding subscriptions while + running under heavy load. Thanks to Jeff Chung for the pull request! + JPA search now uses hibernate ScrollableResults instead of plain JPA List. This should improve performance over large search results. @@ -191,6 +195,43 @@ StructureMapUtilities. Thanks to Travis Lukach for reporting and providing a test case! + + Add link to DSTU3 JavaDocs from documentation index. Thanks + to Vadim Peretokin for the pull request! + + + Fix a typo in the documentation. Thanks to Saren Currie + for the pull request! + + + Add a command line flag to the CLI tool to allow configuration of the + server search result cache timeout period. Thanks to Eugene Lubarsky + for the pull request! + + + Correct an issue with the model classes for STU3 where any classes + containing the @ChildOrder annotation (basically the conformance + resources) will not correctly set the order if any of the + elements are a choice type (i.e. named "foo[x]"). Thanks to + GitHub user @CarthageKing for the pull request! + + + Fix potential deadlock in stale search deleting task in JPA server, as well + as potential deadlock when executing transactions containing nested + searches when operating under extremely heavy load. + + + JPA server transaction operations now put OperationOutcome resources resulting + from actions in + Bundle.entry.response.outcome]]> + instead of the previous + Bundle.entry.resource]]> + + + An issue was corrected where search parameters containing negative numbers + were sometimes treated as positive numbers when processing the search. Thanks + to Keith Boone for reporting and suggesting a fix! + diff --git a/src/site/xdoc/docindex.xml b/src/site/xdoc/docindex.xml index cb7d6a7bf48..49cefb6481c 100644 --- a/src/site/xdoc/docindex.xml +++ b/src/site/xdoc/docindex.xml @@ -69,6 +69,7 @@
  • Core API
  • Model API (DSTU1)
  • Model API (DSTU2)
  • +
  • Model API (STU3)
  • JPA Server API