diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index 2925cddee83..9df4f52f5df 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index 60f23bd7bcc..a03a6465c2a 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index 00ce73745e2..912fe4efd95 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java index 78d6e18e54c..39c83e204b8 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; +import ca.uhn.fhir.model.primitive.IdDt; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseBackboneElement; @@ -194,6 +195,45 @@ public class BundleBuilder { return new CreateBuilder(request); } + /** + * Adds an entry containing a delete (DELETE) request. + * Also sets the Bundle.type value to "transaction" if it is not already set. + * + * Note that the resource is only used to extract its ID and type, and the body of the resource is not included in the entry, + * + * @param theResource The resource to delete. + */ + public void addTransactionDeleteEntry(IBaseResource theResource) { + String resourceType = myContext.getResourceType(theResource); + String idPart = theResource.getIdElement().toUnqualifiedVersionless().getIdPart(); + addTransactionDeleteEntry(resourceType, idPart); + } + + /** + * Adds an entry containing a delete (DELETE) request. + * Also sets the Bundle.type value to "transaction" if it is not already set. + * + * @param theResourceType The type resource to delete. + * @param theIdPart the ID of the resource to delete. + */ + public void addTransactionDeleteEntry(String theResourceType, String theIdPart) { + setBundleField("type", "transaction"); + IBase request = addEntryAndReturnRequest(); + IdDt idDt = new IdDt(theIdPart); + + // Bundle.entry.request.url + IPrimitiveType url = (IPrimitiveType) myContext.getElementDefinition("uri").newInstance(); + url.setValueAsString(idDt.toUnqualifiedVersionless().withResourceType(theResourceType).getValue()); + myEntryRequestUrlChild.getMutator().setValue(request, url); + + // Bundle.entry.request.method + IPrimitiveType method = (IPrimitiveType) myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments()); + method.setValueAsString("DELETE"); + myEntryRequestMethodChild.getMutator().setValue(request, method); + } + + + /** * Adds an entry for a Collection bundle type */ @@ -251,6 +291,16 @@ public class BundleBuilder { return request; } + public IBase addEntryAndReturnRequest() { + IBase entry = addEntry(); + + // Bundle.entry.request + IBase request = myEntryRequestDef.newInstance(); + myEntryRequestChild.getMutator().setValue(entry, request); + return request; + + } + public IBaseBundle getBundle() { return myBundle; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TerserUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TerserUtil.java index fc7e8fd0ced..e6de9a87c0d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TerserUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TerserUtil.java @@ -25,6 +25,7 @@ import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; +import org.apache.commons.lang3.tuple.Triple; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.Logger; @@ -48,9 +49,15 @@ public final class TerserUtil { private static final String EQUALS_DEEP = "equalsDeep"; + /** + * Exclude for id, identifier and meta fields of a resource. + */ public static final Collection IDS_AND_META_EXCLUDES = Collections.unmodifiableSet(Stream.of("id", "identifier", "meta").collect(Collectors.toSet())); + /** + * Exclusion predicate for id, identifier, meta fields. + */ public static final Predicate EXCLUDE_IDS_AND_META = new Predicate() { @Override public boolean test(String s) { @@ -58,6 +65,25 @@ public final class TerserUtil { } }; + /** + * Exclusion predicate for id/identifier, meta and fields with empty values. This ensures that source / target resources, + * empty source fields will not results in erasure of target fields. + */ + public static final Predicate> EXCLUDE_IDS_META_AND_EMPTY = new Predicate>() { + @Override + public boolean test(Triple theTriple) { + if (!EXCLUDE_IDS_AND_META.test(theTriple.getLeft().getElementName())) { + return false; + } + BaseRuntimeChildDefinition childDefinition = theTriple.getLeft(); + boolean isSourceFieldEmpty = childDefinition.getAccessor().getValues(theTriple.getMiddle()).isEmpty(); + return !isSourceFieldEmpty; + } + }; + + /** + * Exclusion predicate for keeping all fields. + */ public static final Predicate INCLUDE_ALL = new Predicate() { @Override public boolean test(String s) { @@ -235,24 +261,35 @@ public final class TerserUtil { } /** - * Replaces all fields that test positive by the given inclusion strategy. theTo will contain a copy of the + * Replaces all fields that have matching field names by the given inclusion strategy. theTo will contain a copy of the * values from theFrom instance. * - * @param theFhirContext Context holding resource definition - * @param theFrom The resource to merge the fields from - * @param theTo The resource to merge the fields into - * @param inclusionStrategy Inclusion strategy that checks if a given field should be replaced by checking {@link Predicate#test(Object)} + * @param theFhirContext Context holding resource definition + * @param theFrom The resource to merge the fields from + * @param theTo The resource to merge the fields into + * @param theFieldNameInclusion Inclusion strategy that checks if a given field should be replaced */ - public static void replaceFields(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, Predicate inclusionStrategy) { - FhirTerser terser = theFhirContext.newTerser(); + public static void replaceFields(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, Predicate theFieldNameInclusion) { + Predicate> predicate + = (t) -> theFieldNameInclusion.test(t.getLeft().getElementName()); + replaceFieldsByPredicate(theFhirContext, theFrom, theTo, predicate); + } + /** + * Replaces fields on theTo resource that test positive by the given predicate. theTo will contain a copy of the + * values from theFrom for which predicate tests positive. Please note that composite fields will be replaced fully. + * + * @param theFhirContext Context holding resource definition + * @param theFrom The resource to merge the fields from + * @param theTo The resource to merge the fields into + * @param thePredicate Predicate that checks if a given field should be replaced + */ + public static void replaceFieldsByPredicate(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, Predicate> thePredicate) { RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom); for (BaseRuntimeChildDefinition childDefinition : definition.getChildrenAndExtension()) { - if (!inclusionStrategy.test(childDefinition.getElementName())) { - continue; + if (thePredicate.test(Triple.of(childDefinition, theFrom, theTo))) { + replaceField(theFrom, theTo, childDefinition); } - - replaceField(theFrom, theTo, childDefinition); } } @@ -277,14 +314,11 @@ public final class TerserUtil { * @param theTo The resource to replace the field on */ public static void replaceField(FhirContext theFhirContext, String theFieldName, IBaseResource theFrom, IBaseResource theTo) { - replaceField(theFhirContext, theFhirContext.newTerser(), theFieldName, theFrom, theTo); - } - - /** - * @deprecated Use {@link #replaceField(FhirContext, String, IBaseResource, IBaseResource)} instead - */ - public static void replaceField(FhirContext theFhirContext, FhirTerser theTerser, String theFieldName, IBaseResource theFrom, IBaseResource theTo) { - replaceField(theFrom, theTo, getBaseRuntimeChildDefinition(theFhirContext, theFieldName, theFrom)); + RuntimeResourceDefinition definition = theFhirContext.getResourceDefinition(theFrom); + if (definition == null) { + throw new IllegalArgumentException(String.format("Field %s does not exist in %s", theFieldName, theFrom)); + } + replaceField(theFrom, theTo, theFhirContext.getResourceDefinition(theFrom).getChildByName(theFieldName)); } /** @@ -301,7 +335,7 @@ public final class TerserUtil { /** * Sets the provided field with the given values. This method will add to the collection of existing field values - * in case of multiple cardinality. Use {@link #clearField(FhirContext, FhirTerser, String, IBaseResource, IBase...)} + * in case of multiple cardinality. Use {@link #clearField(FhirContext, String, IBaseResource)} * to remove values before setting * * @param theFhirContext Context holding resource definition @@ -315,7 +349,7 @@ public final class TerserUtil { /** * Sets the provided field with the given values. This method will add to the collection of existing field values - * in case of multiple cardinality. Use {@link #clearField(FhirContext, FhirTerser, String, IBaseResource, IBase...)} + * in case of multiple cardinality. Use {@link #clearField(FhirContext, String, IBaseResource)} * to remove values before setting * * @param theFhirContext Context holding resource definition @@ -370,10 +404,26 @@ public final class TerserUtil { setFieldByFhirPath(theFhirContext.newTerser(), theFhirPath, theResource, theValue); } + /** + * Returns field values ant the specified FHIR path from the resource. + * + * @param theFhirContext Context holding resource definition + * @param theFhirPath The FHIR path to get the field from + * @param theResource The resource from which the value should be retrieved + * @return Returns the list of field values at the given FHIR path + */ public static List getFieldByFhirPath(FhirContext theFhirContext, String theFhirPath, IBase theResource) { return theFhirContext.newTerser().getValues(theResource, theFhirPath, false, false); } + /** + * Returns the first available field value at the specified FHIR path from the resource. + * + * @param theFhirContext Context holding resource definition + * @param theFhirPath The FHIR path to get the field from + * @param theResource The resource from which the value should be retrieved + * @return Returns the first available value or null if no values can be retrieved + */ public static IBase getFirstFieldByFhirPath(FhirContext theFhirContext, String theFhirPath, IBase theResource) { List values = getFieldByFhirPath(theFhirContext, theFhirPath, theResource); if (values == null || values.isEmpty()) { diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/validation/PlaceholderTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/validation/PlaceholderTest.java index f757cc2b801..5d5b2820135 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/validation/PlaceholderTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/validation/PlaceholderTest.java @@ -11,5 +11,4 @@ public class PlaceholderTest { public void testPass() { // nothing } - } diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index d3c726265b4..fdb411e91dc 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -3,14 +3,14 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT pom HAPI FHIR BOM ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml index 2816ae6159e..92bafa40399 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java index b2b9cb837c3..2e511c26433 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java +++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java @@ -31,6 +31,7 @@ import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.time.DateUtils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -70,6 +71,9 @@ public abstract class BaseCommand implements Comparable { protected static final String VERBOSE_LOGGING_PARAM = "l"; protected static final String VERBOSE_LOGGING_PARAM_LONGOPT = "logging"; protected static final String VERBOSE_LOGGING_PARAM_DESC = "If specified, verbose logging will be used."; + protected static final int DEFAULT_THREAD_COUNT = 10; + protected static final String THREAD_COUNT = "thread-count"; + // TODO: Don't use qualified names for loggers in HAPI CLI. private static final Logger ourLog = LoggerFactory.getLogger(BaseCommand.class); protected FhirContext myFhirCtx; @@ -87,6 +91,11 @@ public abstract class BaseCommand implements Comparable { addOptionalOption(theOptions, null, BEARER_TOKEN_PARAM_LONGOPT, BEARER_TOKEN_PARAM_NAME, BEARER_TOKEN_PARAM_DESC); } + protected void addThreadCountOption(Options theOptions) { + addOptionalOption(theOptions, null, THREAD_COUNT, "count", "If specified, this argument specifies the number of worker threads used (default is " + DEFAULT_THREAD_COUNT + ")"); + } + + protected String promptUser(String thePrompt) throws ParseException { System.out.print(ansi().bold().fgBrightDefault()); System.out.print(thePrompt); @@ -309,6 +318,12 @@ public abstract class BaseCommand implements Comparable { return getFhirContext().getResourceDefinition("Bundle").getImplementingClass(IBaseBundle.class); } + protected int getThreadCount(CommandLine theCommandLine) throws ParseException { + Integer parallelismThreadCount = getAndParsePositiveIntegerParam(theCommandLine, THREAD_COUNT); + parallelismThreadCount = ObjectUtils.defaultIfNull(parallelismThreadCount, DEFAULT_THREAD_COUNT); + return parallelismThreadCount.intValue(); + } + public abstract String getCommandDescription(); public abstract String getCommandName(); diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml index 7d9dc89fe6c..0c0e9694712 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir-cli - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml index 1055a8ed4ea..23fdc156c0e 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../../hapi-deployable-pom diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index 8784078d56b..ae67b1dad2f 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index cef760eeff8..52fed03fb71 100644 --- a/hapi-fhir-client-okhttp/pom.xml +++ b/hapi-fhir-client-okhttp/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index e7ac14275c6..f407f56be2d 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index 2ec2f22795c..a988e2f45c5 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index 24b559ea001..8ea8d57f03b 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index 40519292d48..2fcd0c94674 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -78,13 +78,13 @@ ca.uhn.hapi.fhir hapi-fhir-structures-dstu2 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT compile ca.uhn.hapi.fhir hapi-fhir-jpaserver-subscription - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT compile @@ -101,7 +101,7 @@ ca.uhn.hapi.fhir hapi-fhir-testpage-overlay - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT classes diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2515-mdm-survivorship-rules-application.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2515-mdm-survivorship-rules-application.yaml new file mode 100644 index 00000000000..f8e96a9f02e --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_4_0/2515-mdm-survivorship-rules-application.yaml @@ -0,0 +1,4 @@ +--- +type: fix +issue: 2515 +title: "Fixed issues with application of survivorship rules when matching golden record to a single resource" diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index 43dd8b85ed7..1d22f0b5e4a 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index 073ecc3dbf0..b2004c3ad14 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-example/pom.xml b/hapi-fhir-jaxrsserver-example/pom.xml index cce18f1d9c1..c3417a5963f 100644 --- a/hapi-fhir-jaxrsserver-example/pom.xml +++ b/hapi-fhir-jaxrsserver-example/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-jpaserver-api/pom.xml b/hapi-fhir-jpaserver-api/pom.xml index ac534aaccba..fa591624b35 100644 --- a/hapi-fhir-jpaserver-api/pom.xml +++ b/hapi-fhir-jpaserver-api/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index eedfef43910..3fed26d92f7 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-batch/pom.xml b/hapi-fhir-jpaserver-batch/pom.xml index a08e196fe26..6b49017689b 100644 --- a/hapi-fhir-jpaserver-batch/pom.xml +++ b/hapi-fhir-jpaserver-batch/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-cql/pom.xml b/hapi-fhir-jpaserver-cql/pom.xml index 20069c8fa7e..9be25f3da9e 100644 --- a/hapi-fhir-jpaserver-cql/pom.xml +++ b/hapi-fhir-jpaserver-cql/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -144,13 +144,13 @@ ca.uhn.hapi.fhir hapi-fhir-test-utilities - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT test ca.uhn.hapi.fhir hapi-fhir-jpaserver-test-utilities - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT test diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index 3295a49c94a..29d7f7a9503 100644 --- a/hapi-fhir-jpaserver-mdm/pom.xml +++ b/hapi-fhir-jpaserver-mdm/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -55,13 +55,13 @@ ca.uhn.hapi.fhir hapi-fhir-test-utilities - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT test ca.uhn.hapi.fhir hapi-fhir-jpaserver-test-utilities - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT test diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java index fae7c2da3d1..c24d28289d9 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/GoldenResourceMergerSvcImpl.java @@ -31,7 +31,6 @@ import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.util.GoldenResourceHelper; import ca.uhn.fhir.mdm.util.MdmResourceUtil; -import ca.uhn.fhir.mdm.util.TerserUtil; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import org.hl7.fhir.instance.model.api.IAnyResource; import org.slf4j.Logger; diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java index c4977891444..94db6849073 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmEidUpdateService.java @@ -134,6 +134,11 @@ public class MdmEidUpdateService { ourLog.debug(theMessage); } + public void applySurvivorshipRulesAndSaveGoldenResource(IAnyResource theTargetResource, IAnyResource theGoldenResource, MdmTransactionContext theMdmTransactionContext) { + myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(theTargetResource, theGoldenResource, theMdmTransactionContext); + myMdmResourceDaoSvc.upsertGoldenResource(theGoldenResource, theMdmTransactionContext.getResourceType()); + } + /** * Data class to hold context surrounding an update operation for an MDM target. */ @@ -162,7 +167,7 @@ public class MdmEidUpdateService { if (theExistingMatchLink.isPresent()) { MdmLink mdmLink = theExistingMatchLink.get(); Long existingGoldenResourcePid = mdmLink.getGoldenResourcePid(); - myExistingGoldenResource = myMdmResourceDaoSvc.readGoldenResourceByPid(new ResourcePersistentId(existingGoldenResourcePid), resourceType); + myExistingGoldenResource = myMdmResourceDaoSvc.readGoldenResourceByPid(new ResourcePersistentId(existingGoldenResourcePid), resourceType); myRemainsMatchedToSameGoldenResource = candidateIsSameAsMdmLinkGoldenResource(mdmLink, theMatchedGoldenResourceCandidate); } else { myRemainsMatchedToSameGoldenResource = false; diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java index 5cac2826956..fdd04914646 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvc.java @@ -46,6 +46,7 @@ import java.util.List; */ @Service public class MdmMatchLinkSvc { + private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); @Autowired @@ -62,7 +63,7 @@ public class MdmMatchLinkSvc { * or create one if one does not exist. Performs matching based on rules defined in mdm-rules.json. * Does nothing if resource is determined to be not managed by MDM. * - * @param theResource the incoming MDM source, which can be any supported MDM type. + * @param theResource the incoming MDM source, which can be any supported MDM type. * @param theMdmTransactionContext * @return an {@link TransactionLogMessages} which contains all informational messages related to MDM processing of this resource. */ @@ -130,20 +131,21 @@ public class MdmMatchLinkSvc { myMdmLinkSvc.updateLink(newGoldenResource, theResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } - private void handleMdmCreate(IAnyResource theSourceResource, MatchedGoldenResourceCandidate theGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { + private void handleMdmCreate(IAnyResource theTargetResource, MatchedGoldenResourceCandidate theGoldenResourceCandidate, MdmTransactionContext theMdmTransactionContext) { log(theMdmTransactionContext, "MDM has narrowed down to one candidate for matching."); - IAnyResource golenResource = myMdmGoldenResourceFindingSvc.getGoldenResourceFromMatchedGoldenResourceCandidate(theGoldenResourceCandidate, theMdmTransactionContext.getResourceType()); + IAnyResource goldenResource = myMdmGoldenResourceFindingSvc.getGoldenResourceFromMatchedGoldenResourceCandidate(theGoldenResourceCandidate, theMdmTransactionContext.getResourceType()); - if (myGoldenResourceHelper.isPotentialDuplicate(golenResource, theSourceResource)) { + if (myGoldenResourceHelper.isPotentialDuplicate(goldenResource, theTargetResource)) { log(theMdmTransactionContext, "Duplicate detected based on the fact that both resources have different external EIDs."); - IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theSourceResource, theMdmTransactionContext); - myMdmLinkSvc.updateLink(newGoldenResource, theSourceResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); - myMdmLinkSvc.updateLink(newGoldenResource, golenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); + IAnyResource newGoldenResource = myGoldenResourceHelper.createGoldenResourceFromMdmSourceResource(theTargetResource, theMdmTransactionContext); + myMdmLinkSvc.updateLink(newGoldenResource, theTargetResource, MdmMatchOutcome.NEW_GOLDEN_RESOURCE_MATCH, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); + myMdmLinkSvc.updateLink(newGoldenResource, goldenResource, MdmMatchOutcome.POSSIBLE_DUPLICATE, MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } else { if (theGoldenResourceCandidate.isMatch()) { - myGoldenResourceHelper.handleExternalEidAddition(golenResource, theSourceResource, theMdmTransactionContext); + myGoldenResourceHelper.handleExternalEidAddition(goldenResource, theTargetResource, theMdmTransactionContext); + myEidUpdateService.applySurvivorshipRulesAndSaveGoldenResource(theTargetResource, goldenResource, theMdmTransactionContext); } - myMdmLinkSvc.updateLink(golenResource, theSourceResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); + myMdmLinkSvc.updateLink(goldenResource, theTargetResource, theGoldenResourceCandidate.getMatchResult(), MdmLinkSourceEnum.AUTO, theMdmTransactionContext); } } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java index f61fb4bccb0..1dac6473a13 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSurvivorshipSvcImpl.java @@ -23,7 +23,7 @@ package ca.uhn.fhir.jpa.mdm.svc; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService; import ca.uhn.fhir.mdm.model.MdmTransactionContext; -import ca.uhn.fhir.mdm.util.TerserUtil; +import ca.uhn.fhir.util.TerserUtil; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; import org.springframework.beans.factory.annotation.Autowired; diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java index 0bd144b0568..39b5101c93e 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/provider/MdmProviderMergeGoldenResourcesR4Test.java @@ -4,9 +4,9 @@ import ca.uhn.fhir.jpa.entity.MdmLink; import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.util.MdmResourceUtil; -import ca.uhn.fhir.mdm.util.TerserUtil; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; +import ca.uhn.fhir.util.TerserUtil; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.StringType; import org.junit.jupiter.api.BeforeEach; diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcSurvivorshipTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcSurvivorshipTest.java new file mode 100644 index 00000000000..2a1d563d085 --- /dev/null +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcSurvivorshipTest.java @@ -0,0 +1,70 @@ +package ca.uhn.fhir.jpa.mdm.svc; + +import ca.uhn.fhir.jpa.entity.MdmLink; +import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; +import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.mdm.api.IMdmLinkSvc; +import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService; +import ca.uhn.fhir.mdm.api.MdmConstants; +import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; +import ca.uhn.fhir.mdm.api.MdmMatchOutcome; +import ca.uhn.fhir.mdm.model.MdmTransactionContext; +import ca.uhn.fhir.mdm.util.GoldenResourceHelper; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.param.TokenParam; +import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.r4.model.Patient; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mockito; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.SpyBean; + +import javax.annotation.Nullable; + +import static ca.uhn.fhir.mdm.api.MdmMatchResultEnum.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.mockito.Mockito.times; +import static org.slf4j.LoggerFactory.getLogger; + +public class MdmMatchLinkSvcSurvivorshipTest extends BaseMdmR4Test { + + private static final Logger ourLog = getLogger(MdmMatchLinkSvcSurvivorshipTest.class); + + @Autowired + IMdmLinkSvc myMdmLinkSvc; + + @SpyBean + IMdmSurvivorshipService myMdmSurvivorshipService; + + @Autowired + private GoldenResourceHelper myGoldenResourceHelper; + + @Captor + ArgumentCaptor myPatientCaptor; + @Captor + ArgumentCaptor myContext; + + @Test + public void testSurvivorshipIsCalledOnMatchingToTheSameGoldenResource() { + // no candidates + createPatientAndUpdateLinks(buildJanePatient()); + verifySurvivorshipCalled(1); + + // single candidate + createPatientAndUpdateLinks(buildJanePatient()); + verifySurvivorshipCalled(2); + + // multiple candidates matching to the same golden record + createPatientAndUpdateLinks(buildJanePatient()); + verifySurvivorshipCalled(3); + } + + private void verifySurvivorshipCalled(int theNumberOfTimes) { + Mockito.verify(myMdmSurvivorshipService, times(theNumberOfTimes)).applySurvivorshipRulesToGoldenResource(myPatientCaptor.capture(), myPatientCaptor.capture(), myContext.capture()); + } +} diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java index 06eb9ebe9d4..b3236ccaa39 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/svc/MdmMatchLinkSvcTest.java @@ -476,28 +476,6 @@ public class MdmMatchLinkSvcTest extends BaseMdmR4Test { assertThat(nameFirstRep.getGivenAsSingleString(), is(equalToIgnoringCase("paul"))); } - @Test - public void testPatientCreateDoesNotOverwriteGoldenResourceAttributesThatAreInvolvedInLinking() { - Patient paul = buildPaulPatient(); - paul.setGender(Enumerations.AdministrativeGender.MALE); - paul = createPatientAndUpdateLinks(paul); - - Patient sourcePatientFromTarget = (Patient) getGoldenResourceFromTargetResource(paul); - - assertThat(sourcePatientFromTarget.getGender(), is(equalTo(Enumerations.AdministrativeGender.MALE))); - - Patient paul2 = buildPaulPatient(); - paul2.setGender(Enumerations.AdministrativeGender.FEMALE); - paul2 = createPatientAndUpdateLinks(paul2); - - assertThat(paul2, is(sameGoldenResourceAs(paul))); - - //Newly matched patients aren't allowed to overwrite GoldenResource Attributes unless they are empty, - // so gender should still be set to male. - Patient paul2GoldenResource = (Patient) getGoldenResourceFromTargetResource(paul2); - assertThat(paul2GoldenResource.getGender(), is(equalTo(Enumerations.AdministrativeGender.MALE))); - } - @Test //Test Case #1 public void testPatientUpdatesOverwriteGoldenResourceData() { diff --git a/hapi-fhir-jpaserver-migrate/pom.xml b/hapi-fhir-jpaserver-migrate/pom.xml index 68316dcf0db..be260a03b39 100644 --- a/hapi-fhir-jpaserver-migrate/pom.xml +++ b/hapi-fhir-jpaserver-migrate/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index b46518bed86..7a40544f634 100644 --- a/hapi-fhir-jpaserver-model/pom.xml +++ b/hapi-fhir-jpaserver-model/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index 5dc3b7d17f4..5bc11f73872 100755 --- a/hapi-fhir-jpaserver-searchparam/pom.xml +++ b/hapi-fhir-jpaserver-searchparam/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index fc862aea074..369918d69c8 100644 --- a/hapi-fhir-jpaserver-subscription/pom.xml +++ b/hapi-fhir-jpaserver-subscription/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index b66f8e9615e..06b73aa7bac 100644 --- a/hapi-fhir-jpaserver-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index 183e9a6b602..9cec5a13cf8 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml @@ -164,7 +164,7 @@ ca.uhn.hapi.fhir hapi-fhir-converter - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index adc4be9c0ab..1952a50d819 100644 --- a/hapi-fhir-server-mdm/pom.xml +++ b/hapi-fhir-server-mdm/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/TerserUtil.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/TerserUtil.java deleted file mode 100644 index d64a55396ea..00000000000 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/util/TerserUtil.java +++ /dev/null @@ -1,147 +0,0 @@ -package ca.uhn.fhir.mdm.util; - -/*- - * #%L - * HAPI FHIR - Master Data Management - * %% - * Copyright (C) 2014 - 2021 Smile CDR, Inc. - * %% - * 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 ca.uhn.fhir.context.BaseRuntimeChildDefinition; -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.mdm.model.CanonicalEID; -import ca.uhn.fhir.util.FhirTerser; -import org.hl7.fhir.instance.model.api.IBase; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.slf4j.Logger; - -import java.util.Collection; -import java.util.List; -import java.util.function.Predicate; - -import static org.slf4j.LoggerFactory.getLogger; - -@Deprecated -public final class TerserUtil { - private static final Logger ourLog = getLogger(TerserUtil.class); - - public static final Collection IDS_AND_META_EXCLUDES = ca.uhn.fhir.util.TerserUtil.IDS_AND_META_EXCLUDES; - - public static final Predicate EXCLUDE_IDS_AND_META = ca.uhn.fhir.util.TerserUtil.EXCLUDE_IDS_AND_META; - - private TerserUtil() { - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void cloneEidIntoResource(FhirContext theFhirContext, BaseRuntimeChildDefinition theIdentifierDefinition, IBase theEid, IBase theResourceToCloneEidInto) { - ca.uhn.fhir.util.TerserUtil.cloneEidIntoResource(theFhirContext, theIdentifierDefinition, theEid, theResourceToCloneEidInto); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static boolean hasValues(FhirContext theFhirContext, IBaseResource theResource, String theFieldName) { - return ca.uhn.fhir.util.TerserUtil.hasValues(theFhirContext, theResource, theFieldName); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static List getValues(FhirContext theFhirContext, IBaseResource theResource, String theFieldName) { - return ca.uhn.fhir.util.TerserUtil.getValues(theFhirContext, theResource, theFieldName); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void cloneCompositeField(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, String field) { - ca.uhn.fhir.util.TerserUtil.cloneCompositeField(theFhirContext, theFrom, theTo, field); - - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void mergeAllFields(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo) { - ca.uhn.fhir.util.TerserUtil.mergeAllFields(theFhirContext, theFrom, theTo); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void replaceFields(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, Predicate inclusionStrategy) { - ca.uhn.fhir.util.TerserUtil.replaceFields(theFhirContext, theFrom, theTo, inclusionStrategy); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static boolean fieldExists(FhirContext theFhirContext, String theFieldName, IBaseResource theInstance) { - return ca.uhn.fhir.util.TerserUtil.fieldExists(theFhirContext, theFieldName, theInstance); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void replaceField(FhirContext theFhirContext, String theFieldName, IBaseResource theFrom, IBaseResource theTo) { - ca.uhn.fhir.util.TerserUtil.replaceField(theFhirContext, theFieldName, theFrom, theTo); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void replaceField(FhirContext theFhirContext, FhirTerser theTerser, String theFieldName, IBaseResource theFrom, IBaseResource theTo) { - ca.uhn.fhir.util.TerserUtil.replaceField(theFhirContext, theTerser, theFieldName, theFrom, theTo); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void mergeFieldsExceptIdAndMeta(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo) { - ca.uhn.fhir.util.TerserUtil.mergeFieldsExceptIdAndMeta(theFhirContext, theFrom, theTo); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void mergeFields(FhirContext theFhirContext, IBaseResource theFrom, IBaseResource theTo, Predicate inclusionStrategy) { - ca.uhn.fhir.util.TerserUtil.mergeFields(theFhirContext, theFrom, theTo, inclusionStrategy); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void mergeField(FhirContext theFhirContext, String theFieldName, IBaseResource theFrom, IBaseResource theTo) { - ca.uhn.fhir.util.TerserUtil.mergeField(theFhirContext, theFieldName, theFrom, theTo); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static void mergeField(FhirContext theFhirContext, FhirTerser theTerser, String theFieldName, IBaseResource theFrom, IBaseResource theTo) { - ca.uhn.fhir.util.TerserUtil.mergeField(theFhirContext, theTerser, theFieldName, theFrom, theTo); - } - - /** - * @deprecated Use {@link ca.uhn.fhir.util.TerserUtil} instead - */ - public static T clone(FhirContext theFhirContext, T theInstance) { - return ca.uhn.fhir.util.TerserUtil.clone(theFhirContext, theInstance); - } - -} diff --git a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/util/TerserUtilTest.java b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/util/TerserUtilTest.java deleted file mode 100644 index a94891fbdd2..00000000000 --- a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/util/TerserUtilTest.java +++ /dev/null @@ -1,197 +0,0 @@ -package ca.uhn.fhir.mdm.util; - -import ca.uhn.fhir.context.RuntimeResourceDefinition; -import ca.uhn.fhir.mdm.BaseR4Test; -import org.hl7.fhir.r4.model.DateTimeType; -import org.hl7.fhir.r4.model.Extension; -import org.hl7.fhir.r4.model.Identifier; -import org.hl7.fhir.r4.model.Patient; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class TerserUtilTest extends BaseR4Test { - - @Test - void testCloneEidIntoResource() { - Identifier identifier = new Identifier().setSystem("http://org.com/sys").setValue("123"); - - Patient p1 = new Patient(); - p1.addIdentifier(identifier); - - Patient p2 = new Patient(); - RuntimeResourceDefinition definition = ourFhirContext.getResourceDefinition(p1); - TerserUtil.cloneEidIntoResource(ourFhirContext, definition.getChildByName("identifier"), identifier, p2); - - assertEquals(1, p2.getIdentifier().size()); - assertEquals(p1.getIdentifier().get(0).getSystem(), p2.getIdentifier().get(0).getSystem()); - assertEquals(p1.getIdentifier().get(0).getValue(), p2.getIdentifier().get(0).getValue()); - } - - @Test - void testFieldExists() { - assertTrue(TerserUtil.fieldExists(ourFhirContext, "identifier", new Patient())); - assertFalse(TerserUtil.fieldExists(ourFhirContext, "randomFieldName", new Patient())); - } - - @Test - void testCloneFields() { - Patient p1 = buildJohny(); - p1.addName().addGiven("Sigizmund"); - p1.setId("Patient/22"); - - Patient p2 = new Patient(); - - TerserUtil.mergeFieldsExceptIdAndMeta(ourFhirContext, p1, p2); - - assertTrue(p2.getIdentifier().isEmpty()); - - assertNull(p2.getId()); - assertEquals(1, p2.getName().size()); - assertEquals(p1.getName().get(0).getNameAsSingleString(), p2.getName().get(0).getNameAsSingleString()); - } - - @Test - void testCloneWithNonPrimitives() { - Patient p1 = new Patient(); - Patient p2 = new Patient(); - - p1.addName().addGiven("Joe"); - p1.getNameFirstRep().addGiven("George"); - assertThat(p1.getName(), hasSize(1)); - assertThat(p1.getName().get(0).getGiven(), hasSize(2)); - - p2.addName().addGiven("Jeff"); - p2.getNameFirstRep().addGiven("George"); - assertThat(p2.getName(), hasSize(1)); - assertThat(p2.getName().get(0).getGiven(), hasSize(2)); - - TerserUtil.mergeAllFields(ourFhirContext, p1, p2); - assertThat(p2.getName(), hasSize(2)); - assertThat(p2.getName().get(0).getGiven(), hasSize(2)); - assertThat(p2.getName().get(1).getGiven(), hasSize(2)); - } - - @Test - void testMergeForAddressWithExtensions() { - Extension ext = new Extension(); - ext.setUrl("http://hapifhir.io/extensions/address#create-timestamp"); - ext.setValue(new DateTimeType("2021-01-02T11:13:15")); - - Patient p1 = new Patient(); - p1.addAddress() - .addLine("10 Main Street") - .setCity("Hamilton") - .setState("ON") - .setPostalCode("Z0Z0Z0") - .setCountry("Canada") - .addExtension(ext); - - Patient p2 = new Patient(); - p2.addAddress().addLine("10 Lenin Street").setCity("Severodvinsk").setCountry("Russia"); - - TerserUtil.mergeField(ourFhirContext,"address", p1, p2); - - assertEquals(2, p2.getAddress().size()); - assertEquals("[10 Lenin Street]", p2.getAddress().get(0).getLine().toString()); - assertEquals("[10 Main Street]", p2.getAddress().get(1).getLine().toString()); - assertTrue(p2.getAddress().get(1).hasExtension()); - - p1 = new Patient(); - p1.addAddress().addLine("10 Main Street").addExtension(ext); - p2 = new Patient(); - p2.addAddress().addLine("10 Main Street").addExtension(new Extension("demo", new DateTimeType("2021-01-02"))); - - TerserUtil.mergeField(ourFhirContext,"address", p1, p2); - assertEquals(2, p2.getAddress().size()); - assertTrue(p2.getAddress().get(0).hasExtension()); - assertTrue(p2.getAddress().get(1).hasExtension()); - - } - - @Test - void testReplaceForAddressWithExtensions() { - Extension ext = new Extension(); - ext.setUrl("http://hapifhir.io/extensions/address#create-timestamp"); - ext.setValue(new DateTimeType("2021-01-02T11:13:15")); - - Patient p1 = new Patient(); - p1.addAddress() - .addLine("10 Main Street") - .setCity("Hamilton") - .setState("ON") - .setPostalCode("Z0Z0Z0") - .setCountry("Canada") - .addExtension(ext); - - Patient p2 = new Patient(); - p2.addAddress().addLine("10 Lenin Street").setCity("Severodvinsk").setCountry("Russia"); - - TerserUtil.replaceField(ourFhirContext,"address", p1, p2); - - assertEquals(1, p2.getAddress().size()); - assertEquals("[10 Main Street]", p2.getAddress().get(0).getLine().toString()); - assertTrue(p2.getAddress().get(0).hasExtension()); - } - - @Test - void testMergeForSimilarAddresses() { - Extension ext = new Extension(); - ext.setUrl("http://hapifhir.io/extensions/address#create-timestamp"); - ext.setValue(new DateTimeType("2021-01-02T11:13:15")); - - Patient p1 = new Patient(); - p1.addAddress() - .addLine("10 Main Street") - .setCity("Hamilton") - .setState("ON") - .setPostalCode("Z0Z0Z0") - .setCountry("Canada") - .addExtension(ext); - - Patient p2 = new Patient(); - p2.addAddress() - .addLine("10 Main Street") - .setCity("Hamilton") - .setState("ON") - .setPostalCode("Z0Z0Z1") - .setCountry("Canada") - .addExtension(ext); - - TerserUtil.mergeField(ourFhirContext,"address", p1, p2); - - assertEquals(2, p2.getAddress().size()); - assertEquals("[10 Main Street]", p2.getAddress().get(0).getLine().toString()); - assertEquals("[10 Main Street]", p2.getAddress().get(1).getLine().toString()); - assertTrue(p2.getAddress().get(1).hasExtension()); - } - - - @Test - void testCloneWithDuplicateNonPrimitives() { - Patient p1 = new Patient(); - Patient p2 = new Patient(); - - p1.addName().addGiven("Jim"); - p1.getNameFirstRep().addGiven("George"); - - assertThat(p1.getName(), hasSize(1)); - assertThat(p1.getName().get(0).getGiven(), hasSize(2)); - - p2.addName().addGiven("Jim"); - p2.getNameFirstRep().addGiven("George"); - - assertThat(p2.getName(), hasSize(1)); - assertThat(p2.getName().get(0).getGiven(), hasSize(2)); - - TerserUtil.mergeAllFields(ourFhirContext, p1, p2); - - assertThat(p2.getName(), hasSize(1)); - assertThat(p2.getName().get(0).getGiven(), hasSize(2)); - } -} diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index 1e71fc77421..4fe87a2ee16 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml index d0905db3a66..19eedc6bfd2 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml index 919e895664c..656d16080d7 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT hapi-fhir-spring-boot-sample-client-apache diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml index 622de27723a..0f9be244025 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT hapi-fhir-spring-boot-sample-client-okhttp diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml index ad0f6ed0cfb..9d5b6483f92 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT hapi-fhir-spring-boot-sample-server-jersey diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml index 02e9d448d79..a57c5e80e1b 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT hapi-fhir-spring-boot-samples diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml index c210826be2c..3f90ae6bbcc 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml index 38c1789454d..ff3fe4a179a 100644 --- a/hapi-fhir-spring-boot/pom.xml +++ b/hapi-fhir-spring-boot/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index c8054db0e2b..61d4ea265db 100644 --- a/hapi-fhir-structures-dstu2.1/pom.xml +++ b/hapi-fhir-structures-dstu2.1/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml index 6659bcd46c2..9359dc2e980 100644 --- a/hapi-fhir-structures-dstu2/pom.xml +++ b/hapi-fhir-structures-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index 04fc5a8cbc3..5a825a62517 100644 --- a/hapi-fhir-structures-dstu3/pom.xml +++ b/hapi-fhir-structures-dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml index 8383bdda70a..e842ad1c049 100644 --- a/hapi-fhir-structures-hl7org-dstu2/pom.xml +++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml index e0793555c76..d5f9e85f836 100644 --- a/hapi-fhir-structures-r4/pom.xml +++ b/hapi-fhir-structures-r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/BundleBuilderTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/BundleBuilderTest.java index 22bf634d525..e31bbc9fbd0 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/BundleBuilderTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/BundleBuilderTest.java @@ -156,6 +156,36 @@ public class BundleBuilderTest { assertEquals(Bundle.HTTPVerb.POST, bundle.getEntry().get(0).getRequest().getMethod()); } + @Test + public void testAddEntryDelete() { + BundleBuilder builder = new BundleBuilder(myFhirContext); + + Patient patient = new Patient(); + patient.setActive(true); + patient.setId("123"); + builder.addTransactionDeleteEntry(patient); + builder.addTransactionDeleteEntry("Patient", "123"); + Bundle bundle = (Bundle) builder.getBundle(); + + ourLog.info("Bundle:\n{}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); + + assertEquals(Bundle.BundleType.TRANSACTION, bundle.getType()); + assertEquals(2, bundle.getEntry().size()); + + //Check the IBaseresource style entry + assertNull(bundle.getEntry().get(0).getResource()); + assertEquals("Patient/123", bundle.getEntry().get(0).getRequest().getUrl()); + assertEquals(Bundle.HTTPVerb.DELETE, bundle.getEntry().get(0).getRequest().getMethod()); + + //Check the resourcetype + id style entry. + assertNull(bundle.getEntry().get(1).getResource()); + assertEquals("Patient/123", bundle.getEntry().get(1).getRequest().getUrl()); + assertEquals(Bundle.HTTPVerb.DELETE, bundle.getEntry().get(1).getRequest().getMethod()); + + + + } + @Test public void testAddEntryCreateConditional() { BundleBuilder builder = new BundleBuilder(myFhirContext); diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/TerserUtilTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/TerserUtilTest.java index d4af78f0162..0d9d03e6f32 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/TerserUtilTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/util/TerserUtilTest.java @@ -13,6 +13,8 @@ import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.PrimitiveType; import org.junit.jupiter.api.Test; +import java.util.Date; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.junit.jupiter.api.Assertions.*; @@ -77,6 +79,7 @@ class TerserUtilTest { assertEquals(check.getValue(), p.getBirthDate()); } + @Test void testFieldExists() { assertTrue(TerserUtil.fieldExists(ourFhirContext, "identifier", TerserUtil.newResource(ourFhirContext, "Patient"))); @@ -294,6 +297,26 @@ class TerserUtilTest { assertEquals("Doe", p2.getName().get(0).getFamily()); } + @Test + public void testReplaceFieldsByPredicate() { + Patient p1 = new Patient(); + p1.addName().setFamily("Doe"); + p1.setGender(Enumerations.AdministrativeGender.MALE); + + Patient p2 = new Patient(); + p2.addName().setFamily("Smith"); + Date dob = new Date(); + p2.setBirthDate(dob); + + TerserUtil.replaceFieldsByPredicate(ourFhirContext, p1, p2, TerserUtil.EXCLUDE_IDS_META_AND_EMPTY); + + // expect p2 to have "Doe" and MALE after replace + assertEquals(1, p2.getName().size()); + assertEquals("Doe", p2.getName().get(0).getFamily()); + assertEquals(Enumerations.AdministrativeGender.MALE, p2.getGender()); + assertEquals(dob, p2.getBirthDate()); + } + @Test public void testClearFields() { Patient p1 = new Patient(); diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index f564ed044b8..490ba126870 100644 --- a/hapi-fhir-structures-r5/pom.xml +++ b/hapi-fhir-structures-r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml index ac4521d10e5..66f0f0ac9fd 100644 --- a/hapi-fhir-test-utilities/pom.xml +++ b/hapi-fhir-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml index 0a140bc05ab..072a4f9a21c 100644 --- a/hapi-fhir-testpage-overlay/pom.xml +++ b/hapi-fhir-testpage-overlay/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml index 4db0f72591a..f8cc76070d3 100644 --- a/hapi-fhir-validation-resources-dstu2.1/pom.xml +++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml index a3b7462547d..a69e2ea236d 100644 --- a/hapi-fhir-validation-resources-dstu2/pom.xml +++ b/hapi-fhir-validation-resources-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml index 33d67b4e94a..0061ae4ef6e 100644 --- a/hapi-fhir-validation-resources-dstu3/pom.xml +++ b/hapi-fhir-validation-resources-dstu3/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml index 5f830ffce69..ace6fe58362 100644 --- a/hapi-fhir-validation-resources-r4/pom.xml +++ b/hapi-fhir-validation-resources-r4/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml index dbc5e9359b8..442455129ad 100644 --- a/hapi-fhir-validation-resources-r5/pom.xml +++ b/hapi-fhir-validation-resources-r5/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index aafc58b15ba..a441397e88e 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index 6daf487888f..1da19fdaf24 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml @@ -58,37 +58,37 @@ ca.uhn.hapi.fhir hapi-fhir-structures-dstu3 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-hl7org-dstu2 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-r4 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-r5 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-dstu2 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-dstu3 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-r4 - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT org.apache.velocity diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index 6b9aa6546e9..2f98895c12d 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index a30317cecab..109923b7ecc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir pom - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT HAPI-FHIR An open-source implementation of the FHIR specification in Java. https://hapifhir.io diff --git a/restful-server-example/pom.xml b/restful-server-example/pom.xml index 7640191ae97..ee4e9459316 100644 --- a/restful-server-example/pom.xml +++ b/restful-server-example/pom.xml @@ -8,7 +8,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../pom.xml diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml index 2ef7b674d4b..757146f0f1c 100644 --- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml +++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml index 85242f389d3..e295bb2a92c 100644 --- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml index 9716634f826..bde4aa9378f 100644 --- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE6-SNAPSHOT + 5.4.0-PRE7-SNAPSHOT ../../pom.xml