Merge branch 'master' into jd-20240905-add-batch-and-chunk-ids-to-logging-context
This commit is contained in:
commit
e148c76a09
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -136,6 +136,7 @@ public enum VersionEnum {
|
||||||
V6_8_5,
|
V6_8_5,
|
||||||
V6_8_6,
|
V6_8_6,
|
||||||
V6_8_7,
|
V6_8_7,
|
||||||
|
V6_8_8,
|
||||||
|
|
||||||
V6_9_0,
|
V6_9_0,
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-bom</artifactId>
|
<artifactId>hapi-fhir-bom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>HAPI FHIR BOM</name>
|
<name>HAPI FHIR BOM</name>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-cli</artifactId>
|
<artifactId>hapi-fhir-cli</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6218
|
||||||
|
jira: SMILE-8370
|
||||||
|
title: "Previously, when disabling the 'Enforce Referential Integrity on Write' setting, referential integrity was still
|
||||||
|
partially enforced when posting a resource with an invalid reference. This has now been fixed."
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6262
|
||||||
|
title: "Previously, when a `extension` was passed in as a part of the CDS hooks request, it would result in a `400 service not found`. This behaviour has now been fixed."
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
type: remove
|
||||||
|
issue: 6283
|
||||||
|
title: "Hibernate Search Fulltext fields which were unused
|
||||||
|
have been removed from indexing.
|
||||||
|
This will reduce storage usage in Lucene and Elasticsearch.
|
||||||
|
The fields that were removed are: `myNarrativeTextEdgeNGram`,
|
||||||
|
`myNarrativeTextNGram`, `myNarrativeTextPhonetic`, `myContentTextEdgeNGram`,
|
||||||
|
`myContentTextNGram`, `myContentTextPhonetic`.
|
||||||
|
"
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6290
|
||||||
|
title: "Previously, a specific migration task was using the `TRIM()` function, which does not exist in MSSQL 2012. This was causing migrations targeting MSSQL 2012 to fail.
|
||||||
|
This has been corrected and replaced with usage of a combination of LTRIM() and RTRIM(). Thanks to Primož Delopst at Better for the contribution!"
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6305
|
||||||
|
title: "Previously, when having StorageSettings#getIndexMissingFields() == IndexEnabledEnum.DISABLED (default value)
|
||||||
|
and attempting to search with the missing qualifier against a resource type with multiple search parameters of type reference,
|
||||||
|
the returned results would be incorrect. This has been fixed."
|
|
@ -4,6 +4,7 @@
|
||||||
title: "The version of a few dependencies have been bumped to more recent versions
|
title: "The version of a few dependencies have been bumped to more recent versions
|
||||||
(dependent HAPI modules listed in brackets):
|
(dependent HAPI modules listed in brackets):
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>org.hl7.fhir.core (Base): 6.3.18 -> 6.3.23</li>
|
||||||
<li>Bower/Moment.js (hapi-fhir-testpage-overlay): 2.27.0 -> 2.29.4</li>
|
<li>Bower/Moment.js (hapi-fhir-testpage-overlay): 2.27.0 -> 2.29.4</li>
|
||||||
<li>htmlunit (Base): 3.9.0 -> 3.11.0</li>
|
<li>htmlunit (Base): 3.9.0 -> 3.11.0</li>
|
||||||
<li>Elasticsearch (Base): 8.11.1 -> 8.14.3</li>
|
<li>Elasticsearch (Base): 8.11.1 -> 8.14.3</li>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -588,8 +588,8 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc {
|
||||||
if (statusTypes.isEmpty()) {
|
if (statusTypes.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Resource has a null status field
|
// Resource has no status field, or an explicitly null one
|
||||||
if (statusTypes.get(0).getValue() == null) {
|
if (!statusTypes.get(0).hasValue() || statusTypes.get(0).getValue() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Resource has a status, and we need to check based on type
|
// Resource has a status, and we need to check based on type
|
||||||
|
|
|
@ -800,14 +800,19 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder im
|
||||||
subquery.addCustomColumns(1);
|
subquery.addCustomColumns(1);
|
||||||
subquery.addFromTable(getTable());
|
subquery.addFromTable(getTable());
|
||||||
|
|
||||||
|
String resourceType = theParams.getResourceTablePredicateBuilder().getResourceType();
|
||||||
|
RuntimeSearchParam paramDefinition =
|
||||||
|
mySearchParamRegistry.getRuntimeSearchParam(resourceType, theParams.getParamName());
|
||||||
|
List<String> pathList = paramDefinition.getPathsSplitForResourceType(resourceType);
|
||||||
|
|
||||||
Condition subQueryCondition = ComboCondition.and(
|
Condition subQueryCondition = ComboCondition.and(
|
||||||
BinaryCondition.equalTo(
|
BinaryCondition.equalTo(
|
||||||
getResourceIdColumn(),
|
getResourceIdColumn(),
|
||||||
theParams.getResourceTablePredicateBuilder().getResourceIdColumn()),
|
theParams.getResourceTablePredicateBuilder().getResourceIdColumn()),
|
||||||
BinaryCondition.equalTo(
|
BinaryCondition.equalTo(getResourceTypeColumn(), generatePlaceholder(resourceType)),
|
||||||
getResourceTypeColumn(),
|
ComboCondition.or(pathList.stream()
|
||||||
generatePlaceholder(
|
.map(path -> BinaryCondition.equalTo(getColumnSourcePath(), generatePlaceholder(path)))
|
||||||
theParams.getResourceTablePredicateBuilder().getResourceType())));
|
.toArray(BinaryCondition[]::new)));
|
||||||
|
|
||||||
subquery.addCondition(subQueryCondition);
|
subquery.addCondition(subQueryCondition);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class PartitionSettings {
|
||||||
private boolean myAlwaysOpenNewTransactionForDifferentPartition;
|
private boolean myAlwaysOpenNewTransactionForDifferentPartition;
|
||||||
private boolean myConditionalCreateDuplicateIdentifiersEnabled = false;
|
private boolean myConditionalCreateDuplicateIdentifiersEnabled = false;
|
||||||
|
|
||||||
|
public PartitionSettings() {}
|
||||||
/**
|
/**
|
||||||
* Should we always open a new database transaction if the partition context changes
|
* Should we always open a new database transaction if the partition context changes
|
||||||
*
|
*
|
||||||
|
|
|
@ -119,21 +119,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
||||||
searchable = Searchable.YES,
|
searchable = Searchable.YES,
|
||||||
projectable = Projectable.YES,
|
projectable = Projectable.YES,
|
||||||
analyzer = "standardAnalyzer")
|
analyzer = "standardAnalyzer")
|
||||||
@FullTextField(
|
|
||||||
name = "myContentTextEdgeNGram",
|
|
||||||
searchable = Searchable.YES,
|
|
||||||
projectable = Projectable.NO,
|
|
||||||
analyzer = "autocompleteEdgeAnalyzer")
|
|
||||||
@FullTextField(
|
|
||||||
name = "myContentTextNGram",
|
|
||||||
searchable = Searchable.YES,
|
|
||||||
projectable = Projectable.NO,
|
|
||||||
analyzer = "autocompleteNGramAnalyzer")
|
|
||||||
@FullTextField(
|
|
||||||
name = "myContentTextPhonetic",
|
|
||||||
searchable = Searchable.YES,
|
|
||||||
projectable = Projectable.NO,
|
|
||||||
analyzer = "autocompletePhoneticAnalyzer")
|
|
||||||
@OptimisticLock(excluded = true)
|
@OptimisticLock(excluded = true)
|
||||||
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "myVersion")))
|
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "myVersion")))
|
||||||
private String myContentText;
|
private String myContentText;
|
||||||
|
@ -171,21 +156,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
||||||
searchable = Searchable.YES,
|
searchable = Searchable.YES,
|
||||||
projectable = Projectable.YES,
|
projectable = Projectable.YES,
|
||||||
analyzer = "standardAnalyzer")
|
analyzer = "standardAnalyzer")
|
||||||
@FullTextField(
|
|
||||||
name = "myNarrativeTextEdgeNGram",
|
|
||||||
searchable = Searchable.YES,
|
|
||||||
projectable = Projectable.NO,
|
|
||||||
analyzer = "autocompleteEdgeAnalyzer")
|
|
||||||
@FullTextField(
|
|
||||||
name = "myNarrativeTextNGram",
|
|
||||||
searchable = Searchable.YES,
|
|
||||||
projectable = Projectable.NO,
|
|
||||||
analyzer = "autocompleteNGramAnalyzer")
|
|
||||||
@FullTextField(
|
|
||||||
name = "myNarrativeTextPhonetic",
|
|
||||||
searchable = Searchable.YES,
|
|
||||||
projectable = Projectable.NO,
|
|
||||||
analyzer = "autocompletePhoneticAnalyzer")
|
|
||||||
@OptimisticLock(excluded = true)
|
@OptimisticLock(excluded = true)
|
||||||
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "myVersion")))
|
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "myVersion")))
|
||||||
private String myNarrativeText;
|
private String myNarrativeText;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -44,13 +44,13 @@ public interface ISearchParamExtractor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant for the {@literal theSearchParamFilter} parameters on this interface
|
* Constant for the {@literal theSearchParamFilter} parameters on this interface
|
||||||
* indicating that all search parameters should be indexed.
|
* indicating that all search parameters should be extracted.
|
||||||
*/
|
*/
|
||||||
ISearchParamFilter ALL_PARAMS = t -> t;
|
ISearchParamFilter ALL_PARAMS = t -> t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant for the {@literal theSearchParamFilter} parameters on this interface
|
* Constant for the {@literal theSearchParamFilter} parameters on this interface
|
||||||
* indicating that no search parameters should be indexed.
|
* indicating that no search parameters should be extracted.
|
||||||
*/
|
*/
|
||||||
ISearchParamFilter NO_PARAMS = t -> Collections.emptyList();
|
ISearchParamFilter NO_PARAMS = t -> Collections.emptyList();
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ public interface ISearchParamExtractor {
|
||||||
interface ISearchParamFilter {
|
interface ISearchParamFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the list of search parameters for indexing, an implementation of this
|
* Given the list of search parameters for extracting, an implementation of this
|
||||||
* interface may selectively remove any that it wants to remove (or can add if desired).
|
* interface may selectively remove any that it wants to remove (or can add if desired).
|
||||||
* <p>
|
* <p>
|
||||||
* Implementations must not modify the list that is passed in. If changes are
|
* Implementations must not modify the list that is passed in. If changes are
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
package ca.uhn.fhir.jpa.dao.r4;
|
package ca.uhn.fhir.jpa.dao.r4;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
|
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
import org.hl7.fhir.r4.model.Observation;
|
||||||
import org.hl7.fhir.r4.model.Organization;
|
import org.hl7.fhir.r4.model.Organization;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test {
|
public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test {
|
||||||
|
@ -23,51 +30,168 @@ public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test {
|
||||||
myStorageSettings.setEnforceReferentialIntegrityOnWrite(new JpaStorageSettings().isEnforceReferentialIntegrityOnWrite());
|
myStorageSettings.setEnforceReferentialIntegrityOnWrite(new JpaStorageSettings().isEnforceReferentialIntegrityOnWrite());
|
||||||
myStorageSettings.setEnforceReferentialIntegrityOnDelete(new JpaStorageSettings().isEnforceReferentialIntegrityOnDelete());
|
myStorageSettings.setEnforceReferentialIntegrityOnDelete(new JpaStorageSettings().isEnforceReferentialIntegrityOnDelete());
|
||||||
myStorageSettings.setEnforceReferenceTargetTypes(new JpaStorageSettings().isEnforceReferenceTargetTypes());
|
myStorageSettings.setEnforceReferenceTargetTypes(new JpaStorageSettings().isEnforceReferenceTargetTypes());
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(new JpaStorageSettings().getResourceClientIdStrategy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("paramsProvider_withResourceType")
|
||||||
|
public void referentialIntegrityOnWriteSetting_unknownIds_fullScopeTest(boolean theIsEnforceRefIntegrityEnabled,
|
||||||
|
JpaStorageSettings.ClientIdStrategyEnum theClientIdStrategy,
|
||||||
|
String theReferenceId) {
|
||||||
|
// Given
|
||||||
|
myStorageSettings.setEnforceReferentialIntegrityOnWrite(theIsEnforceRefIntegrityEnabled);
|
||||||
|
myStorageSettings.setEnforceReferenceTargetTypes(theIsEnforceRefIntegrityEnabled);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(theClientIdStrategy);
|
||||||
|
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setManagingOrganization(new Reference(theReferenceId));
|
||||||
|
|
||||||
|
if (theIsEnforceRefIntegrityEnabled) {
|
||||||
|
try {
|
||||||
|
// When
|
||||||
|
myPatientDao.create(p);
|
||||||
|
fail();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
// Then
|
||||||
|
assertEquals(Msg.code(1094) + "Resource " + theReferenceId + " not found, specified in path: Patient.managingOrganization", e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Disabled ref integrity on write case: all POSTs should succeed
|
||||||
|
// When
|
||||||
|
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
// Then
|
||||||
|
p = myPatientDao.read(id);
|
||||||
|
assertEquals(theReferenceId, p.getManagingOrganization().getReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> paramsProvider_withResourceType() {
|
||||||
|
// theIsEnforceRefIntegrityEnabled, theClientIdStrategy, theReferenceId
|
||||||
|
// note: client ID is tested since resolving the resource reference is different depending on the strategy
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/123"),
|
||||||
|
Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/A123"),
|
||||||
|
Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/123"),
|
||||||
|
Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/A123"),
|
||||||
|
Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/123"),
|
||||||
|
Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "Organization/A123"),
|
||||||
|
Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/123"),
|
||||||
|
Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "Organization/A123")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateUnknownReferenceFail() throws Exception {
|
public void testRefIntegrityOnWrite_withReferenceIdOfAnotherResourceType() {
|
||||||
|
// Given
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC);
|
||||||
|
|
||||||
|
// Create Observation with some ID...
|
||||||
|
Observation obs = new Observation();
|
||||||
|
IIdType obsId = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
// And reference a non-existing Organization resource with the same ID as the Observation
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setManagingOrganization(new Reference("Organization/AAA"));
|
p.setManagingOrganization(new Reference(new IdType("Organization", obsId.getIdPart())));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// When
|
||||||
myPatientDao.create(p);
|
myPatientDao.create(p);
|
||||||
fail();
|
fail();
|
||||||
} catch (InvalidRequestException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals(Msg.code(1094) + "Resource Organization/AAA not found, specified in path: Patient.managingOrganization", e.getMessage());
|
// Then: identify that it is the wrong resource type, since ref integrity is enabled
|
||||||
|
assertEquals(Msg.code(1095) + "Resource contains reference to unknown resource ID Organization/" + obsId.getIdPart(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given: now disable referential integrity on write
|
||||||
|
myStorageSettings.setEnforceReferentialIntegrityOnWrite(false);
|
||||||
|
// When
|
||||||
|
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
// Then: this should now succeed
|
||||||
|
p = myPatientDao.read(id);
|
||||||
|
assertEquals("Organization/" + obsId.getIdPart(), p.getManagingOrganization().getReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testCreateUnknownReferenceAllowed() {
|
@MethodSource("paramsProvider_noResourceType")
|
||||||
myStorageSettings.setEnforceReferentialIntegrityOnWrite(false);
|
public void testRefIntegrityOnWrite_withValidReferenceId_shouldAlwaysSucceed(boolean theIsEnforceRefIntegrityEnabled,
|
||||||
|
JpaStorageSettings.ClientIdStrategyEnum theClientIdStrategy,
|
||||||
|
String theReferenceId) {
|
||||||
|
// Given
|
||||||
|
myStorageSettings.setEnforceReferentialIntegrityOnWrite(theIsEnforceRefIntegrityEnabled);
|
||||||
|
myStorageSettings.setEnforceReferenceTargetTypes(theIsEnforceRefIntegrityEnabled);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(theClientIdStrategy);
|
||||||
|
|
||||||
|
Organization obs = new Organization();
|
||||||
|
obs.setId(theReferenceId);
|
||||||
|
myOrganizationDao.update(obs, mySrd);
|
||||||
|
String qualifiedReferenceId = "Organization/" + theReferenceId;
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setManagingOrganization(new Reference("Organization/AAA"));
|
p.setManagingOrganization(new Reference(qualifiedReferenceId));
|
||||||
|
|
||||||
|
// When
|
||||||
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
// Then
|
||||||
p = myPatientDao.read(id);
|
p = myPatientDao.read(id);
|
||||||
assertEquals("Organization/AAA", p.getManagingOrganization().getReference());
|
assertEquals(qualifiedReferenceId, p.getManagingOrganization().getReference());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private static Stream<Arguments> paramsProvider_noResourceType() {
|
||||||
public void testCreateUnknownReferenceAllowed_NumericId() {
|
// theIsEnforceRefIntegrityEnabled, theClientIdStrategy, theReferenceId
|
||||||
myStorageSettings.setEnforceReferentialIntegrityOnWrite(false);
|
// note: client ID is tested since resolving the resource reference is different depending on the strategy
|
||||||
myStorageSettings.setEnforceReferenceTargetTypes(false);
|
return Stream.of(
|
||||||
|
Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "A123"),
|
||||||
|
Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "123"),
|
||||||
|
Arguments.of(true, JpaStorageSettings.ClientIdStrategyEnum.ANY, "A123"),
|
||||||
|
Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC, "A123"),
|
||||||
|
Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "123"),
|
||||||
|
Arguments.of(false, JpaStorageSettings.ClientIdStrategyEnum.ANY, "A123")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("paramsProvider_noResourceType")
|
||||||
|
public void testRefIntegrityOnWrite_withReferenceIdOfDeletedResource(boolean theIsEnforceRefIntegrityEnabled,
|
||||||
|
JpaStorageSettings.ClientIdStrategyEnum theClientIdStrategy,
|
||||||
|
String theReferenceId) {
|
||||||
|
// Given
|
||||||
|
myStorageSettings.setEnforceReferentialIntegrityOnWrite(theIsEnforceRefIntegrityEnabled);
|
||||||
|
myStorageSettings.setEnforceReferenceTargetTypes(theIsEnforceRefIntegrityEnabled);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(theClientIdStrategy);
|
||||||
|
|
||||||
|
Organization obs = new Organization();
|
||||||
|
obs.setId(theReferenceId);
|
||||||
|
IIdType obsId = myOrganizationDao.update(obs, mySrd).getId();
|
||||||
|
String qualifiedReferenceId = "Organization/" + theReferenceId;
|
||||||
|
|
||||||
|
myOrganizationDao.delete(obsId, mySrd);
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.setManagingOrganization(new Reference("Organization/123"));
|
p.setManagingOrganization(new Reference(qualifiedReferenceId));
|
||||||
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
|
||||||
|
|
||||||
p = myPatientDao.read(id);
|
if (theIsEnforceRefIntegrityEnabled) {
|
||||||
assertEquals("Organization/123", p.getManagingOrganization().getReference());
|
try {
|
||||||
|
// When
|
||||||
|
myPatientDao.create(p);
|
||||||
|
fail();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
// Then
|
||||||
|
assertEquals(Msg.code(1096) + "Resource " + qualifiedReferenceId + " is deleted, specified in path: Patient.managingOrganization", e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Disabled ref integrity on write case: all POSTs should succeed
|
||||||
|
// When
|
||||||
|
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
p = myPatientDao.read(id);
|
||||||
|
assertEquals(qualifiedReferenceId, p.getManagingOrganization().getReference());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteFail() throws Exception {
|
public void testDeleteFail() {
|
||||||
Organization o = new Organization();
|
Organization o = new Organization();
|
||||||
o.setName("FOO");
|
o.setName("FOO");
|
||||||
IIdType oid = myOrganizationDao.create(o).getId().toUnqualifiedVersionless();
|
IIdType oid = myOrganizationDao.create(o).getId().toUnqualifiedVersionless();
|
||||||
|
@ -89,7 +213,7 @@ public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteAllow() throws Exception {
|
public void testDeleteAllow() {
|
||||||
myStorageSettings.setEnforceReferentialIntegrityOnDelete(false);
|
myStorageSettings.setEnforceReferentialIntegrityOnDelete(false);
|
||||||
|
|
||||||
Organization o = new Organization();
|
Organization o = new Organization();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -217,7 +217,7 @@ import static org.mockito.Mockito.when;
|
||||||
public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4Test.class);
|
||||||
private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw;
|
private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw;
|
||||||
private CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
|
private final CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISearchDao mySearchEntityDao;
|
private ISearchDao mySearchEntityDao;
|
||||||
|
|
||||||
|
@ -413,15 +413,15 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
pt1.addName().setFamily("Elizabeth");
|
pt1.addName().setFamily("Elizabeth");
|
||||||
String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
|
String pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
Patient pt2 = new Patient();
|
Patient pt2 = new Patient();
|
||||||
pt2.addName().setFamily("fghijk");
|
pt2.addName().setFamily("fghijk");
|
||||||
String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue();
|
String pt2id = myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
Patient pt3 = new Patient();
|
Patient pt3 = new Patient();
|
||||||
pt3.addName().setFamily("zzzzz");
|
pt3.addName().setFamily("zzzzz");
|
||||||
myPatientDao.create(pt3).getId().toUnqualifiedVersionless().getValue();
|
myPatientDao.create(pt3, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
|
|
||||||
Bundle output = myClient
|
Bundle output = myClient
|
||||||
|
@ -450,7 +450,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
pt1.addName().setFamily("Smith%");
|
pt1.addName().setFamily("Smith%");
|
||||||
String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
|
String pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
Bundle output = myClient
|
Bundle output = myClient
|
||||||
.search()
|
.search()
|
||||||
|
@ -463,7 +463,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient pt2 = new Patient();
|
Patient pt2 = new Patient();
|
||||||
pt2.addName().setFamily("Sm%ith");
|
pt2.addName().setFamily("Sm%ith");
|
||||||
String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue();
|
String pt2id = myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||||
|
|
||||||
output = myClient
|
output = myClient
|
||||||
.search()
|
.search()
|
||||||
|
@ -740,7 +740,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().setFamily("FAM").addGiven("GIV");
|
p.addName().setFamily("FAM").addGiven("GIV");
|
||||||
IIdType id = myPatientDao.create(p).getId();
|
IIdType id = myPatientDao.create(p, mySrd).getId();
|
||||||
|
|
||||||
myClient.read().resource("Patient").withId(id.toUnqualifiedVersionless()).execute();
|
myClient.read().resource("Patient").withId(id.toUnqualifiedVersionless()).execute();
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().setFamily("FAM").addGiven("GIV");
|
p.addName().setFamily("FAM").addGiven("GIV");
|
||||||
IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
myClient
|
myClient
|
||||||
.delete()
|
.delete()
|
||||||
|
@ -1025,57 +1025,58 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
public void testCreateAndReadBackResourceWithContainedReferenceToContainer() {
|
public void testCreateAndReadBackResourceWithContainedReferenceToContainer() {
|
||||||
myFhirContext.setParserErrorHandler(new StrictErrorHandler());
|
myFhirContext.setParserErrorHandler(new StrictErrorHandler());
|
||||||
|
|
||||||
String input = "{\n" +
|
String input = """
|
||||||
" \"resourceType\": \"Organization\",\n" +
|
{
|
||||||
" \"id\": \"1\",\n" +
|
"resourceType": "Organization",
|
||||||
" \"meta\": {\n" +
|
"id": "1",
|
||||||
" \"tag\": [\n" +
|
"meta": {
|
||||||
" {\n" +
|
"tag": [
|
||||||
" \"system\": \"https://blah.org/deployment\",\n" +
|
{
|
||||||
" \"code\": \"e69414dd-b5c2-462d-bcfd-9d04d6b16596\",\n" +
|
"system": "https://blah.org/deployment",
|
||||||
" \"display\": \"DEPLOYMENT\"\n" +
|
"code": "e69414dd-b5c2-462d-bcfd-9d04d6b16596",
|
||||||
" },\n" +
|
"display": "DEPLOYMENT"
|
||||||
" {\n" +
|
},
|
||||||
" \"system\": \"https://blah.org/region\",\n" +
|
{
|
||||||
" \"code\": \"b47d7a5b-b159-4bed-a8f8-3258e6603adb\",\n" +
|
"system": "https://blah.org/region",
|
||||||
" \"display\": \"REGION\"\n" +
|
"code": "b47d7a5b-b159-4bed-a8f8-3258e6603adb",
|
||||||
" },\n" +
|
"display": "REGION"
|
||||||
" {\n" +
|
},
|
||||||
" \"system\": \"https://blah.org/provider\",\n" +
|
{
|
||||||
" \"code\": \"28c30004-0333-40cf-9e7f-3f9e080930bd\",\n" +
|
"system": "https://blah.org/provider",
|
||||||
" \"display\": \"PROVIDER\"\n" +
|
"code": "28c30004-0333-40cf-9e7f-3f9e080930bd",
|
||||||
" }\n" +
|
"display": "PROVIDER"
|
||||||
" ]\n" +
|
}
|
||||||
" },\n" +
|
]
|
||||||
" \"contained\": [\n" +
|
},
|
||||||
" {\n" +
|
"contained": [
|
||||||
" \"resourceType\": \"Location\",\n" +
|
{
|
||||||
" \"id\": \"2\",\n" +
|
"resourceType": "Location",
|
||||||
" \"position\": {\n" +
|
"id": "2",
|
||||||
" \"longitude\": 51.443238301454289,\n" +
|
"position": {
|
||||||
" \"latitude\": 7.34196905697293\n" +
|
"longitude": 51.443238301454289,
|
||||||
" },\n" +
|
"latitude": 7.34196905697293
|
||||||
" \"managingOrganization\": {\n" +
|
},
|
||||||
" \"reference\": \"#\"\n" +
|
"managingOrganization": {
|
||||||
" }\n" +
|
"reference": "#"
|
||||||
" }\n" +
|
}
|
||||||
" ],\n" +
|
}
|
||||||
" \"type\": [\n" +
|
],
|
||||||
" {\n" +
|
"type": [
|
||||||
" \"coding\": [\n" +
|
{
|
||||||
" {\n" +
|
"coding": [
|
||||||
" \"system\": \"https://blah.org/fmc/OrganizationType\",\n" +
|
{
|
||||||
" \"code\": \"CLINIC\",\n" +
|
"system": "https://blah.org/fmc/OrganizationType",
|
||||||
" \"display\": \"Clinic\"\n" +
|
"code": "CLINIC",
|
||||||
" }\n" +
|
"display": "Clinic"
|
||||||
" ]\n" +
|
}
|
||||||
" }\n" +
|
]
|
||||||
" ],\n" +
|
}
|
||||||
" \"name\": \"testOrg\"\n" +
|
],
|
||||||
"}";
|
"name": "testOrg"
|
||||||
|
}""";
|
||||||
|
|
||||||
Organization org = myFhirContext.newJsonParser().parseResource(Organization.class, input);
|
Organization org = myFhirContext.newJsonParser().parseResource(Organization.class, input);
|
||||||
IIdType id = myOrganizationDao.create(org).getId();
|
IIdType id = myOrganizationDao.create(org, mySrd).getId();
|
||||||
org = myOrganizationDao.read(id);
|
org = myOrganizationDao.read(id);
|
||||||
|
|
||||||
String output = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(org);
|
String output = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(org);
|
||||||
|
@ -1095,9 +1096,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
}
|
}
|
||||||
List<IBaseResource> outcome = myClient.transaction().withResources(resources).prettyPrint().encodedXml().execute();
|
List<IBaseResource> outcome = myClient.transaction().withResources(resources).prettyPrint().encodedXml().execute();
|
||||||
|
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> assertEquals(100, myResourceTableDao.count()));
|
||||||
assertEquals(100, myResourceTableDao.count());
|
|
||||||
});
|
|
||||||
|
|
||||||
Bundle found = myClient
|
Bundle found = myClient
|
||||||
.search()
|
.search()
|
||||||
|
@ -1306,7 +1305,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateQuestionnaireResponseWithValidation() throws IOException {
|
public void testCreateQuestionnaireResponseWithValidation() {
|
||||||
CodeSystem cs = new CodeSystem();
|
CodeSystem cs = new CodeSystem();
|
||||||
cs.setUrl("http://cs");
|
cs.setUrl("http://cs");
|
||||||
cs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
cs.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||||
|
@ -1906,8 +1905,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to make sure that works too..
|
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to make sure that works too..
|
||||||
*/
|
*/
|
||||||
Socket sock = new Socket();
|
Socket sock = new Socket();
|
||||||
sock.setSoTimeout(3000);
|
try (sock) {
|
||||||
try {
|
sock.setSoTimeout(3000);
|
||||||
sock.connect(new InetSocketAddress("localhost", myPort));
|
sock.connect(new InetSocketAddress("localhost", myPort));
|
||||||
sock.getOutputStream().write(("DELETE /fhir/context/Patient?identifier=http://ghh.org/patient|" + methodName + " HTTP/1.1\n").getBytes(StandardCharsets.UTF_8));
|
sock.getOutputStream().write(("DELETE /fhir/context/Patient?identifier=http://ghh.org/patient|" + methodName + " HTTP/1.1\n").getBytes(StandardCharsets.UTF_8));
|
||||||
sock.getOutputStream().write("Host: localhost\n".getBytes(StandardCharsets.UTF_8));
|
sock.getOutputStream().write("Host: localhost\n".getBytes(StandardCharsets.UTF_8));
|
||||||
|
@ -1915,7 +1914,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
BufferedReader socketInput = new BufferedReader(new InputStreamReader(sock.getInputStream()));
|
BufferedReader socketInput = new BufferedReader(new InputStreamReader(sock.getInputStream()));
|
||||||
|
|
||||||
// String response = "";
|
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
char[] buf = new char[1000];
|
char[] buf = new char[1000];
|
||||||
while (socketInput.read(buf) != -1) {
|
while (socketInput.read(buf) != -1) {
|
||||||
|
@ -1925,9 +1923,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
ourLog.debug("Resp: {}", resp);
|
ourLog.debug("Resp: {}", resp);
|
||||||
} catch (SocketTimeoutException e) {
|
} catch (SocketTimeoutException e) {
|
||||||
e.printStackTrace();
|
ourLog.debug(e.getMessage(), e);
|
||||||
} finally {
|
|
||||||
sock.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
@ -2398,7 +2394,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
assertThat(idValues).as(idValues.toString()).hasSize(10);
|
assertThat(idValues).as(idValues.toString()).hasSize(10);
|
||||||
|
|
||||||
idValues = searchAndReturnUnqualifiedIdValues(myServerBase + "/_history?_at=gt" + InstantDt.withCurrentTime().getYear());
|
idValues = searchAndReturnUnqualifiedIdValues(myServerBase + "/_history?_at=gt" + InstantDt.withCurrentTime().getYear());
|
||||||
assertThat(idValues).hasSize(0);
|
assertThat(idValues).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2427,7 +2423,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
|
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute();
|
Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).execute();
|
||||||
assertEquals(1, history.getEntry().size());
|
assertEquals(1, history.getEntry().size());
|
||||||
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
|
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
|
||||||
// validate entry.fullUrl
|
// validate entry.fullUrl
|
||||||
|
@ -2476,7 +2472,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
|
myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute();
|
Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).execute();
|
||||||
assertEquals(1, history.getEntry().size());
|
assertEquals(1, history.getEntry().size());
|
||||||
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
|
BundleEntryComponent historyEntry0 = history.getEntry().get(0);
|
||||||
// validate entry.fullUrl
|
// validate entry.fullUrl
|
||||||
|
@ -2508,7 +2504,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
ourLog.info("Res ID: {}", id);
|
ourLog.info("Res ID: {}", id);
|
||||||
|
|
||||||
Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA).execute();
|
Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA).execute();
|
||||||
assertThat(history.getEntry()).hasSize(3);
|
assertThat(history.getEntry()).hasSize(3);
|
||||||
assertEquals(id.withVersion("3").getValue(), history.getEntry().get(0).getResource().getId());
|
assertEquals(id.withVersion("3").getValue(), history.getEntry().get(0).getResource().getId());
|
||||||
assertThat(((Patient) history.getEntry().get(0).getResource()).getName()).hasSize(1);
|
assertThat(((Patient) history.getEntry().get(0).getResource()).getName()).hasSize(1);
|
||||||
|
@ -2746,7 +2742,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
int total = 20;
|
int total = 20;
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("ORG");
|
org.setName("ORG");
|
||||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Coding tagCode = new Coding();
|
Coding tagCode = new Coding();
|
||||||
tagCode.setCode("test");
|
tagCode.setCode("test");
|
||||||
|
@ -2757,7 +2753,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
.addTag(tagCode);
|
.addTag(tagCode);
|
||||||
t.setStatus(Task.TaskStatus.REQUESTED);
|
t.setStatus(Task.TaskStatus.REQUESTED);
|
||||||
t.getOwner().setReference(orgId.getValue());
|
t.getOwner().setReference(orgId.getValue());
|
||||||
myTaskDao.create(t);
|
myTaskDao.create(t, mySrd);
|
||||||
}
|
}
|
||||||
HashSet<String> ids = new HashSet<>();
|
HashSet<String> ids = new HashSet<>();
|
||||||
|
|
||||||
|
@ -2835,12 +2831,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
if (orgCount > 0) {
|
if (orgCount > 0) {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("ORG");
|
org.setName("ORG");
|
||||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
orgCount--;
|
orgCount--;
|
||||||
t.getOwner().setReference(orgId.getValue());
|
t.getOwner().setReference(orgId.getValue());
|
||||||
}
|
}
|
||||||
myTaskDao.create(t);
|
myTaskDao.create(t, mySrd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2909,12 +2905,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
if (orgCount > 0) {
|
if (orgCount > 0) {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("ORG");
|
org.setName("ORG");
|
||||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
orgCount--;
|
orgCount--;
|
||||||
t.getOwner().setReference(orgId.getValue());
|
t.getOwner().setReference(orgId.getValue());
|
||||||
}
|
}
|
||||||
myTaskDao.create(t);
|
myTaskDao.create(t, mySrd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2961,13 +2957,13 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
public void testIncludeCountDoesntIncludeIncludes() {
|
public void testIncludeCountDoesntIncludeIncludes() {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("ORG");
|
org.setName("ORG");
|
||||||
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
|
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
Patient pt = new Patient();
|
Patient pt = new Patient();
|
||||||
pt.getManagingOrganization().setReference(orgId.getValue());
|
pt.getManagingOrganization().setReference(orgId.getValue());
|
||||||
pt.addName().setFamily("FAM" + i);
|
pt.addName().setFamily("FAM" + i);
|
||||||
myPatientDao.create(pt);
|
myPatientDao.create(pt, mySrd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bundle bundle = myClient
|
Bundle bundle = myClient
|
||||||
|
@ -3168,7 +3164,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||||
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
||||||
assertEquals(false, newPt.getActive());
|
assertFalse(newPt.getActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -3196,7 +3192,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||||
assertEquals("1", newPt.getIdElement().getVersionIdPart());
|
assertEquals("1", newPt.getIdElement().getVersionIdPart());
|
||||||
assertEquals(true, newPt.getActive());
|
assertTrue(newPt.getActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -3226,7 +3222,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||||
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
||||||
assertEquals(false, newPt.getActive());
|
assertFalse(newPt.getActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -3255,7 +3251,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||||
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
||||||
assertEquals(false, newPt.getActive());
|
assertFalse(newPt.getActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -3323,12 +3319,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
{
|
{
|
||||||
Bundle returned = myClient.search().forResource(Patient.class).encodedXml().returnBundle(Bundle.class).execute();
|
Bundle returned = myClient.search().forResource(Patient.class).encodedXml().returnBundle(Bundle.class).execute();
|
||||||
assertThat(returned.getEntry().size()).isGreaterThan(1);
|
assertThat(returned.getEntry()).hasSizeGreaterThan(1);
|
||||||
assertEquals(BundleType.SEARCHSET, returned.getType());
|
assertEquals(BundleType.SEARCHSET, returned.getType());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Bundle returned = myClient.search().forResource(Patient.class).encodedJson().returnBundle(Bundle.class).execute();
|
Bundle returned = myClient.search().forResource(Patient.class).encodedJson().returnBundle(Bundle.class).execute();
|
||||||
assertThat(returned.getEntry().size()).isGreaterThan(1);
|
assertThat(returned.getEntry()).hasSizeGreaterThan(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3350,7 +3346,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Bundle bundle = myClient.history().onServer().andReturnBundle(Bundle.class).execute();
|
Bundle bundle = myClient.history().onServer().returnBundle(Bundle.class).execute();
|
||||||
assertEquals(1, bundle.getTotal());
|
assertEquals(1, bundle.getTotal());
|
||||||
assertThat(bundle.getEntry()).hasSize(1);
|
assertThat(bundle.getEntry()).hasSize(1);
|
||||||
assertEquals(id2.getIdPart(), bundle.getEntry().get(0).getResource().getIdElement().getIdPart());
|
assertEquals(id2.getIdPart(), bundle.getEntry().get(0).getResource().getIdElement().getIdPart());
|
||||||
|
@ -3507,15 +3503,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
assertThat(text).doesNotContain("\"B\"");
|
assertThat(text).doesNotContain("\"B\"");
|
||||||
assertThat(text).doesNotContain("\"B1\"");
|
assertThat(text).doesNotContain("\"B1\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// HttpGet read = new HttpGet(ourServerBase + "/Observation?patient=P5000000302&_sort:desc=code&code:in=http://fkcfhir.org/fhir/vs/ccdacapddialysisorder");
|
|
||||||
// try (CloseableHttpResponse response = ourHttpClient.execute(read)) {
|
|
||||||
// String text = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
|
||||||
// ourLog.info(text);
|
|
||||||
// assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatusLine().getStatusCode());
|
|
||||||
// assertThat(text).doesNotContain("\"text\",\"type\"");
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -3873,9 +3860,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
p.addName().setFamily(methodName + "1");
|
p.addName().setFamily(methodName + "1");
|
||||||
IIdType pid1 = myClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
IIdType pid1 = myClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Thread.sleep(10);
|
|
||||||
long time1 = System.currentTimeMillis();
|
long time1 = System.currentTimeMillis();
|
||||||
Thread.sleep(10);
|
|
||||||
|
|
||||||
Patient p2 = new Patient();
|
Patient p2 = new Patient();
|
||||||
p2.addName().setFamily(methodName + "2");
|
p2.addName().setFamily(methodName + "2");
|
||||||
|
@ -4064,9 +4049,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
public void testSearchLastUpdatedParamRp() throws InterruptedException {
|
public void testSearchLastUpdatedParamRp() throws InterruptedException {
|
||||||
String methodName = "testSearchLastUpdatedParamRp";
|
String methodName = "testSearchLastUpdatedParamRp";
|
||||||
|
|
||||||
int sleep = 100;
|
|
||||||
Thread.sleep(sleep);
|
|
||||||
|
|
||||||
DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
|
DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
|
||||||
IIdType id1a;
|
IIdType id1a;
|
||||||
{
|
{
|
||||||
|
@ -4083,9 +4065,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
id1b = myClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
id1b = myClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.sleep(1100);
|
|
||||||
DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
|
DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI);
|
||||||
Thread.sleep(1100);
|
|
||||||
|
|
||||||
IIdType id2;
|
IIdType id2;
|
||||||
{
|
{
|
||||||
|
@ -4249,13 +4229,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
|
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
|
||||||
matches = bundle.getEntry().size();
|
matches = bundle.getEntry().size();
|
||||||
|
|
||||||
assertThat(matches).isGreaterThan(0);
|
assertThat(matches).isPositive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchReturnsSearchDate() throws Exception {
|
public void testSearchReturnsSearchDate() throws Exception {
|
||||||
Date before = new Date();
|
Date before = new Date();
|
||||||
Thread.sleep(1);
|
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Bundle found = myClient
|
Bundle found = myClient
|
||||||
|
@ -4266,7 +4245,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
Thread.sleep(1);
|
|
||||||
Date after = new Date();
|
Date after = new Date();
|
||||||
|
|
||||||
InstantType updated = found.getMeta().getLastUpdatedElement();
|
InstantType updated = found.getMeta().getLastUpdatedElement();
|
||||||
|
@ -4300,7 +4278,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4313,7 +4291,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4326,7 +4304,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4339,24 +4317,24 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
// > 1m
|
// > 1m
|
||||||
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m");
|
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m");
|
||||||
ourLog.info("uri = " + uri);
|
ourLog.info("uri = {}", uri);
|
||||||
List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||||
assertThat(ids).hasSize(3);
|
assertThat(ids).hasSize(3);
|
||||||
|
|
||||||
//>= 100cm
|
//>= 100cm
|
||||||
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm");
|
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm");
|
||||||
ourLog.info("uri = " + uri);
|
ourLog.info("uri = {}", uri);
|
||||||
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||||
assertThat(ids).hasSize(3);
|
assertThat(ids).hasSize(3);
|
||||||
|
|
||||||
//>= 10dm
|
//>= 10dm
|
||||||
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm");
|
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm");
|
||||||
ourLog.info("uri = " + uri);
|
ourLog.info("uri = {}", uri);
|
||||||
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||||
assertThat(ids).hasSize(3);
|
assertThat(ids).hasSize(3);
|
||||||
}
|
}
|
||||||
|
@ -4381,7 +4359,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4392,7 +4370,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4403,7 +4381,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4414,7 +4392,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
String uri;
|
String uri;
|
||||||
|
@ -4451,7 +4429,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4462,7 +4440,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4474,7 +4452,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
|
@ -4490,8 +4468,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
//-- check use normalized quantity table to search
|
//-- check use normalized quantity table to search
|
||||||
String searchSql = myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, true);
|
String searchSql = myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, true);
|
||||||
assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0");
|
assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0").contains("HFJ_SPIDX_QUANTITY_NRML");
|
||||||
assertThat(searchSql).contains("HFJ_SPIDX_QUANTITY_NRML");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -5044,7 +5021,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -5056,7 +5033,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -5068,7 +5045,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -5080,7 +5057,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
String uri = myServerBase + "/Observation?_sort=code-value-quantity";
|
String uri = myServerBase + "/Observation?_sort=code-value-quantity";
|
||||||
|
@ -5092,7 +5069,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
found = myFhirContext.newXmlParser().parseResource(Bundle.class, output);
|
found = myFhirContext.newXmlParser().parseResource(Bundle.class, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Bundle: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
|
ourLog.debug("Bundle: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
|
||||||
|
|
||||||
List<IIdType> list = toUnqualifiedVersionlessIds(found);
|
List<IIdType> list = toUnqualifiedVersionlessIds(found);
|
||||||
assertThat(found.getEntry()).hasSize(4);
|
assertThat(found.getEntry()).hasSize(4);
|
||||||
|
@ -5129,7 +5106,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -5145,7 +5122,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -5161,7 +5138,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -5176,7 +5153,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
comp.setValue(new Quantity().setValue(250));
|
comp.setValue(new Quantity().setValue(250));
|
||||||
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
String uri = myServerBase + "/Observation?_sort=combo-code-value-quantity";
|
String uri = myServerBase + "/Observation?_sort=combo-code-value-quantity";
|
||||||
|
@ -5188,7 +5165,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
found = myFhirContext.newXmlParser().parseResource(Bundle.class, output);
|
found = myFhirContext.newXmlParser().parseResource(Bundle.class, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Bundle: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
|
ourLog.debug("Bundle: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found));
|
||||||
|
|
||||||
List<IIdType> list = toUnqualifiedVersionlessIds(found);
|
List<IIdType> list = toUnqualifiedVersionlessIds(found);
|
||||||
assertThat(found.getEntry()).hasSize(4);
|
assertThat(found.getEntry()).hasSize(4);
|
||||||
|
@ -5264,9 +5241,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
List<IIdType> list = toUnqualifiedVersionlessIds(found);
|
List<IIdType> list = toUnqualifiedVersionlessIds(found);
|
||||||
ourLog.info(methodName + " found: " + list.toString() + " - Wanted " + orgMissing + " but not " + orgNotMissing);
|
ourLog.info(methodName + " found: " + list.toString() + " - Wanted " + orgMissing + " but not " + orgNotMissing);
|
||||||
assertThat(list).doesNotContain(orgNotMissing);
|
assertThat(list).doesNotContain(orgNotMissing).doesNotContain(deletedIdMissingTrue).contains(orgMissing);
|
||||||
assertThat(list).doesNotContain(deletedIdMissingTrue);
|
|
||||||
assertThat(list).contains(orgMissing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -5927,7 +5902,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
Date before = new Date();
|
Date before = new Date();
|
||||||
Thread.sleep(100);
|
|
||||||
|
|
||||||
pt = new Patient();
|
pt = new Patient();
|
||||||
pt.setId(id.getIdPart());
|
pt.setId(id.getIdPart());
|
||||||
|
@ -6450,7 +6424,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
|
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
|
||||||
obs.setValue(new Quantity().setValueElement(new DecimalType(125.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"));
|
obs.setValue(new Quantity().setValueElement(new DecimalType(125.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"));
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
|
|
||||||
IIdType opid1 = myObservationDao.create(obs, mySrd).getId();
|
IIdType opid1 = myObservationDao.create(obs, mySrd).getId();
|
||||||
|
|
||||||
|
@ -6463,7 +6437,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
|
cc.addCoding().setCode("2345-7").setSystem("http://loinc.org");
|
||||||
obs.setValue(new Quantity().setValueElement(new DecimalType(24.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"));
|
obs.setValue(new Quantity().setValueElement(new DecimalType(24.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"));
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
|
|
||||||
myObservationDao.update(obs, mySrd);
|
myObservationDao.update(obs, mySrd);
|
||||||
}
|
}
|
||||||
|
@ -6479,7 +6453,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -6492,7 +6466,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -6505,25 +6479,25 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
myObservationDao.create(obs, mySrd);
|
myObservationDao.create(obs, mySrd);
|
||||||
|
|
||||||
ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs));
|
||||||
}
|
}
|
||||||
|
|
||||||
// > 1m
|
// > 1m
|
||||||
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m");
|
String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m");
|
||||||
ourLog.info("uri = " + uri);
|
ourLog.info("uri = {}", uri);
|
||||||
List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||||
assertThat(ids).hasSize(2);
|
assertThat(ids).hasSize(2);
|
||||||
|
|
||||||
|
|
||||||
//>= 100cm
|
//>= 100cm
|
||||||
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm");
|
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm");
|
||||||
ourLog.info("uri = " + uri);
|
ourLog.info("uri = {}", uri);
|
||||||
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||||
assertThat(ids).hasSize(2);
|
assertThat(ids).hasSize(2);
|
||||||
|
|
||||||
//>= 10dm
|
//>= 10dm
|
||||||
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm");
|
uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm");
|
||||||
ourLog.info("uri = " + uri);
|
ourLog.info("uri = {}", uri);
|
||||||
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||||
assertThat(ids).hasSize(2);
|
assertThat(ids).hasSize(2);
|
||||||
}
|
}
|
||||||
|
@ -6540,7 +6514,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
patient.setBirthDateElement(new DateType("2073"));
|
patient.setBirthDateElement(new DateType("2073"));
|
||||||
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient));
|
ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient));
|
||||||
|
|
||||||
ourLog.info("pid0 " + pid0);
|
ourLog.info("pid0 " + pid0);
|
||||||
}
|
}
|
||||||
|
@ -6553,7 +6527,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(resp);
|
ourLog.info(resp);
|
||||||
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
|
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
|
||||||
ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
|
ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = myServerBase + "/Patient?_total=accurate&birthdate=gt2072-01-01";
|
uri = myServerBase + "/Patient?_total=accurate&birthdate=gt2072-01-01";
|
||||||
|
@ -6564,7 +6538,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(resp);
|
ourLog.info(resp);
|
||||||
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
|
Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp);
|
||||||
ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
|
ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6995,9 +6969,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
&& theInput.IsEnforceRefOnType
|
&& theInput.IsEnforceRefOnType
|
||||||
&& theInput.IsEnforceRefOnWrite).isFalse();
|
&& theInput.IsEnforceRefOnWrite).isFalse();
|
||||||
} catch (InvalidRequestException ex) {
|
} catch (InvalidRequestException ex) {
|
||||||
assertThat(ex.getMessage().contains(
|
assertThat(ex.getMessage()).as(ex.getMessage()).contains("Invalid resource reference");
|
||||||
"Invalid resource reference"
|
|
||||||
)).as(ex.getMessage()).isTrue();
|
|
||||||
} finally {
|
} finally {
|
||||||
myStorageSettings.setEnforceReferentialIntegrityOnWrite(isEnforceRefOnWrite);
|
myStorageSettings.setEnforceReferentialIntegrityOnWrite(isEnforceRefOnWrite);
|
||||||
myStorageSettings.setEnforceReferenceTargetTypes(isEnforceRefTargetTypes);
|
myStorageSettings.setEnforceReferenceTargetTypes(isEnforceRefTargetTypes);
|
||||||
|
@ -7331,9 +7303,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
patient.setBirthDate(cal.getTime());
|
patient.setBirthDate(cal.getTime());
|
||||||
}
|
}
|
||||||
return patient;
|
return patient;
|
||||||
}, (isMissing) -> {
|
}, (isMissing) -> doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing)));
|
||||||
return doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
@ -7346,9 +7316,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
patient.setGender(AdministrativeGender.FEMALE);
|
patient.setGender(AdministrativeGender.FEMALE);
|
||||||
}
|
}
|
||||||
return patient;
|
return patient;
|
||||||
}, isMissing -> {
|
}, isMissing -> doSearch(Patient.class, Patient.GENDER.isMissing(isMissing)));
|
||||||
return doSearch(Patient.class, Patient.GENDER.isMissing(isMissing));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
@ -7364,9 +7332,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
patient.setGeneralPractitioner(Collections.singletonList(new Reference(practitionerId)));
|
patient.setGeneralPractitioner(Collections.singletonList(new Reference(practitionerId)));
|
||||||
}
|
}
|
||||||
return patient;
|
return patient;
|
||||||
}, isMissing -> {
|
}, isMissing -> doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing)));
|
||||||
return doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
@ -7409,9 +7375,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
sp.setUrl("http://example.com");
|
sp.setUrl("http://example.com");
|
||||||
}
|
}
|
||||||
return sp;
|
return sp;
|
||||||
}, isMissing -> {
|
}, isMissing -> doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing)));
|
||||||
return doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
@ -7424,9 +7388,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
obs.setValue(new Quantity(3));
|
obs.setValue(new Quantity(3));
|
||||||
}
|
}
|
||||||
return obs;
|
return obs;
|
||||||
}, isMissing -> {
|
}, isMissing -> doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing)));
|
||||||
return doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
@ -7457,7 +7419,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
Y doTask(X theInput);
|
Y doTask(X theInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MissingSearchTestParameters {
|
public static class MissingSearchTestParameters {
|
||||||
/**
|
/**
|
||||||
* The setting for IndexMissingFields
|
* The setting for IndexMissingFields
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package ca.uhn.fhir.jpa.term;
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
|
||||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
|
||||||
import ca.uhn.fhir.context.support.LookupCodeRequest;
|
import ca.uhn.fhir.context.support.LookupCodeRequest;
|
||||||
|
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.config.JpaConfig;
|
import ca.uhn.fhir.jpa.config.JpaConfig;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
|
@ -20,9 +19,10 @@ import ca.uhn.fhir.rest.param.UriParam;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
import org.hl7.fhir.r4.model.CodeType;
|
import org.hl7.fhir.r4.model.CodeType;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
@ -40,8 +40,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -82,14 +80,12 @@ import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_UPLOAD_
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_XML_FILE;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_XML_FILE;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_ALL_VALUESET_ID;
|
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_ALL_VALUESET_ID;
|
||||||
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
|
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,9 +137,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
@Autowired
|
@Autowired
|
||||||
private Batch2JobHelper myBatchJobHelper;
|
private Batch2JobHelper myBatchJobHelper;
|
||||||
|
|
||||||
|
private final ServletRequestDetails myRequestDetails = new ServletRequestDetails();
|
||||||
private ZipCollectionBuilder myFiles;
|
|
||||||
private ServletRequestDetails myRequestDetails = new ServletRequestDetails();
|
|
||||||
|
|
||||||
private Properties uploadProperties;
|
private Properties uploadProperties;
|
||||||
private IFhirResourceDao<ValueSet> myValueSetIFhirResourceDao;
|
private IFhirResourceDao<ValueSet> myValueSetIFhirResourceDao;
|
||||||
|
@ -182,17 +176,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
|
|
||||||
private void validateValidateCode(String theCurrentVersion, Collection<String> allVersions) {
|
private void validateValidateCode(String theCurrentVersion, Collection<String> allVersions) {
|
||||||
IValidationSupport.CodeValidationResult resultNoVersioned = myCodeSystemDao.validateCode(null,
|
validateValidateCodeForVersion(theCurrentVersion);
|
||||||
new UriType(BASE_LOINC_URL), null, new CodeType(VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE),
|
|
||||||
null, null, null, null);
|
|
||||||
assertNotNull(resultNoVersioned);
|
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultNoVersioned.getDisplay());
|
|
||||||
|
|
||||||
IValidationSupport.CodeValidationResult resultVersioned = myCodeSystemDao.validateCode(null,
|
|
||||||
new UriType(BASE_LOINC_URL), null, new CodeType(VS_VERSIONED_ON_UPLOAD_FIRST_CODE),
|
|
||||||
null, null, null, null);
|
|
||||||
assertNotNull(resultVersioned);
|
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultVersioned.getDisplay());
|
|
||||||
|
|
||||||
allVersions.forEach(this::validateValidateCodeForVersion);
|
allVersions.forEach(this::validateValidateCodeForVersion);
|
||||||
}
|
}
|
||||||
|
@ -215,13 +199,15 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
private void validateValueLookup(String theCurrentVersion, Collection<String> allVersions) {
|
private void validateValueLookup(String theCurrentVersion, Collection<String> allVersions) {
|
||||||
IValidationSupport.LookupCodeResult resultNoVer = myValidationSupport.lookupCode(
|
IValidationSupport.LookupCodeResult resultNoVer = myValidationSupport.lookupCode(
|
||||||
new ValidationSupportContext(myValidationSupport), new LookupCodeRequest(BASE_LOINC_URL, VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE));
|
new ValidationSupportContext(myValidationSupport),
|
||||||
|
new LookupCodeRequest(BASE_LOINC_URL, VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE));
|
||||||
assertNotNull(resultNoVer);
|
assertNotNull(resultNoVer);
|
||||||
String expectedNoVer = prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
|
String expectedNoVer = prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
|
||||||
assertEquals(expectedNoVer, resultNoVer.getCodeDisplay());
|
assertEquals(expectedNoVer, resultNoVer.getCodeDisplay());
|
||||||
|
|
||||||
IValidationSupport.LookupCodeResult resultWithVer = myValidationSupport.lookupCode(
|
IValidationSupport.LookupCodeResult resultWithVer = myValidationSupport.lookupCode(
|
||||||
new ValidationSupportContext(myValidationSupport), new LookupCodeRequest(BASE_LOINC_URL, VS_VERSIONED_ON_UPLOAD_FIRST_CODE));
|
new ValidationSupportContext(myValidationSupport),
|
||||||
|
new LookupCodeRequest(BASE_LOINC_URL, VS_VERSIONED_ON_UPLOAD_FIRST_CODE));
|
||||||
assertNotNull(resultWithVer);
|
assertNotNull(resultWithVer);
|
||||||
String expectedWithVer = prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
|
String expectedWithVer = prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY);
|
||||||
assertEquals(expectedWithVer, resultWithVer.getCodeDisplay());
|
assertEquals(expectedWithVer, resultWithVer.getCodeDisplay());
|
||||||
|
@ -278,42 +264,28 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
private void validateExpandedTermConcepts(String theCurrentVersion, Collection<String> theAllVersions) {
|
private void validateExpandedTermConcepts(String theCurrentVersion, Collection<String> theAllVersions) {
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
TermConcept termConceptNoVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
|
TermConcept termConceptNoVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
|
||||||
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
|
||||||
VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
|
|
||||||
assertNotNull(termConceptNoVerCsvNoVer);
|
|
||||||
// data should have version because it was loaded with a version
|
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptNoVerCsvNoVer.getDisplay());
|
|
||||||
|
|
||||||
TermConcept termConceptVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
|
|
||||||
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
|
||||||
VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
|
|
||||||
assertNotNull(termConceptVerCsvNoVer);
|
|
||||||
// data should have version because it was loaded with a version
|
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvNoVer.getDisplay());
|
|
||||||
|
|
||||||
if (theCurrentVersion != null) {
|
|
||||||
TermConcept termConceptNoVerCsvVer = (TermConcept) myEntityManager.createQuery(
|
|
||||||
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
||||||
VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId = '" + theCurrentVersion + "'").getSingleResult();
|
VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
|
||||||
assertNotNull(termConceptNoVerCsvVer);
|
assertNotNull(termConceptNoVerCsvNoVer);
|
||||||
// data should have version because it was loaded with a version
|
// data should have version because it was loaded with a version
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptNoVerCsvVer.getDisplay());
|
assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptNoVerCsvNoVer.getDisplay());
|
||||||
|
|
||||||
TermConcept termConceptVerCsvVer = (TermConcept) myEntityManager.createQuery(
|
TermConcept termConceptVerCsvNoVer = (TermConcept) myEntityManager.createQuery(
|
||||||
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
||||||
VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId = '" + theCurrentVersion + "'").getSingleResult();
|
VS_VERSIONED_ON_UPLOAD_FIRST_CODE + "' and tcsv.myCodeSystemVersionId is null").getSingleResult();
|
||||||
assertNotNull(termConceptVerCsvVer);
|
assertNotNull(termConceptVerCsvNoVer);
|
||||||
// data should have version because it was loaded with a version
|
// data should have version because it was loaded with a version
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvVer.getDisplay());
|
assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), termConceptVerCsvNoVer.getDisplay());
|
||||||
}
|
|
||||||
|
|
||||||
theAllVersions.forEach(this::validateExpandedTermConceptsForVersion);
|
if (theCurrentVersion != null) {
|
||||||
|
validateExpandedTermConceptsForVersion(theCurrentVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
theAllVersions.forEach(this::validateExpandedTermConceptsForVersion);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void validateExpandedTermConceptsForVersion(String theVersion) {
|
private void validateExpandedTermConceptsForVersion(String theVersion) {
|
||||||
TermConcept termConceptNoVer = (TermConcept) myEntityManager.createQuery(
|
TermConcept termConceptNoVer = (TermConcept) myEntityManager.createQuery(
|
||||||
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
"select tc from TermConcept tc join fetch tc.myCodeSystem tcsv where tc.myCode = '" +
|
||||||
|
@ -384,7 +356,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
* no the CodeSystem version.
|
* no the CodeSystem version.
|
||||||
*/
|
*/
|
||||||
private void validateValueSetSearchForVersion(String theVersion) {
|
private void validateValueSetSearchForVersion(String theVersion) {
|
||||||
// for no versioned VS (VS version, different than CS version)
|
// for no versioned VS (VS version, different from CS version)
|
||||||
|
|
||||||
SearchParameterMap paramsUploadNoVer = new SearchParameterMap("url", new UriParam(VS_NO_VERSIONED_ON_UPLOAD));
|
SearchParameterMap paramsUploadNoVer = new SearchParameterMap("url", new UriParam(VS_NO_VERSIONED_ON_UPLOAD));
|
||||||
paramsUploadNoVer.add("version", new TokenParam(theVersion));
|
paramsUploadNoVer.add("version", new TokenParam(theVersion));
|
||||||
|
@ -398,7 +370,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
assertEquals(expectedLoadNoVersionUnqualifiedId, loadNoVersionValueSet.getIdElement().getIdPart());
|
assertEquals(expectedLoadNoVersionUnqualifiedId, loadNoVersionValueSet.getIdElement().getIdPart());
|
||||||
|
|
||||||
|
|
||||||
// versioned VS (VS version, different than CS version)
|
// versioned VS (VS version, different from CS version)
|
||||||
|
|
||||||
SearchParameterMap paramsUploadVer = new SearchParameterMap("url", new UriParam(VS_VERSIONED_ON_UPLOAD));
|
SearchParameterMap paramsUploadVer = new SearchParameterMap("url", new UriParam(VS_VERSIONED_ON_UPLOAD));
|
||||||
paramsUploadVer.add("version", new TokenParam(VS_ANSWER_LIST_VERSION + "-" + theVersion));
|
paramsUploadVer.add("version", new TokenParam(VS_ANSWER_LIST_VERSION + "-" + theVersion));
|
||||||
|
@ -437,8 +409,8 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
Set<String> theExpectedIdVersionsPlusNull = Sets.newHashSet(theExpectedIdVersions);
|
Set<String> theExpectedIdVersionsPlusNull = Sets.newHashSet(theExpectedIdVersions);
|
||||||
theExpectedIdVersionsPlusNull.add(null);
|
theExpectedIdVersionsPlusNull.add(null);
|
||||||
assertThat(theExpectedIdVersionsPlusNull).containsExactlyInAnyOrderElementsOf(theValueSets.stream().map(r -> ((ValueSet) r).getVersion()).toList());
|
List<String> valueSetVersions = theValueSets.stream().map(r -> ((ValueSet) r).getVersion()).toList();
|
||||||
|
assertThat(valueSetVersions).containsExactlyInAnyOrderElementsOf(theExpectedIdVersionsPlusNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -455,14 +427,13 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
// for CodeSystem:
|
// for CodeSystem:
|
||||||
|
|
||||||
// _ current CS is present and has no version
|
// _ current CS is present and has no version
|
||||||
CodeSystem codeSystem = myCodeSystemDao.read(new IdType(LOINC_LOW));
|
CodeSystem codeSystem = myCodeSystemDao.read(new IdType(LOINC_LOW), myRequestDetails);
|
||||||
String csString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem);
|
String csString = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem);
|
||||||
ourLog.info("CodeSystem:\n" + csString);
|
ourLog.info("CodeSystem:\n {}", csString);
|
||||||
|
|
||||||
HashSet<String> shouldNotBePresentVersions = new HashSet<>(possibleVersions);
|
HashSet<String> shouldNotBePresentVersions = new HashSet<>(possibleVersions);
|
||||||
theAllVersions.forEach(shouldNotBePresentVersions::remove);
|
theAllVersions.forEach(shouldNotBePresentVersions::remove);
|
||||||
shouldNotBePresentVersions.forEach(vv -> assertFalse(csString.contains(vv),
|
assertThat(shouldNotBePresentVersions).noneSatisfy(vv -> assertThat(vv).isEqualTo(codeSystem.getVersion()));
|
||||||
"Found version string: '" + vv + "' in CodeSystem: " + csString));
|
|
||||||
|
|
||||||
// same reading it from term service
|
// same reading it from term service
|
||||||
CodeSystem cs = myITermReadSvc.fetchCanonicalCodeSystemFromCompleteContext(BASE_LOINC_URL);
|
CodeSystem cs = myITermReadSvc.fetchCanonicalCodeSystemFromCompleteContext(BASE_LOINC_URL);
|
||||||
|
@ -501,7 +472,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
public void uploadCurrentNoVersion() throws Exception {
|
public void uploadCurrentNoVersion() throws Exception {
|
||||||
IIdType csId = uploadLoincCodeSystem(null, true);
|
uploadLoincCodeSystem(null, true);
|
||||||
|
|
||||||
runCommonValidations(Collections.emptyList());
|
runCommonValidations(Collections.emptyList());
|
||||||
|
|
||||||
|
@ -516,7 +487,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
@Test()
|
@Test()
|
||||||
public void uploadWithVersion() throws Exception {
|
public void uploadWithVersion() throws Exception {
|
||||||
String ver = "2.67";
|
String ver = "2.67";
|
||||||
IIdType csId = uploadLoincCodeSystem(ver, true);
|
uploadLoincCodeSystem(ver, true);
|
||||||
|
|
||||||
runCommonValidations(Collections.singletonList(ver));
|
runCommonValidations(Collections.singletonList(ver));
|
||||||
|
|
||||||
|
@ -637,25 +608,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
assertThat(vsContainsDisplay).contains(expectedDisplay);
|
assertThat(vsContainsDisplay).contains(expectedDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void validateValidateCodeLoincAllVS(String theCurrentVersion, Collection<String> allVersions) {
|
|
||||||
IValidationSupport.CodeValidationResult resultNoVersioned = myCodeSystemDao.validateCode(null,
|
|
||||||
new UriType(BASE_LOINC_URL), null, new CodeType(VS_NO_VERSIONED_ON_UPLOAD_FIRST_CODE),
|
|
||||||
null, null, null, null);
|
|
||||||
assertNotNull(resultNoVersioned);
|
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_NO_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultNoVersioned.getDisplay());
|
|
||||||
|
|
||||||
IValidationSupport.CodeValidationResult resultVersioned = myCodeSystemDao.validateCode(null,
|
|
||||||
new UriType(BASE_LOINC_URL), null, new CodeType(VS_VERSIONED_ON_UPLOAD_FIRST_CODE),
|
|
||||||
null, null, null, null);
|
|
||||||
assertNotNull(resultVersioned);
|
|
||||||
assertEquals(prefixWithVersion(theCurrentVersion, VS_VERSIONED_ON_UPLOAD_FIRST_DISPLAY), resultVersioned.getDisplay());
|
|
||||||
|
|
||||||
allVersions.forEach(this::validateValidateCodeForVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void validateValueExpandLoincAllVsForVersion(String theVersion) {
|
private void validateValueExpandLoincAllVsForVersion(String theVersion) {
|
||||||
ValueSet vs = myValueSetDao.expandByIdentifier(LOINC_ALL_VS_URL + "|" + theVersion, null);
|
ValueSet vs = myValueSetDao.expandByIdentifier(LOINC_ALL_VS_URL + "|" + theVersion, null);
|
||||||
assertThat(vs.getExpansion().getContains()).hasSize(ALL_VS_QTY);
|
assertThat(vs.getExpansion().getContains()).hasSize(ALL_VS_QTY);
|
||||||
|
@ -664,7 +616,6 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
checkContainsElementVersion(vs, theVersion);
|
checkContainsElementVersion(vs, theVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates TermConcepts were created in the sequence indicated by the parameters
|
* Validates TermConcepts were created in the sequence indicated by the parameters
|
||||||
* and their displays match the expected versions
|
* and their displays match the expected versions
|
||||||
|
@ -735,8 +686,8 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private IIdType uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception {
|
private void uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception {
|
||||||
myFiles = new ZipCollectionBuilder();
|
ZipCollectionBuilder files = new ZipCollectionBuilder();
|
||||||
|
|
||||||
myRequestDetails.getUserData().put(LOINC_CODESYSTEM_MAKE_CURRENT, theMakeItCurrent);
|
myRequestDetails.getUserData().put(LOINC_CODESYSTEM_MAKE_CURRENT, theMakeItCurrent);
|
||||||
uploadProperties.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), Boolean.toString(theMakeItCurrent));
|
uploadProperties.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), Boolean.toString(theMakeItCurrent));
|
||||||
|
@ -749,12 +700,10 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
uploadProperties.put(LOINC_CODESYSTEM_VERSION.getCode(), theVersion);
|
uploadProperties.put(LOINC_CODESYSTEM_VERSION.getCode(), theVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
addLoincMandatoryFilesToZip(myFiles, theVersion);
|
addLoincMandatoryFilesToZip(files, theVersion);
|
||||||
|
|
||||||
UploadStatistics stats = myTermLoaderSvc.loadLoinc(myFiles.getFiles(), mySrd);
|
myTermLoaderSvc.loadLoinc(files.getFiles(), mySrd);
|
||||||
myTerminologyDeferredStorageSvc.saveAllDeferred();
|
myTerminologyDeferredStorageSvc.saveAllDeferred();
|
||||||
|
|
||||||
return stats.getTarget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -787,10 +736,12 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
private TermCodeSystemVersion fetchCurrentCodeSystemVersion() {
|
private TermCodeSystemVersion fetchCurrentCodeSystemVersion() {
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
List<TermCodeSystem> tcsList = myEntityManager.createQuery("from TermCodeSystem").getResultList();
|
List<TermCodeSystem> tcsList = myEntityManager.createQuery("from TermCodeSystem").getResultList();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
List<TermCodeSystemVersion> tcsvList = myEntityManager.createQuery("from TermCodeSystemVersion").getResultList();
|
List<TermCodeSystemVersion> tcsvList = myEntityManager.createQuery("from TermCodeSystemVersion").getResultList();
|
||||||
ourLog.error("tcslist: {}", tcsList.stream().map(tcs -> tcs.toString()).collect(joining("\n", "\n", "")));
|
ourLog.error("tcslist: {}", tcsList.stream().map(TermCodeSystem::toString).collect(joining("\n", "\n", "")));
|
||||||
ourLog.error("tcsvlist: {}", tcsvList.stream().map(v -> v.toString()).collect(joining("\n", "\n", "")));
|
ourLog.error("tcsvlist: {}", tcsvList.stream().map(TermCodeSystemVersion::toString).collect(joining("\n", "\n", "")));
|
||||||
|
|
||||||
if (tcsList.size() != 1) {
|
if (tcsList.size() != 1) {
|
||||||
throw new IllegalStateException("More than one TCS: " +
|
throw new IllegalStateException("More than one TCS: " +
|
||||||
|
@ -807,8 +758,9 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void addBaseLoincMandatoryFilesToZip(
|
private static void addBaseLoincMandatoryFilesToZip(ZipCollectionBuilder theFiles,
|
||||||
ZipCollectionBuilder theFiles, Boolean theIncludeTop2000, String theClassPathPrefix) throws IOException {
|
@SuppressWarnings("SameParameterValue") Boolean theIncludeTop2000,
|
||||||
|
String theClassPathPrefix) throws IOException {
|
||||||
theFiles.addFileZip(theClassPathPrefix, LOINC_XML_FILE.getCode());
|
theFiles.addFileZip(theClassPathPrefix, LOINC_XML_FILE.getCode());
|
||||||
theFiles.addFileZip(theClassPathPrefix, LOINC_GROUP_FILE_DEFAULT.getCode());
|
theFiles.addFileZip(theClassPathPrefix, LOINC_GROUP_FILE_DEFAULT.getCode());
|
||||||
theFiles.addFileZip(theClassPathPrefix, LOINC_GROUP_TERMS_FILE_DEFAULT.getCode());
|
theFiles.addFileZip(theClassPathPrefix, LOINC_GROUP_TERMS_FILE_DEFAULT.getCode());
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -45,7 +45,7 @@ public interface ICdsServiceRegistry {
|
||||||
* @param theCdsServiceRequestJson the service request
|
* @param theCdsServiceRequestJson the service request
|
||||||
* @return the service response
|
* @return the service response
|
||||||
*/
|
*/
|
||||||
CdsServiceResponseJson callService(String theServiceId, CdsServiceRequestJson theCdsServiceRequestJson);
|
CdsServiceResponseJson callService(String theServiceId, Object theCdsServiceRequestJson);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the REST method available at https://example.com/cds-services/{theServiceId}/feedback
|
* This is the REST method available at https://example.com/cds-services/{theServiceId}/feedback
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
package ca.uhn.hapi.fhir.cdshooks.api.json;
|
package ca.uhn.hapi.fhir.cdshooks.api.json;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Users can define CDS Hooks extensions by extending this class.
|
* Users can define CDS Hooks extensions by extending this class.
|
||||||
* Implementors can extend this class for defining their custom extensions.
|
* Implementors can extend this class for defining their custom extensions.
|
||||||
*/
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class CdsHooksExtension implements IModelJson {}
|
public class CdsHooksExtension implements IModelJson {}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.hapi.fhir.cdshooks.api.json;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -29,6 +30,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class CdsServiceRequestContextJson extends BaseCdsServiceJson implements IModelJson {
|
public class CdsServiceRequestContextJson extends BaseCdsServiceJson implements IModelJson {
|
||||||
|
|
||||||
@JsonAnyGetter
|
@JsonAnyGetter
|
||||||
|
|
|
@ -31,6 +31,7 @@ import ca.uhn.hapi.fhir.cdshooks.api.ICdsConfigService;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.ICdsHooksDaoAuthorizationSvc;
|
import ca.uhn.hapi.fhir.cdshooks.api.ICdsHooksDaoAuthorizationSvc;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
|
import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.module.CdsHooksObjectMapperFactory;
|
import ca.uhn.hapi.fhir.cdshooks.module.CdsHooksObjectMapperFactory;
|
||||||
|
import ca.uhn.hapi.fhir.cdshooks.serializer.CdsServiceRequestJsonDeserializer;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.CdsConfigServiceImpl;
|
import ca.uhn.hapi.fhir.cdshooks.svc.CdsConfigServiceImpl;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.CdsHooksContextBooter;
|
import ca.uhn.hapi.fhir.cdshooks.svc.CdsHooksContextBooter;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.CdsServiceRegistryImpl;
|
import ca.uhn.hapi.fhir.cdshooks.svc.CdsServiceRegistryImpl;
|
||||||
|
@ -100,13 +101,15 @@ public class CdsHooksConfig {
|
||||||
ICdsCrServiceFactory theCdsCrServiceFactory,
|
ICdsCrServiceFactory theCdsCrServiceFactory,
|
||||||
ICrDiscoveryServiceFactory theCrDiscoveryServiceFactory,
|
ICrDiscoveryServiceFactory theCrDiscoveryServiceFactory,
|
||||||
FhirContext theFhirContext) {
|
FhirContext theFhirContext) {
|
||||||
|
final CdsServiceRequestJsonDeserializer cdsServiceRequestJsonDeserializer =
|
||||||
|
new CdsServiceRequestJsonDeserializer(theFhirContext, theObjectMapper);
|
||||||
return new CdsServiceRegistryImpl(
|
return new CdsServiceRegistryImpl(
|
||||||
theCdsHooksContextBooter,
|
theCdsHooksContextBooter,
|
||||||
theCdsPrefetchSvc,
|
theCdsPrefetchSvc,
|
||||||
theObjectMapper,
|
theObjectMapper,
|
||||||
theCdsCrServiceFactory,
|
theCdsCrServiceFactory,
|
||||||
theCrDiscoveryServiceFactory,
|
theCrDiscoveryServiceFactory,
|
||||||
theFhirContext);
|
cdsServiceRequestJsonDeserializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
@ -21,7 +21,6 @@ package ca.uhn.hapi.fhir.cdshooks.controller;
|
||||||
|
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
|
import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
|
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServicesJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServicesJson;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
@ -73,7 +72,7 @@ public class CdsHooksController {
|
||||||
method = {RequestMethod.POST},
|
method = {RequestMethod.POST},
|
||||||
consumes = {MediaType.APPLICATION_JSON_VALUE})
|
consumes = {MediaType.APPLICATION_JSON_VALUE})
|
||||||
public ResponseEntity<CdsServiceResponseJson> cdsServiceRequest(
|
public ResponseEntity<CdsServiceResponseJson> cdsServiceRequest(
|
||||||
@PathVariable("cds_hook") String theCdsHook, @RequestBody CdsServiceRequestJson theCdsServiceRequestJson) {
|
@PathVariable("cds_hook") String theCdsHook, @RequestBody Object theCdsServiceRequestJson) {
|
||||||
CdsServiceResponseJson response = myCdsServiceRegistry.callService(theCdsHook, theCdsServiceRequestJson);
|
CdsServiceResponseJson response = myCdsServiceRegistry.callService(theCdsHook, theCdsServiceRequestJson);
|
||||||
return ResponseEntity.status(200)
|
return ResponseEntity.status(200)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
|
|
@ -20,84 +20,60 @@
|
||||||
package ca.uhn.hapi.fhir.cdshooks.serializer;
|
package ca.uhn.hapi.fhir.cdshooks.serializer;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.serializer.FhirResourceDeserializer;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsHooksExtension;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsHooksExtension;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.CdsServiceRegistryImpl;
|
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
import jakarta.annotation.Nonnull;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CdsServiceRequestJsonDeserializer extends StdDeserializer<CdsServiceRequestJson> {
|
public class CdsServiceRequestJsonDeserializer {
|
||||||
|
|
||||||
private final CdsServiceRegistryImpl myCdsServiceRegistry;
|
|
||||||
private final ObjectMapper myObjectMapper;
|
private final ObjectMapper myObjectMapper;
|
||||||
private final FhirContext myFhirContext;
|
private final FhirContext myFhirContext;
|
||||||
private final IParser myParser;
|
private final IParser myParser;
|
||||||
|
|
||||||
public CdsServiceRequestJsonDeserializer(CdsServiceRegistryImpl theCdsServiceRegistry, FhirContext theFhirContext) {
|
public CdsServiceRequestJsonDeserializer(
|
||||||
super(CdsServiceRequestJson.class);
|
@Nonnull FhirContext theFhirContext, @Nonnull ObjectMapper theObjectMapper) {
|
||||||
myCdsServiceRegistry = theCdsServiceRegistry;
|
|
||||||
myFhirContext = theFhirContext;
|
myFhirContext = theFhirContext;
|
||||||
myParser = myFhirContext.newJsonParser().setPrettyPrint(true);
|
myParser = myFhirContext.newJsonParser().setPrettyPrint(true);
|
||||||
// We create a new ObjectMapper instead of using the one from the ApplicationContext to avoid an infinite loop
|
myObjectMapper = theObjectMapper;
|
||||||
// during deserialization.
|
|
||||||
myObjectMapper = new ObjectMapper();
|
|
||||||
configureObjectMapper(myObjectMapper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public CdsServiceRequestJson deserialize(
|
||||||
public CdsServiceRequestJson deserialize(JsonParser theJsonParser, DeserializationContext theDeserializationContext)
|
@Nonnull CdsServiceJson theCdsServiceJson, @Nonnull Object theCdsServiceRequestJson) {
|
||||||
throws IOException {
|
final JsonNode cdsServiceRequestJsonNode =
|
||||||
final JsonNode cdsServiceRequestJsonNode = theJsonParser.getCodec().readTree(theJsonParser);
|
myObjectMapper.convertValue(theCdsServiceRequestJson, JsonNode.class);
|
||||||
final JsonNode hookNode = cdsServiceRequestJsonNode.get("hook");
|
final JsonNode contextNode = cdsServiceRequestJsonNode.get("context");
|
||||||
final JsonNode extensionNode = cdsServiceRequestJsonNode.get("extension");
|
validateHookInstance(cdsServiceRequestJsonNode.get("hookInstance"));
|
||||||
final JsonNode requestContext = cdsServiceRequestJsonNode.get("context");
|
validateHook(cdsServiceRequestJsonNode.get("hook"));
|
||||||
final CdsServiceRequestJson cdsServiceRequestJson =
|
validateContext(contextNode);
|
||||||
myObjectMapper.treeToValue(cdsServiceRequestJsonNode, CdsServiceRequestJson.class);
|
try {
|
||||||
if (extensionNode != null) {
|
final JsonNode extensionNode = cdsServiceRequestJsonNode.get("extension");
|
||||||
CdsHooksExtension myRequestExtension = deserializeExtension(hookNode.textValue(), extensionNode.toString());
|
final CdsServiceRequestJson cdsServiceRequestJson =
|
||||||
cdsServiceRequestJson.setExtension(myRequestExtension);
|
myObjectMapper.convertValue(cdsServiceRequestJsonNode, CdsServiceRequestJson.class);
|
||||||
|
LinkedHashMap<String, Object> map = myObjectMapper.readValue(contextNode.toString(), LinkedHashMap.class);
|
||||||
|
cdsServiceRequestJson.setContext(deserializeContext(map));
|
||||||
|
if (extensionNode != null) {
|
||||||
|
CdsHooksExtension myRequestExtension =
|
||||||
|
deserializeExtension(theCdsServiceJson, extensionNode.toString());
|
||||||
|
cdsServiceRequestJson.setExtension(myRequestExtension);
|
||||||
|
}
|
||||||
|
return cdsServiceRequestJson;
|
||||||
|
} catch (JsonProcessingException | IllegalArgumentException theEx) {
|
||||||
|
throw new InvalidRequestException(Msg.code(2551) + "Invalid CdsServiceRequest received. " + theEx);
|
||||||
}
|
}
|
||||||
if (requestContext != null) {
|
|
||||||
LinkedHashMap<String, Object> map =
|
|
||||||
myObjectMapper.readValue(requestContext.toString(), LinkedHashMap.class);
|
|
||||||
cdsServiceRequestJson.setContext(deserializeRequestContext(map));
|
|
||||||
}
|
|
||||||
return cdsServiceRequestJson;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void configureObjectMapper(ObjectMapper theObjectMapper) {
|
CdsServiceRequestContextJson deserializeContext(LinkedHashMap<String, Object> theMap)
|
||||||
SimpleModule module = new SimpleModule();
|
|
||||||
module.addDeserializer(IBaseResource.class, new FhirResourceDeserializer(myFhirContext));
|
|
||||||
theObjectMapper.registerModule(module);
|
|
||||||
// set this as we will need to ignore properties which are not defined by specific implementation.
|
|
||||||
theObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CdsHooksExtension deserializeExtension(String theServiceId, String theExtension) throws JsonProcessingException {
|
|
||||||
final CdsServiceJson cdsServicesJson = myCdsServiceRegistry.getCdsServiceJson(theServiceId);
|
|
||||||
Class<? extends CdsHooksExtension> extensionClass = cdsServicesJson.getExtensionClass();
|
|
||||||
if (extensionClass == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return myObjectMapper.readValue(theExtension, extensionClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
CdsServiceRequestContextJson deserializeRequestContext(LinkedHashMap<String, Object> theMap)
|
|
||||||
throws JsonProcessingException {
|
throws JsonProcessingException {
|
||||||
final CdsServiceRequestContextJson cdsServiceRequestContextJson = new CdsServiceRequestContextJson();
|
final CdsServiceRequestContextJson cdsServiceRequestContextJson = new CdsServiceRequestContextJson();
|
||||||
for (Map.Entry<String, Object> entry : theMap.entrySet()) {
|
for (Map.Entry<String, Object> entry : theMap.entrySet()) {
|
||||||
|
@ -114,4 +90,31 @@ public class CdsServiceRequestJsonDeserializer extends StdDeserializer<CdsServic
|
||||||
}
|
}
|
||||||
return cdsServiceRequestContextJson;
|
return cdsServiceRequestContextJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CdsHooksExtension deserializeExtension(
|
||||||
|
@Nonnull CdsServiceJson theCdsServiceJson, @Nonnull String theExtension) throws JsonProcessingException {
|
||||||
|
Class<? extends CdsHooksExtension> extensionClass = theCdsServiceJson.getExtensionClass();
|
||||||
|
if (extensionClass == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return myObjectMapper.readValue(theExtension, extensionClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateHook(JsonNode hookIdNode) {
|
||||||
|
if (hookIdNode == null) {
|
||||||
|
throw new InvalidRequestException(Msg.code(2549) + "hook cannot be null for a CdsServiceRequest.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateHookInstance(JsonNode hookInstanceNode) {
|
||||||
|
if (hookInstanceNode == null) {
|
||||||
|
throw new InvalidRequestException(Msg.code(2548) + "hookInstance cannot be null for a CdsServiceRequest.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateContext(JsonNode requestContextNode) {
|
||||||
|
if (requestContextNode == null) {
|
||||||
|
throw new InvalidRequestException(Msg.code(2550) + "context cannot be null for a CdsServiceRequest.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package ca.uhn.hapi.fhir.cdshooks.svc;
|
package ca.uhn.hapi.fhir.cdshooks.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.ICdsMethod;
|
import ca.uhn.hapi.fhir.cdshooks.api.ICdsMethod;
|
||||||
|
@ -38,7 +37,6 @@ import ca.uhn.hapi.fhir.cdshooks.svc.cr.discovery.ICrDiscoveryServiceFactory;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.prefetch.CdsPrefetchSvc;
|
import ca.uhn.hapi.fhir.cdshooks.svc.prefetch.CdsPrefetchSvc;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import jakarta.annotation.Nonnull;
|
import jakarta.annotation.Nonnull;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
@ -50,7 +48,7 @@ import java.util.function.Function;
|
||||||
|
|
||||||
public class CdsServiceRegistryImpl implements ICdsServiceRegistry {
|
public class CdsServiceRegistryImpl implements ICdsServiceRegistry {
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(CdsServiceRegistryImpl.class);
|
private static final Logger ourLog = LoggerFactory.getLogger(CdsServiceRegistryImpl.class);
|
||||||
|
private final CdsServiceRequestJsonDeserializer myCdsServiceRequestJsonDeserializer;
|
||||||
private CdsServiceCache myServiceCache;
|
private CdsServiceCache myServiceCache;
|
||||||
|
|
||||||
private final CdsHooksContextBooter myCdsHooksContextBooter;
|
private final CdsHooksContextBooter myCdsHooksContextBooter;
|
||||||
|
@ -65,19 +63,13 @@ public class CdsServiceRegistryImpl implements ICdsServiceRegistry {
|
||||||
ObjectMapper theObjectMapper,
|
ObjectMapper theObjectMapper,
|
||||||
ICdsCrServiceFactory theCdsCrServiceFactory,
|
ICdsCrServiceFactory theCdsCrServiceFactory,
|
||||||
ICrDiscoveryServiceFactory theCrDiscoveryServiceFactory,
|
ICrDiscoveryServiceFactory theCrDiscoveryServiceFactory,
|
||||||
FhirContext theFhirContext) {
|
CdsServiceRequestJsonDeserializer theCdsServiceRequestJsonDeserializer) {
|
||||||
myCdsHooksContextBooter = theCdsHooksContextBooter;
|
myCdsHooksContextBooter = theCdsHooksContextBooter;
|
||||||
myCdsPrefetchSvc = theCdsPrefetchSvc;
|
myCdsPrefetchSvc = theCdsPrefetchSvc;
|
||||||
myObjectMapper = theObjectMapper;
|
myObjectMapper = theObjectMapper;
|
||||||
// registering this deserializer here instead of
|
|
||||||
// CdsHooksObjectMapperFactory to avoid circular
|
|
||||||
// dependency
|
|
||||||
SimpleModule module = new SimpleModule();
|
|
||||||
module.addDeserializer(
|
|
||||||
CdsServiceRequestJson.class, new CdsServiceRequestJsonDeserializer(this, theFhirContext));
|
|
||||||
myObjectMapper.registerModule(module);
|
|
||||||
myCdsCrServiceFactory = theCdsCrServiceFactory;
|
myCdsCrServiceFactory = theCdsCrServiceFactory;
|
||||||
myCrDiscoveryServiceFactory = theCrDiscoveryServiceFactory;
|
myCrDiscoveryServiceFactory = theCrDiscoveryServiceFactory;
|
||||||
|
myCdsServiceRequestJsonDeserializer = theCdsServiceRequestJsonDeserializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
|
@ -91,10 +83,13 @@ public class CdsServiceRegistryImpl implements ICdsServiceRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CdsServiceResponseJson callService(String theServiceId, CdsServiceRequestJson theCdsServiceRequestJson) {
|
public CdsServiceResponseJson callService(String theServiceId, Object theCdsServiceRequestJson) {
|
||||||
|
final CdsServiceJson cdsServiceJson = getCdsServiceJson(theServiceId);
|
||||||
|
final CdsServiceRequestJson deserializedRequest =
|
||||||
|
myCdsServiceRequestJsonDeserializer.deserialize(cdsServiceJson, theCdsServiceRequestJson);
|
||||||
ICdsServiceMethod serviceMethod = (ICdsServiceMethod) getCdsServiceMethodOrThrowException(theServiceId);
|
ICdsServiceMethod serviceMethod = (ICdsServiceMethod) getCdsServiceMethodOrThrowException(theServiceId);
|
||||||
myCdsPrefetchSvc.augmentRequest(theCdsServiceRequestJson, serviceMethod);
|
myCdsPrefetchSvc.augmentRequest(deserializedRequest, serviceMethod);
|
||||||
Object response = serviceMethod.invoke(myObjectMapper, theCdsServiceRequestJson, theServiceId);
|
Object response = serviceMethod.invoke(myObjectMapper, deserializedRequest, theServiceId);
|
||||||
return encodeServiceResponse(theServiceId, response);
|
return encodeServiceResponse(theServiceId, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeebackOutcomeEnum;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeebackOutcomeEnum;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
||||||
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseCardJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseCardJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
|
||||||
|
@ -118,6 +119,7 @@ public class CdsHooksControllerTest {
|
||||||
request.setHookInstance(TEST_HOOK_INSTANCE);
|
request.setHookInstance(TEST_HOOK_INSTANCE);
|
||||||
request.setHook(HelloWorldService.TEST_HOOK);
|
request.setHook(HelloWorldService.TEST_HOOK);
|
||||||
request.setFhirServer(TEST_FHIR_SERVER);
|
request.setFhirServer(TEST_FHIR_SERVER);
|
||||||
|
request.setContext( withCdsServiceRequestContext());
|
||||||
|
|
||||||
String requestBody = myObjectMapper.writeValueAsString(request);
|
String requestBody = myObjectMapper.writeValueAsString(request);
|
||||||
|
|
||||||
|
@ -142,8 +144,9 @@ public class CdsHooksControllerTest {
|
||||||
CdsServiceRequestJson request = new CdsServiceRequestJson();
|
CdsServiceRequestJson request = new CdsServiceRequestJson();
|
||||||
request.setExtension(requestExtension);
|
request.setExtension(requestExtension);
|
||||||
request.setFhirServer(TEST_FHIR_SERVER);
|
request.setFhirServer(TEST_FHIR_SERVER);
|
||||||
request.setHook(HelloWorldService.TEST_HOOK_UNIVERSE_ID);
|
request.setHook(HelloWorldService.TEST_HOOK);
|
||||||
|
request.setContext(withCdsServiceRequestContext());
|
||||||
|
request.setHookInstance(UUID.randomUUID().toString());
|
||||||
|
|
||||||
String requestBody = myObjectMapper.writeValueAsString(request);
|
String requestBody = myObjectMapper.writeValueAsString(request);
|
||||||
|
|
||||||
|
@ -163,6 +166,7 @@ public class CdsHooksControllerTest {
|
||||||
request.setHookInstance(TEST_HOOK_INSTANCE);
|
request.setHookInstance(TEST_HOOK_INSTANCE);
|
||||||
request.setHook(HelloWorldService.TEST_HOOK);
|
request.setHook(HelloWorldService.TEST_HOOK);
|
||||||
request.setFhirServer(TEST_FHIR_SERVER);
|
request.setFhirServer(TEST_FHIR_SERVER);
|
||||||
|
request.setContext(withCdsServiceRequestContext());
|
||||||
|
|
||||||
String requestBody = myObjectMapper.writeValueAsString(request);
|
String requestBody = myObjectMapper.writeValueAsString(request);
|
||||||
|
|
||||||
|
@ -268,4 +272,11 @@ public class CdsHooksControllerTest {
|
||||||
return JsonUtil.serialize(input, true);
|
return JsonUtil.serialize(input, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static CdsServiceRequestContextJson withCdsServiceRequestContext() {
|
||||||
|
CdsServiceRequestContextJson cdsServiceRequestContextJson = new CdsServiceRequestContextJson();
|
||||||
|
cdsServiceRequestContextJson.put("patientId", "Patient/123");
|
||||||
|
return cdsServiceRequestContextJson;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,106 +1,152 @@
|
||||||
package ca.uhn.hapi.fhir.cdshooks.serializer;
|
package ca.uhn.hapi.fhir.cdshooks.serializer;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsHooksExtension;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestContextJson;
|
||||||
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceRequestJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.custom.extensions.model.ExampleExtension;
|
import ca.uhn.hapi.fhir.cdshooks.custom.extensions.model.ExampleExtension;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.CdsServiceRegistryImpl;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
class CdsServiceRequestJsonDeserializerTest {
|
class CdsServiceRequestJsonDeserializerTest {
|
||||||
@Mock
|
private static final String SERVICE_ID = "service-id";
|
||||||
private CdsServiceRegistryImpl myCdsServiceRegistry;
|
private static final String EXAMPLE_PROPERTY_VALUE = "example-value";
|
||||||
|
private static final String EXAMPLE_PROPERTY_KEY = "example-property";
|
||||||
|
private static final String HOOK_ID = "hook-id";
|
||||||
private final FhirContext myFhirContext = FhirContext.forR4();
|
private final FhirContext myFhirContext = FhirContext.forR4();
|
||||||
|
private final ObjectMapper myObjectMapper = new ObjectMapper();
|
||||||
private CdsServiceRequestJsonDeserializer myFixture;
|
private CdsServiceRequestJsonDeserializer myFixture;
|
||||||
|
|
||||||
@BeforeEach()
|
@BeforeEach()
|
||||||
void setup() {
|
void setup() {
|
||||||
myFixture = new CdsServiceRequestJsonDeserializer(myCdsServiceRegistry, myFhirContext);
|
myFixture = new CdsServiceRequestJsonDeserializer(myFhirContext, myObjectMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void configureObjectMapper() {
|
void deserialize_shouldDeserialize_whenValidCdsServiceRequestWithExtensionReceived() {
|
||||||
// setup
|
// setup
|
||||||
ObjectMapper input = new ObjectMapper();
|
final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
|
||||||
|
final LinkedHashMap<String, Object> extension = withExtension();
|
||||||
|
final LinkedHashMap<String, Object> request = withRequest(extension);
|
||||||
|
request.put("context", withContext());
|
||||||
// execute
|
// execute
|
||||||
myFixture.configureObjectMapper(input);
|
final CdsServiceRequestJson actual = myFixture.deserialize(cdsServiceJson, request);
|
||||||
// validate
|
// validate
|
||||||
assertThat(input.getRegisteredModuleIds()).hasSize(1);
|
assertThat(actual.getExtension()).isInstanceOf(ExampleExtension.class);
|
||||||
|
final ExampleExtension actualExtension = (ExampleExtension) actual.getExtension();
|
||||||
|
assertThat(actualExtension.getExampleProperty()).isEqualTo(EXAMPLE_PROPERTY_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deserializeExtensionWhenClassFoundShouldDeserializeExtension() throws JsonProcessingException {
|
void deserialize_shouldIgnoreExtraFieldsInsideExtension_whenExtensionContainsMoreFieldsThanDefinedInClass() {
|
||||||
|
// setup
|
||||||
|
final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
|
||||||
|
final LinkedHashMap<String, Object> extension = withExtension();
|
||||||
|
extension.put("example-extra-property", "example-extra-value");
|
||||||
|
final LinkedHashMap<String, Object> request = withRequest(extension);
|
||||||
|
request.put("context", withContext());
|
||||||
|
// execute
|
||||||
|
final CdsServiceRequestJson actual = myFixture.deserialize(cdsServiceJson, request);
|
||||||
|
// validate
|
||||||
|
assertThat(actual.getExtension()).isInstanceOf(ExampleExtension.class);
|
||||||
|
final ExampleExtension actualExtension = (ExampleExtension) actual.getExtension();
|
||||||
|
assertThat(actualExtension.getExampleProperty()).isEqualTo(EXAMPLE_PROPERTY_VALUE);
|
||||||
|
assertThat(actual.getContext().get("encounterId")).isEqualTo("Encounter/123");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static LinkedHashMap<String, Object> withContext() {
|
||||||
|
final LinkedHashMap<String, Object> context = new LinkedHashMap<>();
|
||||||
|
context.put("encounterId", "Encounter/123");
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deserialize_shouldThrow_whenCdsServiceRequestIncludesInvalidProperty() {
|
||||||
|
// setup
|
||||||
|
final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
|
||||||
|
final LinkedHashMap<String, Object> extension = withExtension();
|
||||||
|
final LinkedHashMap<String, Object> request = withRequest(extension);
|
||||||
|
request.put("invalid-key", "some-value");
|
||||||
|
request.put("context", withContext());
|
||||||
|
// execute & validate
|
||||||
|
assertThatThrownBy(
|
||||||
|
() -> myFixture.deserialize(cdsServiceJson, request))
|
||||||
|
.isInstanceOf(InvalidRequestException.class)
|
||||||
|
.hasMessageContaining("HAPI-2551:")
|
||||||
|
.hasMessageContaining("Invalid CdsServiceRequest received.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deserialize_shouldReturnNullExtension_whenNotClassFound() {
|
||||||
// setup
|
// setup
|
||||||
final String serviceId = "service-id";
|
|
||||||
final String extension = """
|
|
||||||
{
|
|
||||||
"example-property": "example-value"
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
final CdsServiceJson cdsServiceJson = new CdsServiceJson();
|
final CdsServiceJson cdsServiceJson = new CdsServiceJson();
|
||||||
cdsServiceJson.setId(serviceId);
|
cdsServiceJson.setId(SERVICE_ID);
|
||||||
cdsServiceJson.setExtensionClass(ExampleExtension.class);
|
final LinkedHashMap<String, Object> extension = withExtension();
|
||||||
doReturn(cdsServiceJson).when(myCdsServiceRegistry).getCdsServiceJson(serviceId);
|
extension.put("example-extra-property", "example-extra-value");
|
||||||
|
final LinkedHashMap<String, Object> request = withRequest(extension);
|
||||||
|
request.put("context", withContext());
|
||||||
// execute
|
// execute
|
||||||
final ExampleExtension actual = (ExampleExtension) myFixture.deserializeExtension(serviceId, extension);
|
final CdsServiceRequestJson actual = myFixture.deserialize(cdsServiceJson, request);
|
||||||
// validate
|
// validate
|
||||||
assertThat(actual.getExampleProperty()).isEqualTo("example-value");
|
assertThat(actual.getExtension()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deserializeExtensionWhenClassFoundButExtensionHasExtraPropertiesShouldIgnoreExtraProperties() throws JsonProcessingException {
|
void deserialize_shouldThrow_whenHookNotFoundInRequest() {
|
||||||
// setup
|
// setup
|
||||||
final String serviceId = "service-id";
|
final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
|
||||||
final String extension = """
|
final LinkedHashMap<String, Object> request = new LinkedHashMap<>();
|
||||||
{
|
request.put("context", withContext());
|
||||||
"example-property": "example-value",
|
request.put("hookInstance", UUID.randomUUID().toString());
|
||||||
"example-extra-property": "example-extra-value"
|
// execute and validate
|
||||||
}
|
assertThatThrownBy(() -> myFixture.deserialize(cdsServiceJson, request))
|
||||||
""";
|
.isInstanceOf(InvalidRequestException.class)
|
||||||
final CdsServiceJson cdsServiceJson = new CdsServiceJson();
|
.hasMessageContaining("HAPI-2549:")
|
||||||
cdsServiceJson.setId(serviceId);
|
.hasMessageContaining("hook cannot be null for a CdsServiceRequest.");
|
||||||
cdsServiceJson.setExtensionClass(ExampleExtension.class);
|
|
||||||
doReturn(cdsServiceJson).when(myCdsServiceRegistry).getCdsServiceJson(serviceId);
|
|
||||||
// execute
|
|
||||||
final ExampleExtension actual = (ExampleExtension) myFixture.deserializeExtension(serviceId, extension);
|
|
||||||
// validate
|
|
||||||
assertThat(actual.getExampleProperty()).isEqualTo("example-value");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deserializeExtensionWhenNotClassFoundShouldReturnNull() throws JsonProcessingException {
|
void deserialize_shouldThrow_whenContextNotFoundInRequest() {
|
||||||
// setup
|
// setup
|
||||||
final String serviceId = "service-id";
|
final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
|
||||||
final String extension = """
|
final LinkedHashMap<String, Object> request = new LinkedHashMap<>();
|
||||||
{
|
request.put("hook", HOOK_ID);
|
||||||
"example-property": "example-value"
|
request.put("hookInstance", UUID.randomUUID().toString());
|
||||||
}
|
// execute and validate
|
||||||
""";
|
assertThatThrownBy(() -> myFixture.deserialize(cdsServiceJson, request))
|
||||||
final CdsServiceJson cdsServiceJson = new CdsServiceJson();
|
.isInstanceOf(InvalidRequestException.class)
|
||||||
cdsServiceJson.setId(serviceId);
|
.hasMessageContaining("HAPI-2550:")
|
||||||
doReturn(cdsServiceJson).when(myCdsServiceRegistry).getCdsServiceJson(serviceId);
|
.hasMessageContaining("context cannot be null for a CdsServiceRequest.");
|
||||||
// execute
|
|
||||||
final CdsHooksExtension actual = myFixture.deserializeExtension(serviceId, extension);
|
|
||||||
// validate
|
|
||||||
assertThat(actual).isNull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void deserializeRequestContextShouldDeserializeValidContext() throws JsonProcessingException {
|
void deserialize_shouldThrow_whenHookInstanceNotFoundInRequest() {
|
||||||
|
// setup
|
||||||
|
final CdsServiceJson cdsServiceJson = withCdsServiceJsonIncludingExtensionClass();
|
||||||
|
final LinkedHashMap<String, Object> request = new LinkedHashMap<>();
|
||||||
|
request.put("context", withContext());
|
||||||
|
request.put("hook", HOOK_ID);
|
||||||
|
// execute and validate
|
||||||
|
assertThatThrownBy(() -> myFixture.deserialize(cdsServiceJson, request))
|
||||||
|
.isInstanceOf(InvalidRequestException.class)
|
||||||
|
.hasMessageContaining("HAPI-2548:")
|
||||||
|
.hasMessageContaining("hookInstance cannot be null for a CdsServiceRequest.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deserializeRequestContext_shouldDeserialize_whenContextIsValid() throws JsonProcessingException {
|
||||||
// setup
|
// setup
|
||||||
final String encounterId = "123";
|
final String encounterId = "123";
|
||||||
final Patient patientContext = new Patient();
|
final Patient patientContext = new Patient();
|
||||||
|
@ -109,9 +155,34 @@ class CdsServiceRequestJsonDeserializerTest {
|
||||||
input.put("encounterId", encounterId);
|
input.put("encounterId", encounterId);
|
||||||
input.put("patient", patientContext);
|
input.put("patient", patientContext);
|
||||||
// execute
|
// execute
|
||||||
final CdsServiceRequestContextJson actual = myFixture.deserializeRequestContext(input);
|
final CdsServiceRequestContextJson actual = myFixture.deserializeContext(input);
|
||||||
// validate
|
// validate
|
||||||
assertThat(actual.get("encounterId")).isEqualTo(encounterId);
|
assertThat(actual.get("encounterId")).isEqualTo(encounterId);
|
||||||
assertThat(actual.get("patient")).usingRecursiveComparison().isEqualTo(patientContext);
|
assertThat(actual.get("patient")).usingRecursiveComparison().isEqualTo(patientContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static LinkedHashMap<String, Object> withExtension() {
|
||||||
|
final LinkedHashMap<String, Object> extension = new LinkedHashMap<>();
|
||||||
|
extension.put(EXAMPLE_PROPERTY_KEY, EXAMPLE_PROPERTY_VALUE);
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static CdsServiceJson withCdsServiceJsonIncludingExtensionClass() {
|
||||||
|
final CdsServiceJson cdsServiceJson = new CdsServiceJson();
|
||||||
|
cdsServiceJson.setId(SERVICE_ID);
|
||||||
|
cdsServiceJson.setExtensionClass(ExampleExtension.class);
|
||||||
|
cdsServiceJson.setHook(HOOK_ID);
|
||||||
|
return cdsServiceJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static LinkedHashMap<String, Object> withRequest(@Nonnull LinkedHashMap<String, Object> theExtension) {
|
||||||
|
final LinkedHashMap<String, Object> request = new LinkedHashMap<>();
|
||||||
|
request.put("extension", theExtension);
|
||||||
|
request.put("hookInstance", UUID.randomUUID().toString());
|
||||||
|
request.put("hook", HOOK_ID);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package ca.uhn.hapi.fhir.cdshooks.svc;
|
package ca.uhn.hapi.fhir.cdshooks.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceFeedbackJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceJson;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
|
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
|
||||||
|
import ca.uhn.hapi.fhir.cdshooks.serializer.CdsServiceRequestJsonDeserializer;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.cr.ICdsCrServiceFactory;
|
import ca.uhn.hapi.fhir.cdshooks.svc.cr.ICdsCrServiceFactory;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.cr.discovery.ICrDiscoveryServiceFactory;
|
import ca.uhn.hapi.fhir.cdshooks.svc.cr.discovery.ICrDiscoveryServiceFactory;
|
||||||
import ca.uhn.hapi.fhir.cdshooks.svc.prefetch.CdsPrefetchSvc;
|
import ca.uhn.hapi.fhir.cdshooks.svc.prefetch.CdsPrefetchSvc;
|
||||||
|
@ -33,13 +33,14 @@ class CdsServiceRegistryImplTest {
|
||||||
private ICrDiscoveryServiceFactory myCrDiscoveryServiceFactory;
|
private ICrDiscoveryServiceFactory myCrDiscoveryServiceFactory;
|
||||||
@Mock
|
@Mock
|
||||||
private CdsServiceCache myCdsServiceCache;
|
private CdsServiceCache myCdsServiceCache;
|
||||||
|
@Mock
|
||||||
|
private CdsServiceRequestJsonDeserializer myCdsServiceRequestJsonDeserializer;
|
||||||
private final ObjectMapper myObjectMapper = new ObjectMapper();
|
private final ObjectMapper myObjectMapper = new ObjectMapper();
|
||||||
private final FhirContext myFhirContext = FhirContext.forR4();
|
|
||||||
private CdsServiceRegistryImpl myFixture;
|
private CdsServiceRegistryImpl myFixture;
|
||||||
|
|
||||||
@BeforeEach()
|
@BeforeEach()
|
||||||
void setup() {
|
void setup() {
|
||||||
myFixture = new CdsServiceRegistryImpl(myCdsHooksContextBooter, myCdsPrefetchSvc, myObjectMapper, myCdsCrServiceFactory, myCrDiscoveryServiceFactory, myFhirContext);
|
myFixture = new CdsServiceRegistryImpl(myCdsHooksContextBooter, myCdsPrefetchSvc, myObjectMapper, myCdsCrServiceFactory, myCrDiscoveryServiceFactory, myCdsServiceRequestJsonDeserializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-caching-api</artifactId>
|
<artifactId>hapi-fhir-caching-api</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot</artifactId>
|
<artifactId>hapi-fhir-spring-boot</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class ForceIdMigrationFixTask extends BaseTask {
|
||||||
" set fhir_id = coalesce( "
|
" set fhir_id = coalesce( "
|
||||||
+
|
+
|
||||||
// case 5.
|
// case 5.
|
||||||
" trim(fhir_id), "
|
trimFhirId()
|
||||||
+
|
+
|
||||||
// case 3
|
// case 3
|
||||||
" (select f.forced_id from hfj_forced_id f where f.resource_pid = res_id), "
|
" (select f.forced_id from hfj_forced_id f where f.resource_pid = res_id), "
|
||||||
|
@ -109,6 +109,22 @@ public class ForceIdMigrationFixTask extends BaseTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String trimFhirId() {
|
||||||
|
switch (getDriverType()) {
|
||||||
|
case MSSQL_2012:
|
||||||
|
return " LTRIM(RTRIM(fhir_id)), ";
|
||||||
|
case H2_EMBEDDED:
|
||||||
|
case DERBY_EMBEDDED:
|
||||||
|
case MARIADB_10_1:
|
||||||
|
case MYSQL_5_7:
|
||||||
|
case POSTGRES_9_4:
|
||||||
|
case ORACLE_12C:
|
||||||
|
case COCKROACHDB_21_1:
|
||||||
|
default:
|
||||||
|
return " trim(fhir_id), ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String getWhereClauseByDBType() {
|
private String getWhereClauseByDBType() {
|
||||||
switch (getDriverType()) {
|
switch (getDriverType()) {
|
||||||
case MSSQL_2012:
|
case MSSQL_2012:
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -145,6 +145,20 @@
|
||||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- For test CR config that's exported to downstream modules -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
|
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<!-- prevent conflict with other version of this dependency sourced from elsewhere -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.glassfish</groupId>
|
||||||
|
<artifactId>jakarta.json</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- test -->
|
<!-- test -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.testcontainers</groupId>
|
<groupId>org.testcontainers</groupId>
|
||||||
|
|
|
@ -21,8 +21,10 @@ package ca.uhn.fhir.cr.common;
|
||||||
|
|
||||||
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
|
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
@Beta
|
||||||
public interface IRepositoryFactory {
|
public interface IRepositoryFactory {
|
||||||
HapiFhirRepository create(RequestDetails theRequestDetails);
|
HapiFhirRepository create(RequestDetails theRequestDetails);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Clinical Reasoning
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2024 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%
|
||||||
|
*/
|
||||||
|
package ca.uhn.fhir.cr.common;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import org.opencds.cqf.fhir.api.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory interface to return a {@link Repository} from a {@link RequestDetails}
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface RepositoryFactoryForRepositoryInterface {
|
||||||
|
Repository create(RequestDetails theRequestDetails);
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
package ca.uhn.fhir.cr.config;
|
package ca.uhn.fhir.cr.config;
|
||||||
|
|
||||||
import ca.uhn.fhir.cr.common.IRepositoryFactory;
|
import ca.uhn.fhir.cr.common.IRepositoryFactory;
|
||||||
|
import ca.uhn.fhir.cr.common.RepositoryFactoryForRepositoryInterface;
|
||||||
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
|
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
@ -28,8 +29,15 @@ import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class RepositoryConfig {
|
public class RepositoryConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) {
|
IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) {
|
||||||
return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer);
|
return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RepositoryFactoryForRepositoryInterface repositoryFactoryForInterface(
|
||||||
|
DaoRegistry theDaoRegistry, RestfulServer theRestfulServer) {
|
||||||
|
return rd -> new HapiFhirRepository(theDaoRegistry, rd, theRestfulServer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.cr.config.r4;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.cr.common.IRepositoryFactory;
|
import ca.uhn.fhir.cr.common.IRepositoryFactory;
|
||||||
|
import ca.uhn.fhir.cr.common.RepositoryFactoryForRepositoryInterface;
|
||||||
import ca.uhn.fhir.cr.config.ProviderLoader;
|
import ca.uhn.fhir.cr.config.ProviderLoader;
|
||||||
import ca.uhn.fhir.cr.config.ProviderSelector;
|
import ca.uhn.fhir.cr.config.ProviderSelector;
|
||||||
import ca.uhn.fhir.cr.config.RepositoryConfig;
|
import ca.uhn.fhir.cr.config.RepositoryConfig;
|
||||||
|
@ -66,7 +67,8 @@ public class CrR4Config {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
IMeasureServiceFactory r4MeasureServiceFactory(
|
IMeasureServiceFactory r4MeasureServiceFactory(
|
||||||
IRepositoryFactory theRepositoryFactory, MeasureEvaluationOptions theEvaluationOptions) {
|
RepositoryFactoryForRepositoryInterface theRepositoryFactory,
|
||||||
|
MeasureEvaluationOptions theEvaluationOptions) {
|
||||||
return rd -> new R4MeasureService(theRepositoryFactory.create(rd), theEvaluationOptions);
|
return rd -> new R4MeasureService(theRepositoryFactory.create(rd), theEvaluationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,23 @@
|
||||||
package ca.uhn.fhir.cr;
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Clinical Reasoning
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2024 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%
|
||||||
|
*/
|
||||||
|
package ca.uhn.fhir.cr.config.test;
|
||||||
|
|
||||||
import org.cqframework.cql.cql2elm.CqlCompilerException;
|
import org.cqframework.cql.cql2elm.CqlCompilerException;
|
||||||
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
|
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
|
||||||
|
@ -7,7 +26,9 @@ import org.cqframework.cql.cql2elm.LibraryBuilder;
|
||||||
import org.opencds.cqf.fhir.cql.CqlEngineOptions;
|
import org.opencds.cqf.fhir.cql.CqlEngineOptions;
|
||||||
import org.opencds.cqf.fhir.cql.CqlOptions;
|
import org.opencds.cqf.fhir.cql.CqlOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common CQL properties shared with downstream modules.
|
||||||
|
*/
|
||||||
public class TestCqlProperties {
|
public class TestCqlProperties {
|
||||||
|
|
||||||
//cql settings
|
//cql settings
|
|
@ -1,4 +1,23 @@
|
||||||
package ca.uhn.fhir.cr;
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Clinical Reasoning
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2024 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%
|
||||||
|
*/
|
||||||
|
package ca.uhn.fhir.cr.config.test;
|
||||||
|
|
||||||
import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider;
|
import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -47,6 +66,9 @@ import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common hapi-fhir clinical reasoning config shared with downstream modules.
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import({SubscriptionSubmitterConfig.class, SubscriptionChannelConfig.class})
|
@Import({SubscriptionSubmitterConfig.class, SubscriptionChannelConfig.class})
|
||||||
public class TestCrConfig {
|
public class TestCrConfig {
|
||||||
|
@ -77,7 +99,9 @@ public class TestCrConfig {
|
||||||
}
|
}
|
||||||
@Bean
|
@Bean
|
||||||
public TestCqlProperties testCqlProperties(){
|
public TestCqlProperties testCqlProperties(){
|
||||||
return new TestCqlProperties();}
|
return new TestCqlProperties();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public JpaStorageSettings storageSettings() {
|
public JpaStorageSettings storageSettings() {
|
||||||
JpaStorageSettings storageSettings = new JpaStorageSettings();
|
JpaStorageSettings storageSettings = new JpaStorageSettings();
|
||||||
|
@ -87,12 +111,6 @@ public class TestCrConfig {
|
||||||
storageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
storageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
||||||
return storageSettings;
|
return storageSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public PartitionHelper partitionHelper() {
|
|
||||||
return new PartitionHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ModelManager modelManager(Map<ModelIdentifier, Model> theGlobalModelCache) {
|
public ModelManager modelManager(Map<ModelIdentifier, Model> theGlobalModelCache) {
|
||||||
return new ModelManager(theGlobalModelCache);
|
return new ModelManager(theGlobalModelCache);
|
|
@ -1,9 +1,28 @@
|
||||||
package ca.uhn.fhir.cr.r4;
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Clinical Reasoning
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2024 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%
|
||||||
|
*/
|
||||||
|
package ca.uhn.fhir.cr.config.test.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.cr.TestCqlProperties;
|
|
||||||
import ca.uhn.fhir.cr.TestCrConfig;
|
|
||||||
import ca.uhn.fhir.cr.common.CqlThreadFactory;
|
import ca.uhn.fhir.cr.common.CqlThreadFactory;
|
||||||
import ca.uhn.fhir.cr.config.r4.CrR4Config;
|
import ca.uhn.fhir.cr.config.r4.CrR4Config;
|
||||||
|
import ca.uhn.fhir.cr.config.test.TestCqlProperties;
|
||||||
|
import ca.uhn.fhir.cr.config.test.TestCrConfig;
|
||||||
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
|
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
|
||||||
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
|
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
|
||||||
import org.cqframework.cql.cql2elm.model.Model;
|
import org.cqframework.cql.cql2elm.model.Model;
|
||||||
|
@ -30,6 +49,9 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common hapi-fhir clinical reasoning config specifically for R4 shared with downstream modules.
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import({TestCrConfig.class, CrR4Config.class})
|
@Import({TestCrConfig.class, CrR4Config.class})
|
||||||
public class TestCrR4Config {
|
public class TestCrR4Config {
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ca.uhn.fhir.cr;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
public class TestHapiFhirCrPartitionConfig {
|
||||||
|
@Bean
|
||||||
|
public PartitionHelper partitionHelper() {
|
||||||
|
return new PartitionHelper();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
package ca.uhn.fhir.cr.dstu3;
|
package ca.uhn.fhir.cr.dstu3;
|
||||||
|
|
||||||
import ca.uhn.fhir.cr.TestCqlProperties;
|
import ca.uhn.fhir.cr.TestHapiFhirCrPartitionConfig;
|
||||||
import ca.uhn.fhir.cr.TestCrConfig;
|
import ca.uhn.fhir.cr.config.test.TestCqlProperties;
|
||||||
import ca.uhn.fhir.cr.config.dstu3.CrDstu3Config;
|
import ca.uhn.fhir.cr.config.dstu3.CrDstu3Config;
|
||||||
|
import ca.uhn.fhir.cr.config.test.TestCrConfig;
|
||||||
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
|
import org.cqframework.cql.cql2elm.CqlCompilerOptions;
|
||||||
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
|
import org.cqframework.cql.cql2elm.model.CompiledLibrary;
|
||||||
import org.cqframework.cql.cql2elm.model.Model;
|
import org.cqframework.cql.cql2elm.model.Model;
|
||||||
|
@ -26,6 +27,7 @@ import java.util.Set;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import({
|
@Import({
|
||||||
|
TestHapiFhirCrPartitionConfig.class,
|
||||||
TestCrConfig.class,
|
TestCrConfig.class,
|
||||||
CrDstu3Config.class
|
CrDstu3Config.class
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,10 +2,12 @@ package ca.uhn.fhir.cr.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.cr.IResourceLoader;
|
import ca.uhn.fhir.cr.IResourceLoader;
|
||||||
|
import ca.uhn.fhir.cr.TestHapiFhirCrPartitionConfig;
|
||||||
import ca.uhn.fhir.cr.config.r4.ApplyOperationConfig;
|
import ca.uhn.fhir.cr.config.r4.ApplyOperationConfig;
|
||||||
import ca.uhn.fhir.cr.config.r4.ExtractOperationConfig;
|
import ca.uhn.fhir.cr.config.r4.ExtractOperationConfig;
|
||||||
import ca.uhn.fhir.cr.config.r4.PackageOperationConfig;
|
import ca.uhn.fhir.cr.config.r4.PackageOperationConfig;
|
||||||
import ca.uhn.fhir.cr.config.r4.PopulateOperationConfig;
|
import ca.uhn.fhir.cr.config.r4.PopulateOperationConfig;
|
||||||
|
import ca.uhn.fhir.cr.config.test.r4.TestCrR4Config;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
||||||
|
@ -38,6 +40,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
@ContextConfiguration(classes = {
|
@ContextConfiguration(classes = {
|
||||||
|
TestHapiFhirCrPartitionConfig.class,
|
||||||
TestCrR4Config.class,
|
TestCrR4Config.class,
|
||||||
ApplyOperationConfig.class,
|
ApplyOperationConfig.class,
|
||||||
ExtractOperationConfig.class,
|
ExtractOperationConfig.class,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package ca.uhn.fhir.cr.r4;
|
package ca.uhn.fhir.cr.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerCacheRefresherImpl;
|
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCacheRefresher;
|
||||||
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerRegistryImpl;
|
import ca.uhn.fhir.jpa.cache.ResourceChangeListenerRegistryImpl;
|
||||||
import org.hl7.fhir.r4.model.DateType;
|
import org.hl7.fhir.r4.model.DateType;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
@ -16,13 +16,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
@ExtendWith(SpringExtension.class)
|
@ExtendWith(SpringExtension.class)
|
||||||
public class CrResourceListenerTests extends BaseCrR4TestServer {
|
public class CrResourceListenerTest extends BaseCrR4TestServer {
|
||||||
@Autowired
|
@Autowired
|
||||||
EvaluationSettings myEvaluationSettings;
|
EvaluationSettings myEvaluationSettings;
|
||||||
@Autowired
|
@Autowired
|
||||||
ResourceChangeListenerRegistryImpl myResourceChangeListenerRegistry;
|
ResourceChangeListenerRegistryImpl myResourceChangeListenerRegistry;
|
||||||
@Autowired
|
@Autowired
|
||||||
ResourceChangeListenerCacheRefresherImpl myResourceChangeListenerCacheRefresher;
|
IResourceChangeListenerCacheRefresher myResourceChangeListenerCacheRefresher;
|
||||||
|
|
||||||
|
|
||||||
public MeasureReport runEvaluateMeasure(String periodStart, String periodEnd, String subject, String measureId, String reportType, String practitioner){
|
public MeasureReport runEvaluateMeasure(String periodStart, String periodEnd, String subject, String measureId, String reportType, String practitioner){
|
||||||
|
@ -118,7 +118,7 @@ public class CrResourceListenerTests extends BaseCrR4TestServer {
|
||||||
myResourceChangeListenerCacheRefresher.refreshExpiredCachesAndNotifyListeners();
|
myResourceChangeListenerCacheRefresher.refreshExpiredCachesAndNotifyListeners();
|
||||||
|
|
||||||
//cache should be invalidated for matching library name and version
|
//cache should be invalidated for matching library name and version
|
||||||
assertThat(myEvaluationSettings.getLibraryCache()).hasSize(6);
|
assertThat(myEvaluationSettings.getLibraryCache()).hasSize(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class DaoResourceLinkResolver<T extends IResourcePersistentId> implements
|
||||||
type, targetReference, idPart, theRequest, theTransactionDetails);
|
type, targetReference, idPart, theRequest, theTransactionDetails);
|
||||||
if (!createdTableOpt.isPresent()) {
|
if (!createdTableOpt.isPresent()) {
|
||||||
|
|
||||||
if (myStorageSettings.isEnforceReferentialIntegrityOnWrite() == false) {
|
if (!myStorageSettings.isEnforceReferentialIntegrityOnWrite()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,20 +150,8 @@ public class DaoResourceLinkResolver<T extends IResourcePersistentId> implements
|
||||||
"Resolved resource of type {} as PID: {}",
|
"Resolved resource of type {} as PID: {}",
|
||||||
resolvedResource.getResourceType(),
|
resolvedResource.getResourceType(),
|
||||||
resolvedResource.getPersistentId());
|
resolvedResource.getPersistentId());
|
||||||
if (!resourceType.equals(resolvedResource.getResourceType())) {
|
if (!validateResolvedResourceOrThrow(resourceType, resolvedResource, targetResourceId, idPart, sourcePath)) {
|
||||||
ourLog.error(
|
return null;
|
||||||
"Resource with PID {} was of type {} and wanted {}",
|
|
||||||
resolvedResource.getPersistentId(),
|
|
||||||
resourceType,
|
|
||||||
resolvedResource.getResourceType());
|
|
||||||
throw new UnprocessableEntityException(Msg.code(1095)
|
|
||||||
+ "Resource contains reference to unknown resource ID " + targetResourceId.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolvedResource.getDeleted() != null) {
|
|
||||||
String resName = resolvedResource.getResourceType();
|
|
||||||
throw new InvalidRequestException(Msg.code(1096) + "Resource " + resName + "/" + idPart
|
|
||||||
+ " is deleted, specified in path: " + sourcePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (persistentId == null) {
|
if (persistentId == null) {
|
||||||
|
@ -182,6 +170,45 @@ public class DaoResourceLinkResolver<T extends IResourcePersistentId> implements
|
||||||
return resolvedResource;
|
return resolvedResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the resolved resource.
|
||||||
|
* If 'Enforce Referential Integrity on Write' is enabled:
|
||||||
|
* Throws <code>UnprocessableEntityException</code> when resource types do not match
|
||||||
|
* Throws <code>InvalidRequestException</code> when the resolved resource was deleted
|
||||||
|
* <p>
|
||||||
|
* Otherwise, return false when resource types do not match or resource was deleted
|
||||||
|
* and return true if the resolved resource is valid.
|
||||||
|
*/
|
||||||
|
private boolean validateResolvedResourceOrThrow(
|
||||||
|
String resourceType,
|
||||||
|
IResourceLookup resolvedResource,
|
||||||
|
IIdType targetResourceId,
|
||||||
|
String idPart,
|
||||||
|
String sourcePath) {
|
||||||
|
if (!resourceType.equals(resolvedResource.getResourceType())) {
|
||||||
|
ourLog.error(
|
||||||
|
"Resource with PID {} was of type {} and wanted {}",
|
||||||
|
resolvedResource.getPersistentId(),
|
||||||
|
resourceType,
|
||||||
|
resolvedResource.getResourceType());
|
||||||
|
if (!myStorageSettings.isEnforceReferentialIntegrityOnWrite()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw new UnprocessableEntityException(Msg.code(1095)
|
||||||
|
+ "Resource contains reference to unknown resource ID " + targetResourceId.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolvedResource.getDeleted() != null) {
|
||||||
|
if (!myStorageSettings.isEnforceReferentialIntegrityOnWrite()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String resName = resolvedResource.getResourceType();
|
||||||
|
throw new InvalidRequestException(Msg.code(1096) + "Resource " + resName + "/" + idPart
|
||||||
|
+ " is deleted, specified in path: " + sourcePath);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IBaseResource loadTargetResource(
|
public IBaseResource loadTargetResource(
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>7.5.0-SNAPSHOT</version>
|
<version>7.5.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue