merging in masters
This commit is contained in:
commit
8d84ed0b94
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -155,6 +155,7 @@ ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder.invalidCodeMissin
|
||||||
|
|
||||||
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.matchesFound=Matches found
|
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.matchesFound=Matches found
|
||||||
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.noMatchesFound=No Matches found
|
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.noMatchesFound=No Matches found
|
||||||
|
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.onlyNegativeMatchesFound=Only negative matches found
|
||||||
|
|
||||||
ca.uhn.fhir.jpa.dao.JpaResourceDaoSearchParameter.invalidSearchParamExpression=The expression "{0}" can not be evaluated and may be invalid: {1}
|
ca.uhn.fhir.jpa.dao.JpaResourceDaoSearchParameter.invalidSearchParamExpression=The expression "{0}" can not be evaluated and may be invalid: {1}
|
||||||
|
|
||||||
|
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -93,7 +93,8 @@ public class ExportConceptMapToCsvCommandR4Test {
|
||||||
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2a\",\"Display 2a\",\"Code 3a\",\"Display 3a\",\"equal\",\"3a This is a comment.\"\n" +
|
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2a\",\"Display 2a\",\"Code 3a\",\"Display 3a\",\"equal\",\"3a This is a comment.\"\n" +
|
||||||
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2b\",\"Display 2b\",\"Code 3b\",\"Display 3b\",\"equal\",\"3b This is a comment.\"\n" +
|
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2b\",\"Display 2b\",\"Code 3b\",\"Display 3b\",\"equal\",\"3b This is a comment.\"\n" +
|
||||||
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2c\",\"Display 2c\",\"Code 3c\",\"Display 3c\",\"equal\",\"3c This is a comment.\"\n" +
|
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2c\",\"Display 2c\",\"Code 3c\",\"Display 3c\",\"equal\",\"3c This is a comment.\"\n" +
|
||||||
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2d\",\"Display 2d\",\"Code 3d\",\"Display 3d\",\"equal\",\"3d This is a comment.\"\n";
|
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2d\",\"Display 2d\",\"Code 3d\",\"Display 3d\",\"equal\",\"3d This is a comment.\"\n" +
|
||||||
|
"\"http://example.com/codesystem/2\",\"Version 2s\",\"http://example.com/codesystem/3\",\"Version 3t\",\"Code 2e\",\"Display 2e\",\"\",\"\",\"unmatched\",\"3e This is a comment.\"\n";
|
||||||
String result = IOUtils.toString(new FileInputStream(FILE), Charsets.UTF_8);
|
String result = IOUtils.toString(new FileInputStream(FILE), Charsets.UTF_8);
|
||||||
assertEquals(expected, result);
|
assertEquals(expected, result);
|
||||||
|
|
||||||
|
@ -272,6 +273,16 @@ public class ExportConceptMapToCsvCommandR4Test {
|
||||||
.setEquivalence(ConceptMapEquivalence.EQUAL)
|
.setEquivalence(ConceptMapEquivalence.EQUAL)
|
||||||
.setComment("3d This is a comment.");
|
.setComment("3d This is a comment.");
|
||||||
|
|
||||||
|
element = group.addElement();
|
||||||
|
element
|
||||||
|
.setCode("Code 2e")
|
||||||
|
.setDisplay("Display 2e");
|
||||||
|
|
||||||
|
target = element.addTarget();
|
||||||
|
target
|
||||||
|
.setEquivalence(ConceptMapEquivalence.UNMATCHED)
|
||||||
|
.setComment("3e This is a comment.");
|
||||||
|
|
||||||
return conceptMap;
|
return conceptMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
||||||
assertEquals(CS_URL_3, group.getTarget());
|
assertEquals(CS_URL_3, group.getTarget());
|
||||||
assertEquals("Version 3t", group.getTargetVersion());
|
assertEquals("Version 3t", group.getTargetVersion());
|
||||||
|
|
||||||
assertEquals(4, group.getElement().size());
|
assertEquals(5, group.getElement().size());
|
||||||
|
|
||||||
source = group.getElement().get(0);
|
source = group.getElement().get(0);
|
||||||
assertEquals("Code 2a", source.getCode());
|
assertEquals("Code 2a", source.getCode());
|
||||||
|
@ -323,6 +323,19 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
||||||
assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
|
assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
|
||||||
assertEquals("3d This is a comment.", target.getComment());
|
assertEquals("3d This is a comment.", target.getComment());
|
||||||
|
|
||||||
|
// ensure unmatched codes are handled correctly
|
||||||
|
source = group.getElement().get(4);
|
||||||
|
assertEquals("Code 2e", source.getCode());
|
||||||
|
assertEquals("Display 2e", source.getDisplay());
|
||||||
|
|
||||||
|
assertEquals(1, source.getTarget().size());
|
||||||
|
|
||||||
|
target = source.getTarget().get(0);
|
||||||
|
assertNull(target.getCode());
|
||||||
|
assertNull(target.getDisplay());
|
||||||
|
assertEquals(ConceptMapEquivalence.UNMATCHED, target.getEquivalence());
|
||||||
|
assertEquals("3e This is a comment.", target.getComment());
|
||||||
|
|
||||||
App.main(myTlsAuthenticationTestHelper.createBaseRequestGeneratingCommandArgs(
|
App.main(myTlsAuthenticationTestHelper.createBaseRequestGeneratingCommandArgs(
|
||||||
new String[]{
|
new String[]{
|
||||||
ImportCsvToConceptMapCommand.COMMAND,
|
ImportCsvToConceptMapCommand.COMMAND,
|
||||||
|
|
|
@ -284,7 +284,7 @@ public class ImportCsvToConceptMapCommandR4Test {
|
||||||
assertEquals(CS_URL_3, group.getTarget());
|
assertEquals(CS_URL_3, group.getTarget());
|
||||||
assertEquals("Version 3t", group.getTargetVersion());
|
assertEquals("Version 3t", group.getTargetVersion());
|
||||||
|
|
||||||
assertEquals(4, group.getElement().size());
|
assertEquals(5, group.getElement().size());
|
||||||
|
|
||||||
source = group.getElement().get(0);
|
source = group.getElement().get(0);
|
||||||
assertEquals("Code 2a", source.getCode());
|
assertEquals("Code 2a", source.getCode());
|
||||||
|
@ -334,6 +334,19 @@ public class ImportCsvToConceptMapCommandR4Test {
|
||||||
assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
|
assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
|
||||||
assertEquals("3d This is a comment.", target.getComment());
|
assertEquals("3d This is a comment.", target.getComment());
|
||||||
|
|
||||||
|
// ensure unmatched codes are handled correctly
|
||||||
|
source = group.getElement().get(4);
|
||||||
|
assertEquals("Code 2e", source.getCode());
|
||||||
|
assertEquals("Display 2e", source.getDisplay());
|
||||||
|
|
||||||
|
assertEquals(1, source.getTarget().size());
|
||||||
|
|
||||||
|
target = source.getTarget().get(0);
|
||||||
|
assertNull(target.getCode());
|
||||||
|
assertNull(target.getDisplay());
|
||||||
|
assertEquals(ConceptMapEquivalence.UNMATCHED, target.getEquivalence());
|
||||||
|
assertEquals("3e This is a comment.", target.getComment());
|
||||||
|
|
||||||
App.main(myTlsAuthenticationTestHelper.createBaseRequestGeneratingCommandArgs(
|
App.main(myTlsAuthenticationTestHelper.createBaseRequestGeneratingCommandArgs(
|
||||||
new String[]{
|
new String[]{
|
||||||
ImportCsvToConceptMapCommand.COMMAND,
|
ImportCsvToConceptMapCommand.COMMAND,
|
||||||
|
|
|
@ -11,3 +11,4 @@
|
||||||
"http://example.com/codesystem/2","Version 2s","http://example.com/codesystem/3","Version 3t","Code 2b","Display 2b","Code 3b","Display 3b","equal","3b This is a comment."
|
"http://example.com/codesystem/2","Version 2s","http://example.com/codesystem/3","Version 3t","Code 2b","Display 2b","Code 3b","Display 3b","equal","3b This is a comment."
|
||||||
"http://example.com/codesystem/2","Version 2s","http://example.com/codesystem/3","Version 3t","Code 2c","Display 2c","Code 3c","Display 3c","equal","3c This is a comment."
|
"http://example.com/codesystem/2","Version 2s","http://example.com/codesystem/3","Version 3t","Code 2c","Display 2c","Code 3c","Display 3c","equal","3c This is a comment."
|
||||||
"http://example.com/codesystem/2","Version 2s","http://example.com/codesystem/3","Version 3t","Code 2d","Display 2d","Code 3d","Display 3d","equal","3d This is a comment."
|
"http://example.com/codesystem/2","Version 2s","http://example.com/codesystem/3","Version 3t","Code 2d","Display 2d","Code 3d","Display 3d","equal","3d This is a comment."
|
||||||
|
"http://example.com/codesystem/2","Version 2s","http://example.com/codesystem/3","Version 3t","Code 2e","Display 2e","","","unmatched","3e This is a comment."
|
||||||
|
|
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 5801
|
||||||
|
title: "Support for the _language parameter was added but it was not able to be used by clients of a JPA server
|
||||||
|
because the _language parameter was not added to the resource providers. Additionally, no error message
|
||||||
|
was returned when language support was disabled and a search with _language was performed. This has
|
||||||
|
been fixed."
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: change
|
||||||
|
issue: 5814
|
||||||
|
title: "Extracted methods out of ResourceProviderFactory into ObservableSupplierSet so that functionality can be used by
|
||||||
|
other services. Unit tests revealed a cleanup bug in MdmProviderLoader that is fixed in this MR."
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: add
|
||||||
|
issue: 5816
|
||||||
|
title: "The ConceptMap/$translate operation will include targets with an equivalence code of `unmatched` in the response
|
||||||
|
regardless of whether the target has a code."
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
type: change
|
||||||
|
issue: 5817
|
||||||
|
title: "The HFJ_FORCED_ID table is no longer used."
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 5820
|
||||||
|
title: "Unifying the code paths for Patient type export and Patient instance export.
|
||||||
|
These paths should be the same, since type is defined by spec, but instance
|
||||||
|
is just 'syntactic sugar' on top of that spec (and so should be the same).
|
||||||
|
"
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 5824
|
||||||
|
jira: SMILE-7999
|
||||||
|
title: "We now avoid a query during reindex and transaction processing that was very slow on Sql Server."
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 5828
|
||||||
|
title: "When batch 2 jobs with Reduction steps fail in the final part
|
||||||
|
of the reduction step, this would often leave the job
|
||||||
|
stuck in the FINALIZE state.
|
||||||
|
This has been fixed; the job will now FAIL.
|
||||||
|
"
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
## HFJ_FORCED_ID Table
|
||||||
|
The HFJ_FORCED_ID table is no longer used.
|
||||||
|
Users may delete it after upgrading to 7.2 to free database storage space.
|
|
@ -84,6 +84,15 @@ The HFJ_RESOURCE table indicates a single resource of any type in the database.
|
||||||
Contains the resource type (e.g. <code>Patient</code>)
|
Contains the resource type (e.g. <code>Patient</code>)
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>FHIR_ID</td>
|
||||||
|
<td></td>
|
||||||
|
<td>String</td>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
Contains the FHIR Resource id element. Either the PID, or the client-assigned id.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>HASH_SHA256</td>
|
<td>HASH_SHA256</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
|
@ -243,30 +252,6 @@ The complete raw contents of the resource is stored in either the `RES_TEXT` or
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<a name="HFJ_FORCED_ID"/>
|
|
||||||
|
|
||||||
# HFJ_FORCED_ID: Client Assigned/Visible Resource IDs
|
|
||||||
|
|
||||||
By default, the **HFJ_RESOURCE.RES_ID** column is used as the resource ID for all server-assigned IDs. For example, if a Patient resource is created in a completely empty database, it will be assigned the ID `Patient/1` by the server and RES_ID will have a value of 1.
|
|
||||||
|
|
||||||
However, when client-assigned IDs are used, these may contain text values to allow a client to create an ID such
|
|
||||||
as `Patient/ABC`. When a client-assigned ID is given to a resource, a row is created in the **HFJ_RESOURCE** table. When
|
|
||||||
an **HFJ_FORCED_ID** row exists corresponding to the equivalent **HFJ_RESOURCE** row, the RES_ID value is no longer
|
|
||||||
visible or usable by FHIR clients and it becomes purely an internal ID to the JPA server.
|
|
||||||
|
|
||||||
If the server has been configured with
|
|
||||||
a [Resource Server ID Strategy](/apidocs/hapi-fhir-storage/undefined/ca/uhn/fhir/jpa/api/config/JpaStorageSettings.html#setResourceServerIdStrategy(ca.uhn.fhir.jpa.api.config.JpaStorageSettings.IdStrategyEnum))
|
|
||||||
of [UUID](/apidocs/hapi-fhir-storage/undefined/ca/uhn/fhir/jpa/api/config/JpaStorageSettings.IdStrategyEnum.html#UUID), or the
|
|
||||||
server has been configured with
|
|
||||||
a [Resource Client ID Strategy](/apidocs/hapi-fhir-storage/undefined/ca/uhn/fhir/jpa/api/config/JpaStorageSettings.html#setResourceClientIdStrategy(ca.uhn.fhir.jpa.api.config.JpaStorageSettings.ClientIdStrategyEnum))
|
|
||||||
of [ANY](/apidocs/hapi-fhir-storage/undefined/ca/uhn/fhir/jpa/api/config/JpaStorageSettings.ClientIdStrategyEnum.html#ANY)
|
|
||||||
the server will create a Forced ID for all resources (not only resources having textual IDs).
|
|
||||||
|
|
||||||
The **HFJ_RESOURCE** table now has a FHIR_ID column.
|
|
||||||
This column is always populated; both for server-assigned ids and for client-assigned ids.
|
|
||||||
As of Hapi release 6.10, this column is used in place of the **HFJ_FORCED_ID** table for id search and sort.
|
|
||||||
A future version of Hapi will stop populating the **HFJ_FORCED_ID** table.
|
|
||||||
|
|
||||||
## Columns
|
## Columns
|
||||||
|
|
||||||
<table class="table table-striped table-condensed">
|
<table class="table table-striped table-condensed">
|
||||||
|
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -37,7 +37,6 @@ import ca.uhn.fhir.jpa.api.dao.IJpaDao;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc;
|
import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
|
@ -195,9 +194,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IIdHelperService<JpaPid> myIdHelperService;
|
protected IIdHelperService<JpaPid> myIdHelperService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected IForcedIdDao myForcedIdDao;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ISearchCoordinatorSvc<JpaPid> mySearchCoordinatorSvc;
|
protected ISearchCoordinatorSvc<JpaPid> mySearchCoordinatorSvc;
|
||||||
|
|
||||||
|
@ -1204,10 +1200,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
if (entity.getId() == null) {
|
if (entity.getId() == null) {
|
||||||
myEntityManager.persist(entity);
|
myEntityManager.persist(entity);
|
||||||
|
|
||||||
if (entity.getForcedId() != null) {
|
|
||||||
myEntityManager.persist(entity.getForcedId());
|
|
||||||
}
|
|
||||||
|
|
||||||
postPersist(entity, (T) theResource, theRequest);
|
postPersist(entity, (T) theResource, theRequest);
|
||||||
|
|
||||||
} else if (entity.getDeleted() != null) {
|
} else if (entity.getDeleted() != null) {
|
||||||
|
|
|
@ -44,14 +44,12 @@ import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
||||||
import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
|
import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
|
||||||
import ca.uhn.fhir.jpa.api.model.LazyDaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.LazyDaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
|
||||||
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
|
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
|
||||||
import ca.uhn.fhir.jpa.delete.DeleteConflictUtil;
|
import ca.uhn.fhir.jpa.delete.DeleteConflictUtil;
|
||||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
|
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
|
||||||
import ca.uhn.fhir.jpa.model.entity.BaseTag;
|
import ca.uhn.fhir.jpa.model.entity.BaseTag;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
|
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
|
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||||
|
@ -517,18 +515,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String resourceIdBeforeStorage = theResource.getIdElement().getIdPart();
|
boolean isClientAssignedId = storeNonPidResourceId(theResource, entity);
|
||||||
boolean resourceHadIdBeforeStorage = isNotBlank(resourceIdBeforeStorage);
|
|
||||||
boolean resourceIdWasServerAssigned =
|
|
||||||
theResource.getUserData(JpaConstants.RESOURCE_ID_SERVER_ASSIGNED) == Boolean.TRUE;
|
|
||||||
if (resourceHadIdBeforeStorage) {
|
|
||||||
entity.setFhirId(resourceIdBeforeStorage);
|
|
||||||
}
|
|
||||||
|
|
||||||
HookParams hookParams;
|
HookParams hookParams;
|
||||||
|
|
||||||
// Notify interceptor for accepting/rejecting client assigned ids
|
// Notify interceptor for accepting/rejecting client assigned ids
|
||||||
if (!resourceIdWasServerAssigned && resourceHadIdBeforeStorage) {
|
if (isClientAssignedId) {
|
||||||
hookParams = new HookParams().add(IBaseResource.class, theResource).add(RequestDetails.class, theRequest);
|
hookParams = new HookParams().add(IBaseResource.class, theResource).add(RequestDetails.class, theRequest);
|
||||||
doCallHooks(theTransactionDetails, theRequest, Pointcut.STORAGE_PRESTORAGE_CLIENT_ASSIGNED_ID, hookParams);
|
doCallHooks(theTransactionDetails, theRequest, Pointcut.STORAGE_PRESTORAGE_CLIENT_ASSIGNED_ID, hookParams);
|
||||||
}
|
}
|
||||||
|
@ -542,7 +534,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
.add(TransactionDetails.class, theTransactionDetails);
|
.add(TransactionDetails.class, theTransactionDetails);
|
||||||
doCallHooks(theTransactionDetails, theRequest, Pointcut.STORAGE_PRESTORAGE_RESOURCE_CREATED, hookParams);
|
doCallHooks(theTransactionDetails, theRequest, Pointcut.STORAGE_PRESTORAGE_RESOURCE_CREATED, hookParams);
|
||||||
|
|
||||||
if (resourceHadIdBeforeStorage && !resourceIdWasServerAssigned) {
|
if (isClientAssignedId) {
|
||||||
validateResourceIdCreation(theResource, theRequest);
|
validateResourceIdCreation(theResource, theRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,31 +561,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
|
|
||||||
// Store the resource forced ID if necessary
|
// Store the resource forced ID if necessary
|
||||||
JpaPid jpaPid = JpaPid.fromId(updatedEntity.getResourceId());
|
JpaPid jpaPid = JpaPid.fromId(updatedEntity.getResourceId());
|
||||||
if (resourceHadIdBeforeStorage) {
|
|
||||||
if (resourceIdWasServerAssigned) {
|
|
||||||
boolean createForPureNumericIds = true;
|
|
||||||
createForcedIdIfNeeded(entity, resourceIdBeforeStorage, createForPureNumericIds);
|
|
||||||
} else {
|
|
||||||
boolean createForPureNumericIds = getStorageSettings().getResourceClientIdStrategy()
|
|
||||||
!= JpaStorageSettings.ClientIdStrategyEnum.ALPHANUMERIC;
|
|
||||||
createForcedIdIfNeeded(entity, resourceIdBeforeStorage, createForPureNumericIds);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (getStorageSettings().getResourceClientIdStrategy()) {
|
|
||||||
case NOT_ALLOWED:
|
|
||||||
case ALPHANUMERIC:
|
|
||||||
break;
|
|
||||||
case ANY:
|
|
||||||
boolean createForPureNumericIds = true;
|
|
||||||
createForcedIdIfNeeded(
|
|
||||||
updatedEntity, theResource.getIdElement().getIdPart(), createForPureNumericIds);
|
|
||||||
// for client ID mode ANY, we will always have a forced ID. If we ever
|
|
||||||
// stop populating the transient forced ID be warned that we use it
|
|
||||||
// (and expect it to be set correctly) farther below.
|
|
||||||
assert updatedEntity.getTransientForcedId() != null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate the resource with its actual final stored ID from the entity
|
// Populate the resource with its actual final stored ID from the entity
|
||||||
theResource.setId(entity.getIdDt());
|
theResource.setId(entity.getIdDt());
|
||||||
|
@ -601,7 +568,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
// Pre-cache the resource ID
|
// Pre-cache the resource ID
|
||||||
jpaPid.setAssociatedResourceId(entity.getIdType(myFhirContext));
|
jpaPid.setAssociatedResourceId(entity.getIdType(myFhirContext));
|
||||||
myIdHelperService.addResolvedPidToForcedId(
|
myIdHelperService.addResolvedPidToForcedId(
|
||||||
jpaPid, theRequestPartitionId, getResourceName(), entity.getTransientForcedId(), null);
|
jpaPid, theRequestPartitionId, getResourceName(), entity.getFhirId(), null);
|
||||||
theTransactionDetails.addResolvedResourceId(jpaPid.getAssociatedResourceId(), jpaPid);
|
theTransactionDetails.addResolvedResourceId(jpaPid.getAssociatedResourceId(), jpaPid);
|
||||||
theTransactionDetails.addResolvedResource(jpaPid.getAssociatedResourceId(), theResource);
|
theTransactionDetails.addResolvedResource(jpaPid.getAssociatedResourceId(), theResource);
|
||||||
|
|
||||||
|
@ -646,40 +613,34 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createForcedIdIfNeeded(
|
/**
|
||||||
ResourceTable theEntity, String theResourceId, boolean theCreateForPureNumericIds) {
|
* Check for an id on the resource and if so,
|
||||||
// TODO MB delete this in step 3
|
* store it in ResourceTable.
|
||||||
if (isNotBlank(theResourceId) && theEntity.getForcedId() == null) {
|
*
|
||||||
if (theCreateForPureNumericIds || !IdHelperService.isValidPid(theResourceId)) {
|
* The fhirId property is either set here with the resource id
|
||||||
ForcedId forcedId = new ForcedId();
|
* OR by hibernate once the PK is generated for a server-assigned id.
|
||||||
forcedId.setResourceType(theEntity.getResourceType());
|
*
|
||||||
forcedId.setForcedId(theResourceId);
|
* Used for both client-assigned id and for server-assigned UUIDs.
|
||||||
forcedId.setResource(theEntity);
|
*
|
||||||
forcedId.setPartitionId(theEntity.getPartitionId());
|
* @return true if this is a client-assigned id
|
||||||
|
*
|
||||||
|
* @see ca.uhn.fhir.jpa.model.entity.ResourceTable.FhirIdGenerator
|
||||||
|
*/
|
||||||
|
private boolean storeNonPidResourceId(T theResource, ResourceTable entity) {
|
||||||
|
String resourceIdBeforeStorage = theResource.getIdElement().getIdPart();
|
||||||
|
boolean resourceHadIdBeforeStorage = isNotBlank(resourceIdBeforeStorage);
|
||||||
|
boolean resourceIdWasServerAssigned =
|
||||||
|
theResource.getUserData(JpaConstants.RESOURCE_ID_SERVER_ASSIGNED) == Boolean.TRUE;
|
||||||
|
|
||||||
/*
|
// We distinguish actual client-assigned ids from UUIDs which the server assigned.
|
||||||
* As of Hibernate 5.6.2, assigning the forced ID to the
|
boolean isClientAssigned = resourceHadIdBeforeStorage && !resourceIdWasServerAssigned;
|
||||||
* resource table causes an extra update to happen, even
|
|
||||||
* though the ResourceTable entity isn't actually changed
|
// But both need to be set on the entity fhirId field.
|
||||||
* (there is a @OneToOne reference on ResourceTable to the
|
if (resourceHadIdBeforeStorage) {
|
||||||
* ForcedId table, but the actual column is on the ForcedId
|
entity.setFhirId(resourceIdBeforeStorage);
|
||||||
* table so it doesn't actually make sense to update the table
|
|
||||||
* when this is set). But to work around that we avoid
|
|
||||||
* actually assigning ResourceTable#myForcedId here.
|
|
||||||
*
|
|
||||||
* It's conceivable they may fix this in the future, or
|
|
||||||
* they may not.
|
|
||||||
*
|
|
||||||
* If you want to try assigning the forced it to the resource
|
|
||||||
* entity (by calling ResourceTable#setForcedId) try running
|
|
||||||
* the tests FhirResourceDaoR4QueryCountTest to verify that
|
|
||||||
* nothing has broken as a result.
|
|
||||||
* JA 20220121
|
|
||||||
*/
|
|
||||||
theEntity.setTransientForcedId(forcedId.getForcedId());
|
|
||||||
myForcedIdDao.save(forcedId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isClientAssigned;
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateResourceIdCreation(T theResource, RequestDetails theRequest) {
|
void validateResourceIdCreation(T theResource, RequestDetails theRequest) {
|
||||||
|
@ -1891,7 +1852,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
throw new ResourceNotFoundException(Msg.code(1998) + theId);
|
throw new ResourceNotFoundException(Msg.code(1998) + theId);
|
||||||
}
|
}
|
||||||
validateGivenIdIsAppropriateToRetrieveResource(theId, entity);
|
validateGivenIdIsAppropriateToRetrieveResource(theId, entity);
|
||||||
entity.setTransientForcedId(theId.getIdPart());
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2634,18 +2594,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateGivenIdIsAppropriateToRetrieveResource(IIdType theId, BaseHasResource entity) {
|
private void validateGivenIdIsAppropriateToRetrieveResource(IIdType theId, BaseHasResource entity) {
|
||||||
if (entity.getForcedId() != null) {
|
if (!entity.getIdDt().getIdPart().equals(theId.getIdPart())) {
|
||||||
if (getStorageSettings().getResourceClientIdStrategy() != JpaStorageSettings.ClientIdStrategyEnum.ANY) {
|
// This means that the resource with the given numeric ID exists, but it has a "forced ID", meaning
|
||||||
if (theId.isIdPartValidLong()) {
|
// that
|
||||||
// This means that the resource with the given numeric ID exists, but it has a "forced ID", meaning
|
// as far as the outside world is concerned, the given ID doesn't exist (it's just an internal
|
||||||
// that
|
// pointer
|
||||||
// as far as the outside world is concerned, the given ID doesn't exist (it's just an internal
|
// to the
|
||||||
// pointer
|
// forced ID)
|
||||||
// to the
|
throw new ResourceNotFoundException(Msg.code(2000) + theId);
|
||||||
// forced ID)
|
|
||||||
throw new ResourceNotFoundException(Msg.code(2000) + theId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
||||||
import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
|
import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.expunge.ExpungeService;
|
import ca.uhn.fhir.jpa.dao.expunge.ExpungeService;
|
||||||
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
|
import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
|
||||||
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
|
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
|
||||||
|
@ -38,7 +37,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory;
|
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory;
|
||||||
import ca.uhn.fhir.jpa.search.builder.SearchBuilder;
|
import ca.uhn.fhir.jpa.search.SearchConstants;
|
||||||
import ca.uhn.fhir.jpa.util.QueryChunker;
|
import ca.uhn.fhir.jpa.util.QueryChunker;
|
||||||
import ca.uhn.fhir.jpa.util.ResourceCountCache;
|
import ca.uhn.fhir.jpa.util.ResourceCountCache;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
@ -47,34 +46,31 @@ import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||||
import ca.uhn.fhir.util.StopWatch;
|
import ca.uhn.fhir.util.StopWatch;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
import jakarta.annotation.Nullable;
|
import jakarta.annotation.Nullable;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import jakarta.persistence.PersistenceContextType;
|
import jakarta.persistence.PersistenceContextType;
|
||||||
|
import jakarta.persistence.Query;
|
||||||
import jakarta.persistence.TypedQuery;
|
import jakarta.persistence.TypedQuery;
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
|
||||||
import jakarta.persistence.criteria.JoinType;
|
|
||||||
import jakarta.persistence.criteria.Predicate;
|
|
||||||
import jakarta.persistence.criteria.Root;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public abstract class BaseHapiFhirSystemDao<T extends IBaseBundle, MT> extends BaseStorageDao
|
public abstract class BaseHapiFhirSystemDao<T extends IBaseBundle, MT> extends BaseStorageDao
|
||||||
implements IFhirSystemDao<T, MT> {
|
implements IFhirSystemDao<T, MT> {
|
||||||
|
|
||||||
public static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[0];
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirSystemDao.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirSystemDao.class);
|
||||||
|
|
||||||
public ResourceCountCache myResourceCountsCache;
|
public ResourceCountCache myResourceCountsCache;
|
||||||
|
|
||||||
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
||||||
|
@ -95,9 +91,6 @@ public abstract class BaseHapiFhirSystemDao<T extends IBaseBundle, MT> extends B
|
||||||
@Autowired
|
@Autowired
|
||||||
private PersistedJpaBundleProviderFactory myPersistedJpaBundleProviderFactory;
|
private PersistedJpaBundleProviderFactory myPersistedJpaBundleProviderFactory;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IResourceTagDao myResourceTagDao;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
|
@ -181,13 +174,25 @@ public abstract class BaseHapiFhirSystemDao<T extends IBaseBundle, MT> extends B
|
||||||
return myTransactionProcessor.transaction(theRequestDetails, theRequest, true);
|
return myTransactionProcessor.transaction(theRequestDetails, theRequest, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefetch entities into the Hibernate session.
|
||||||
|
*
|
||||||
|
* When processing several resources (e.g. transaction bundle, $reindex chunk, etc.)
|
||||||
|
* it would be slow to fetch each piece of a resource (e.g. all token index rows)
|
||||||
|
* one resource at a time.
|
||||||
|
* Instead, we fetch all the linked resources for the entire batch and populate the Hibernate Session.
|
||||||
|
*
|
||||||
|
* @param theResolvedIds the pids
|
||||||
|
* @param thePreFetchIndexes Should resource indexes be loaded
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
public <P extends IResourcePersistentId> void preFetchResources(
|
public <P extends IResourcePersistentId> void preFetchResources(
|
||||||
List<P> theResolvedIds, boolean thePreFetchIndexes) {
|
List<P> theResolvedIds, boolean thePreFetchIndexes) {
|
||||||
HapiTransactionService.requireTransaction();
|
HapiTransactionService.requireTransaction();
|
||||||
List<Long> pids = theResolvedIds.stream().map(t -> ((JpaPid) t).getId()).collect(Collectors.toList());
|
List<Long> pids = theResolvedIds.stream().map(t -> ((JpaPid) t).getId()).collect(Collectors.toList());
|
||||||
|
|
||||||
new QueryChunker<Long>().chunk(pids, ids -> {
|
new QueryChunker<Long>().chunk(pids, idChunk -> {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pre-fetch the resources we're touching in this transaction in mass - this reduced the
|
* Pre-fetch the resources we're touching in this transaction in mass - this reduced the
|
||||||
|
@ -200,117 +205,110 @@ public abstract class BaseHapiFhirSystemDao<T extends IBaseBundle, MT> extends B
|
||||||
*
|
*
|
||||||
* However, for realistic average workloads, this should reduce the number of round trips.
|
* However, for realistic average workloads, this should reduce the number of round trips.
|
||||||
*/
|
*/
|
||||||
if (ids.size() >= 2) {
|
if (idChunk.size() >= 2) {
|
||||||
List<ResourceTable> loadedResourceTableEntries = new ArrayList<>();
|
List<ResourceTable> entityChunk = prefetchResourceTableHistoryAndProvenance(idChunk);
|
||||||
preFetchIndexes(ids, "forcedId", "myForcedId", loadedResourceTableEntries);
|
|
||||||
|
|
||||||
List<Long> entityIds;
|
|
||||||
|
|
||||||
if (thePreFetchIndexes) {
|
if (thePreFetchIndexes) {
|
||||||
entityIds = loadedResourceTableEntries.stream()
|
|
||||||
.filter(ResourceTable::isParamsStringPopulated)
|
|
||||||
.map(ResourceTable::getId)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (entityIds.size() > 0) {
|
|
||||||
preFetchIndexes(entityIds, "string", "myParamsString", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
entityIds = loadedResourceTableEntries.stream()
|
prefetchByField("string", "myParamsString", ResourceTable::isParamsStringPopulated, entityChunk);
|
||||||
.filter(ResourceTable::isParamsTokenPopulated)
|
prefetchByField("token", "myParamsToken", ResourceTable::isParamsTokenPopulated, entityChunk);
|
||||||
.map(ResourceTable::getId)
|
prefetchByField("date", "myParamsDate", ResourceTable::isParamsDatePopulated, entityChunk);
|
||||||
.collect(Collectors.toList());
|
prefetchByField(
|
||||||
if (entityIds.size() > 0) {
|
"quantity", "myParamsQuantity", ResourceTable::isParamsQuantityPopulated, entityChunk);
|
||||||
preFetchIndexes(entityIds, "token", "myParamsToken", null);
|
prefetchByField("resourceLinks", "myResourceLinks", ResourceTable::isHasLinks, entityChunk);
|
||||||
}
|
|
||||||
|
|
||||||
entityIds = loadedResourceTableEntries.stream()
|
prefetchByJoinClause(
|
||||||
.filter(ResourceTable::isParamsDatePopulated)
|
"tags",
|
||||||
.map(ResourceTable::getId)
|
// fetch the TagResources and the actual TagDefinitions
|
||||||
.collect(Collectors.toList());
|
"LEFT JOIN FETCH r.myTags t LEFT JOIN FETCH t.myTag",
|
||||||
if (entityIds.size() > 0) {
|
BaseHasResource::isHasTags,
|
||||||
preFetchIndexes(entityIds, "date", "myParamsDate", null);
|
entityChunk);
|
||||||
}
|
|
||||||
|
|
||||||
entityIds = loadedResourceTableEntries.stream()
|
|
||||||
.filter(ResourceTable::isParamsQuantityPopulated)
|
|
||||||
.map(ResourceTable::getId)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (entityIds.size() > 0) {
|
|
||||||
preFetchIndexes(entityIds, "quantity", "myParamsQuantity", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
entityIds = loadedResourceTableEntries.stream()
|
|
||||||
.filter(ResourceTable::isHasLinks)
|
|
||||||
.map(ResourceTable::getId)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (entityIds.size() > 0) {
|
|
||||||
preFetchIndexes(entityIds, "resourceLinks", "myResourceLinks", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
entityIds = loadedResourceTableEntries.stream()
|
|
||||||
.filter(BaseHasResource::isHasTags)
|
|
||||||
.map(ResourceTable::getId)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (entityIds.size() > 0) {
|
|
||||||
myResourceTagDao.findByResourceIds(entityIds);
|
|
||||||
preFetchIndexes(entityIds, "tags", "myTags", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
entityIds = loadedResourceTableEntries.stream()
|
|
||||||
.map(ResourceTable::getId)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (myStorageSettings.getIndexMissingFields() == JpaStorageSettings.IndexEnabledEnum.ENABLED) {
|
if (myStorageSettings.getIndexMissingFields() == JpaStorageSettings.IndexEnabledEnum.ENABLED) {
|
||||||
preFetchIndexes(entityIds, "searchParamPresence", "mySearchParamPresents", null);
|
prefetchByField("searchParamPresence", "mySearchParamPresents", r -> true, entityChunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new QueryChunker<ResourceTable>()
|
|
||||||
.chunk(loadedResourceTableEntries, SearchBuilder.getMaximumPageSize() / 2, entries -> {
|
|
||||||
Map<Long, ResourceTable> entities =
|
|
||||||
entries.stream().collect(Collectors.toMap(ResourceTable::getId, t -> t));
|
|
||||||
|
|
||||||
CriteriaBuilder b = myEntityManager.getCriteriaBuilder();
|
|
||||||
CriteriaQuery<ResourceHistoryTable> q = b.createQuery(ResourceHistoryTable.class);
|
|
||||||
Root<ResourceHistoryTable> from = q.from(ResourceHistoryTable.class);
|
|
||||||
|
|
||||||
from.fetch("myProvenance", JoinType.LEFT);
|
|
||||||
|
|
||||||
List<Predicate> orPredicates = new ArrayList<>();
|
|
||||||
for (ResourceTable next : entries) {
|
|
||||||
Predicate resId = b.equal(from.get("myResourceId"), next.getId());
|
|
||||||
Predicate resVer = b.equal(from.get("myResourceVersion"), next.getVersion());
|
|
||||||
orPredicates.add(b.and(resId, resVer));
|
|
||||||
}
|
|
||||||
q.where(b.or(orPredicates.toArray(EMPTY_PREDICATE_ARRAY)));
|
|
||||||
List<ResourceHistoryTable> resultList =
|
|
||||||
myEntityManager.createQuery(q).getResultList();
|
|
||||||
for (ResourceHistoryTable next : resultList) {
|
|
||||||
ResourceTable nextEntity = entities.get(next.getResourceId());
|
|
||||||
if (nextEntity != null) {
|
|
||||||
nextEntity.setCurrentVersionEntity(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void preFetchIndexes(
|
@Nonnull
|
||||||
List<Long> theIds,
|
private List<ResourceTable> prefetchResourceTableHistoryAndProvenance(List<Long> idChunk) {
|
||||||
String typeDesc,
|
assert idChunk.size() < SearchConstants.MAX_PAGE_SIZE : "assume pre-chunked";
|
||||||
String fieldName,
|
|
||||||
@Nullable List<ResourceTable> theEntityListToPopulate) {
|
Query query = myEntityManager.createQuery("select r, h "
|
||||||
new QueryChunker<Long>().chunk(theIds, ids -> {
|
+ " FROM ResourceTable r "
|
||||||
TypedQuery<ResourceTable> query = myEntityManager.createQuery(
|
+ " LEFT JOIN fetch ResourceHistoryTable h "
|
||||||
"FROM ResourceTable r LEFT JOIN FETCH r." + fieldName + " WHERE r.myId IN ( :IDS )",
|
+ " on r.myVersion = h.myResourceVersion and r.id = h.myResourceId "
|
||||||
ResourceTable.class);
|
+ " left join fetch h.myProvenance "
|
||||||
query.setParameter("IDS", ids);
|
+ " WHERE r.myId IN ( :IDS ) ");
|
||||||
List<ResourceTable> indexFetchOutcome = query.getResultList();
|
query.setParameter("IDS", idChunk);
|
||||||
ourLog.debug("Pre-fetched {} {}} indexes", indexFetchOutcome.size(), typeDesc);
|
|
||||||
if (theEntityListToPopulate != null) {
|
@SuppressWarnings("unchecked")
|
||||||
theEntityListToPopulate.addAll(indexFetchOutcome);
|
Stream<Object[]> queryResultStream = query.getResultStream();
|
||||||
}
|
return queryResultStream
|
||||||
});
|
.map(nextPair -> {
|
||||||
|
// Store the matching ResourceHistoryTable in the transient slot on ResourceTable
|
||||||
|
ResourceTable result = (ResourceTable) nextPair[0];
|
||||||
|
ResourceHistoryTable currentVersion = (ResourceHistoryTable) nextPair[1];
|
||||||
|
result.setCurrentVersionEntity(currentVersion);
|
||||||
|
return result;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefetch a join field for the active subset of some ResourceTable entities.
|
||||||
|
* Convenience wrapper around prefetchByJoinClause() for simple fields.
|
||||||
|
*
|
||||||
|
* @param theDescription for logging
|
||||||
|
* @param theJpaFieldName the join field from ResourceTable
|
||||||
|
* @param theEntityPredicate select which ResourceTable entities need this join
|
||||||
|
* @param theEntities the ResourceTable entities to consider
|
||||||
|
*/
|
||||||
|
private void prefetchByField(
|
||||||
|
String theDescription,
|
||||||
|
String theJpaFieldName,
|
||||||
|
Predicate<ResourceTable> theEntityPredicate,
|
||||||
|
List<ResourceTable> theEntities) {
|
||||||
|
|
||||||
|
String joinClause = "LEFT JOIN FETCH r." + theJpaFieldName;
|
||||||
|
|
||||||
|
prefetchByJoinClause(theDescription, joinClause, theEntityPredicate, theEntities);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefetch a join field for the active subset of some ResourceTable entities.
|
||||||
|
*
|
||||||
|
* @param theDescription for logging
|
||||||
|
* @param theJoinClause the JPA join expression to add to `ResourceTable r`
|
||||||
|
* @param theEntityPredicate selects which entities need this prefetch
|
||||||
|
* @param theEntities the ResourceTable entities to consider
|
||||||
|
*/
|
||||||
|
private void prefetchByJoinClause(
|
||||||
|
String theDescription,
|
||||||
|
String theJoinClause,
|
||||||
|
Predicate<ResourceTable> theEntityPredicate,
|
||||||
|
List<ResourceTable> theEntities) {
|
||||||
|
|
||||||
|
// Which entities need this prefetch?
|
||||||
|
List<Long> idSubset = theEntities.stream()
|
||||||
|
.filter(theEntityPredicate)
|
||||||
|
.map(ResourceTable::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (idSubset.isEmpty()) {
|
||||||
|
// nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String jqlQuery = "FROM ResourceTable r " + theJoinClause + " WHERE r.myId IN ( :IDS )";
|
||||||
|
|
||||||
|
TypedQuery<ResourceTable> query = myEntityManager.createQuery(jqlQuery, ResourceTable.class);
|
||||||
|
query.setParameter("IDS", idSubset);
|
||||||
|
List<ResourceTable> indexFetchOutcome = query.getResultList();
|
||||||
|
|
||||||
|
ourLog.debug("Pre-fetched {} {} indexes", indexFetchOutcome.size(), theDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* #%L
|
|
||||||
* HAPI FHIR JPA Server
|
|
||||||
* %%
|
|
||||||
* 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.jpa.dao.data;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Legacy forced_id implementation.
|
|
||||||
*
|
|
||||||
* @deprecated we now have a fhir_id column directly on HFJ_RESOURCE.
|
|
||||||
* No runtime code should query this table except for deletions by PK.
|
|
||||||
* To be deleted in 2024 (zero-downtime).
|
|
||||||
*/
|
|
||||||
@Deprecated(since = "6.10")
|
|
||||||
@Repository
|
|
||||||
public interface IForcedIdDao extends JpaRepository<ForcedId, Long>, IHapiFhirJpaRepository {
|
|
||||||
|
|
||||||
@Modifying
|
|
||||||
@Query("DELETE FROM ForcedId t WHERE t.myId = :pid")
|
|
||||||
void deleteByPid(@Param("pid") Long theId);
|
|
||||||
}
|
|
|
@ -43,7 +43,6 @@ public interface IResourceLinkDao extends JpaRepository<ResourceLink, Long>, IHa
|
||||||
* Loads a collection of ResourceLink entities by PID, but also eagerly fetches
|
* Loads a collection of ResourceLink entities by PID, but also eagerly fetches
|
||||||
* the target resources and their forced IDs
|
* the target resources and their forced IDs
|
||||||
*/
|
*/
|
||||||
@Query(
|
@Query("SELECT t FROM ResourceLink t LEFT JOIN FETCH t.myTargetResource tr WHERE t.myId in :pids")
|
||||||
"SELECT t FROM ResourceLink t LEFT JOIN FETCH t.myTargetResource tr LEFT JOIN FETCH tr.myForcedId WHERE t.myId in :pids")
|
|
||||||
List<ResourceLink> findByPidAndFetchTargetDetails(@Param("pids") List<Long> thePids);
|
List<ResourceLink> findByPidAndFetchTargetDetails(@Param("pids") List<Long> thePids);
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,25 +177,26 @@ public interface IResourceTableDao
|
||||||
@Query("SELECT t.myId, t.myResourceType, t.myVersion FROM ResourceTable t WHERE t.myId IN ( :pid )")
|
@Query("SELECT t.myId, t.myResourceType, t.myVersion FROM ResourceTable t WHERE t.myId IN ( :pid )")
|
||||||
Collection<Object[]> getResourceVersionsForPid(@Param("pid") List<Long> pid);
|
Collection<Object[]> getResourceVersionsForPid(@Param("pid") List<Long> pid);
|
||||||
|
|
||||||
@Query(
|
@Query("SELECT t FROM ResourceTable t WHERE t.myPartitionId.myPartitionId IS NULL AND t.myId = :pid")
|
||||||
"SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId IS NULL AND t.myId = :pid")
|
|
||||||
Optional<ResourceTable> readByPartitionIdNull(@Param("pid") Long theResourceId);
|
Optional<ResourceTable> readByPartitionIdNull(@Param("pid") Long theResourceId);
|
||||||
|
|
||||||
@Query(
|
@Query("SELECT t FROM ResourceTable t WHERE t.myPartitionId.myPartitionId = :partitionId AND t.myId = :pid")
|
||||||
"SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId = :partitionId AND t.myId = :pid")
|
|
||||||
Optional<ResourceTable> readByPartitionId(
|
Optional<ResourceTable> readByPartitionId(
|
||||||
@Param("partitionId") int thePartitionId, @Param("pid") Long theResourceId);
|
@Param("partitionId") int thePartitionId, @Param("pid") Long theResourceId);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE (t.myPartitionId.myPartitionId IS NULL OR t.myPartitionId.myPartitionId IN (:partitionIds)) AND t.myId = :pid")
|
"SELECT t FROM ResourceTable t WHERE (t.myPartitionId.myPartitionId IS NULL OR t.myPartitionId.myPartitionId IN (:partitionIds)) AND t.myId = :pid")
|
||||||
Optional<ResourceTable> readByPartitionIdsOrNull(
|
Optional<ResourceTable> readByPartitionIdsOrNull(
|
||||||
@Param("partitionIds") Collection<Integer> thrValues, @Param("pid") Long theResourceId);
|
@Param("partitionIds") Collection<Integer> thrValues, @Param("pid") Long theResourceId);
|
||||||
|
|
||||||
@Query(
|
@Query("SELECT t FROM ResourceTable t WHERE t.myPartitionId.myPartitionId IN (:partitionIds) AND t.myId = :pid")
|
||||||
"SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myPartitionId.myPartitionId IN (:partitionIds) AND t.myId = :pid")
|
|
||||||
Optional<ResourceTable> readByPartitionIds(
|
Optional<ResourceTable> readByPartitionIds(
|
||||||
@Param("partitionIds") Collection<Integer> thrValues, @Param("pid") Long theResourceId);
|
@Param("partitionIds") Collection<Integer> thrValues, @Param("pid") Long theResourceId);
|
||||||
|
|
||||||
@Query("SELECT t FROM ResourceTable t LEFT JOIN FETCH t.myForcedId WHERE t.myId IN :pids")
|
@Query("SELECT t FROM ResourceTable t WHERE t.myId IN :pids")
|
||||||
List<ResourceTable> findAllByIdAndLoadForcedIds(@Param("pids") List<Long> thePids);
|
List<ResourceTable> findAllByIdAndLoadForcedIds(@Param("pids") List<Long> thePids);
|
||||||
|
|
||||||
|
@Query("SELECT t FROM ResourceTable t where t.myResourceType = :restype and t.myFhirId = :fhirId")
|
||||||
|
Optional<ResourceTable> findByTypeAndFhirId(
|
||||||
|
@Param("restype") String theResourceName, @Param("fhirId") String theFhirId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,9 +53,7 @@ public interface ITermValueSetDao extends JpaRepository<TermValueSet, Long>, IHa
|
||||||
* The current TermValueSet is not necessarily the last uploaded anymore, but the current VS resource
|
* The current TermValueSet is not necessarily the last uploaded anymore, but the current VS resource
|
||||||
* is pointed by a specific ForcedId, so we locate current ValueSet as the one pointing to current VS resource
|
* is pointed by a specific ForcedId, so we locate current ValueSet as the one pointing to current VS resource
|
||||||
*/
|
*/
|
||||||
@Query(
|
@Query(value = "SELECT vs FROM TermValueSet vs where vs.myResource.myFhirId = :forcedId ")
|
||||||
value =
|
|
||||||
"SELECT vs FROM ForcedId f, TermValueSet vs where f.myForcedId = :forcedId and vs.myResource = f.myResource")
|
|
||||||
Optional<TermValueSet> findTermValueSetByForcedId(@Param("forcedId") String theForcedId);
|
Optional<TermValueSet> findTermValueSetByForcedId(@Param("forcedId") String theForcedId);
|
||||||
|
|
||||||
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion IS NULL")
|
@Query("SELECT vs FROM TermValueSet vs WHERE vs.myUrl = :url AND vs.myVersion IS NULL")
|
||||||
|
|
|
@ -47,7 +47,6 @@ import ca.uhn.fhir.jpa.entity.TermConceptProperty;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
|
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
|
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.NpmPackageEntity;
|
import ca.uhn.fhir.jpa.model.entity.NpmPackageEntity;
|
||||||
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
|
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
|
||||||
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity;
|
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity;
|
||||||
|
@ -174,7 +173,6 @@ public class ExpungeEverythingService implements IExpungeEverythingService {
|
||||||
expungeEverythingByTypeWithoutPurging(theRequest, BulkImportJobFileEntity.class, requestPartitionId));
|
expungeEverythingByTypeWithoutPurging(theRequest, BulkImportJobFileEntity.class, requestPartitionId));
|
||||||
counter.addAndGet(
|
counter.addAndGet(
|
||||||
expungeEverythingByTypeWithoutPurging(theRequest, BulkImportJobEntity.class, requestPartitionId));
|
expungeEverythingByTypeWithoutPurging(theRequest, BulkImportJobEntity.class, requestPartitionId));
|
||||||
counter.addAndGet(expungeEverythingByTypeWithoutPurging(theRequest, ForcedId.class, requestPartitionId));
|
|
||||||
counter.addAndGet(expungeEverythingByTypeWithoutPurging(
|
counter.addAndGet(expungeEverythingByTypeWithoutPurging(
|
||||||
theRequest, ResourceIndexedSearchParamDate.class, requestPartitionId));
|
theRequest, ResourceIndexedSearchParamDate.class, requestPartitionId));
|
||||||
counter.addAndGet(expungeEverythingByTypeWithoutPurging(
|
counter.addAndGet(expungeEverythingByTypeWithoutPurging(
|
||||||
|
|
|
@ -27,7 +27,6 @@ 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.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser;
|
import ca.uhn.fhir.jpa.dao.IJpaStorageResourceParser;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTagDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTagDao;
|
||||||
|
@ -46,7 +45,6 @@ import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTagDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
|
import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
|
||||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||||
|
@ -79,9 +77,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
public class JpaResourceExpungeService implements IResourceExpungeService<JpaPid> {
|
public class JpaResourceExpungeService implements IResourceExpungeService<JpaPid> {
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(JpaResourceExpungeService.class);
|
private static final Logger ourLog = LoggerFactory.getLogger(JpaResourceExpungeService.class);
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IForcedIdDao myForcedIdDao;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IResourceTableDao myResourceTableDao;
|
private IResourceTableDao myResourceTableDao;
|
||||||
|
|
||||||
|
@ -323,11 +318,6 @@ public class JpaResourceExpungeService implements IResourceExpungeService<JpaPid
|
||||||
myResourceTagDao.deleteByResourceId(resource.getId());
|
myResourceTagDao.deleteByResourceId(resource.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resource.getForcedId() != null) {
|
|
||||||
ForcedId forcedId = resource.getForcedId();
|
|
||||||
myForcedIdDao.deleteByPid(forcedId.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
myResourceTableDao.deleteByPid(resource.getId());
|
myResourceTableDao.deleteByPid(resource.getId());
|
||||||
} catch (DataIntegrityViolationException e) {
|
} catch (DataIntegrityViolationException e) {
|
||||||
throw new PreconditionFailedException(Msg.code(2415)
|
throw new PreconditionFailedException(Msg.code(2415)
|
||||||
|
|
|
@ -44,7 +44,6 @@ public class ResourceTableFKProvider {
|
||||||
retval.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID"));
|
retval.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID"));
|
||||||
|
|
||||||
// These have the possibility of touching all resource types.
|
// These have the possibility of touching all resource types.
|
||||||
retval.add(new ResourceForeignKey("HFJ_FORCED_ID", "RESOURCE_PID"));
|
|
||||||
retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID"));
|
retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID"));
|
||||||
retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID"));
|
retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID"));
|
||||||
retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID"));
|
retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID"));
|
||||||
|
@ -83,7 +82,6 @@ public class ResourceTableFKProvider {
|
||||||
// These have the possibility of touching all resource types.
|
// These have the possibility of touching all resource types.
|
||||||
retval.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID"));
|
retval.add(new ResourceForeignKey("HFJ_HISTORY_TAG", "RES_ID"));
|
||||||
retval.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID"));
|
retval.add(new ResourceForeignKey("HFJ_RES_VER_PROV", "RES_PID"));
|
||||||
retval.add(new ResourceForeignKey("HFJ_FORCED_ID", "RESOURCE_PID"));
|
|
||||||
retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID"));
|
retval.add(new ResourceForeignKey("HFJ_IDX_CMP_STRING_UNIQ", "RES_ID"));
|
||||||
retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID"));
|
retval.add(new ResourceForeignKey("HFJ_IDX_CMB_TOK_NU", "RES_ID"));
|
||||||
retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID"));
|
retval.add(new ResourceForeignKey("HFJ_RES_LINK", "SRC_RESOURCE_ID"));
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class TermConceptMapGroupElementTarget implements Serializable {
|
||||||
foreignKey = @ForeignKey(name = "FK_TCMGETARGET_ELEMENT"))
|
foreignKey = @ForeignKey(name = "FK_TCMGETARGET_ELEMENT"))
|
||||||
private TermConceptMapGroupElement myConceptMapGroupElement;
|
private TermConceptMapGroupElement myConceptMapGroupElement;
|
||||||
|
|
||||||
@Column(name = "TARGET_CODE", nullable = false, length = TermConcept.MAX_CODE_LENGTH)
|
@Column(name = "TARGET_CODE", nullable = true, length = TermConcept.MAX_CODE_LENGTH)
|
||||||
private String myCode;
|
private String myCode;
|
||||||
|
|
||||||
@Column(name = "TARGET_DISPLAY", nullable = true, length = TermConcept.MAX_DISP_LENGTH)
|
@Column(name = "TARGET_DISPLAY", nullable = true, length = TermConcept.MAX_DISP_LENGTH)
|
||||||
|
|
|
@ -119,6 +119,26 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
||||||
init680();
|
init680();
|
||||||
init680_Part2();
|
init680_Part2();
|
||||||
init700();
|
init700();
|
||||||
|
init720();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init720() {
|
||||||
|
// Start of migrations from 7.0 to 7.2
|
||||||
|
|
||||||
|
Builder version = forVersion(VersionEnum.V7_2_0);
|
||||||
|
|
||||||
|
// allow null codes in concept map targets
|
||||||
|
version.onTable("TRM_CONCEPT_MAP_GRP_ELM_TGT")
|
||||||
|
.modifyColumn("20240327.1", "TARGET_CODE")
|
||||||
|
.nullable()
|
||||||
|
.withType(ColumnTypeEnum.STRING, 500);
|
||||||
|
|
||||||
|
// Stop writing to hfj_forced_id https://github.com/hapifhir/hapi-fhir/pull/5817
|
||||||
|
Builder.BuilderWithTableName forcedId = version.onTable("HFJ_FORCED_ID");
|
||||||
|
forcedId.dropForeignKey("20240402.1", "FK_FORCEDID_RESOURCE", "HFJ_RESOURCE");
|
||||||
|
forcedId.dropIndex("20240402.2", "IDX_FORCEDID_RESID");
|
||||||
|
forcedId.dropIndex("20240402.3", "IDX_FORCEDID_TYPE_FID");
|
||||||
|
forcedId.dropIndex("20240402.4", "IDX_FORCEID_FID");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void init700() {
|
protected void init700() {
|
||||||
|
@ -1398,9 +1418,9 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
||||||
.addIndex("20211210.4", "FK_FORCEDID_RESOURCE")
|
.addIndex("20211210.4", "FK_FORCEDID_RESOURCE")
|
||||||
.unique(true)
|
.unique(true)
|
||||||
.withColumns("RESOURCE_PID")
|
.withColumns("RESOURCE_PID")
|
||||||
.doNothing() // This migration was added in error, as this table already has a unique constraint on
|
|
||||||
// RESOURCE_PID and every database creates an index on anything that is unique.
|
// RESOURCE_PID and every database creates an index on anything that is unique.
|
||||||
.onlyAppliesToPlatforms(NON_AUTOMATIC_FK_INDEX_PLATFORMS);
|
.onlyAppliesToPlatforms(NON_AUTOMATIC_FK_INDEX_PLATFORMS)
|
||||||
|
.doNothing(); // This migration was added in error, as this table already has a unique constraint on
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init570() {
|
private void init570() {
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.hibernate.ScrollMode;
|
||||||
import org.hibernate.ScrollableResults;
|
import org.hibernate.ScrollableResults;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
|
import org.hl7.fhir.r4.model.Enumerations;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -416,6 +417,10 @@ public class TermConceptClientMappingSvcImpl implements ITermConceptClientMappin
|
||||||
theTranslationResult.setResult(false);
|
theTranslationResult.setResult(false);
|
||||||
msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "noMatchesFound");
|
msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "noMatchesFound");
|
||||||
theTranslationResult.setMessage(msg);
|
theTranslationResult.setMessage(msg);
|
||||||
|
} else if (isOnlyNegativeMatches(theTranslationResult)) {
|
||||||
|
theTranslationResult.setResult(false);
|
||||||
|
msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "onlyNegativeMatchesFound");
|
||||||
|
theTranslationResult.setMessage(msg);
|
||||||
} else {
|
} else {
|
||||||
theTranslationResult.setResult(true);
|
theTranslationResult.setResult(true);
|
||||||
msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "matchesFound");
|
msg = myContext.getLocalizer().getMessage(TermConceptMappingSvcImpl.class, "matchesFound");
|
||||||
|
@ -423,6 +428,21 @@ public class TermConceptClientMappingSvcImpl implements ITermConceptClientMappin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates whether a translation result contains any positive matches or only negative ones. This is required
|
||||||
|
* because the <a href="https://hl7.org/fhir/R4/conceptmap-operation-translate.html">FHIR specification</a> states
|
||||||
|
* that the result field "can only be true if at least one returned match has an equivalence which is not unmatched
|
||||||
|
* or disjoint".
|
||||||
|
* @param theTranslationResult the translation result to be evaluated
|
||||||
|
* @return true if all the potential matches in the result have a negative valence (i.e., "unmatched" and "disjoint")
|
||||||
|
*/
|
||||||
|
private boolean isOnlyNegativeMatches(TranslateConceptResults theTranslationResult) {
|
||||||
|
return theTranslationResult.getResults().stream()
|
||||||
|
.map(TranslateConceptResult::getEquivalence)
|
||||||
|
.allMatch(t -> StringUtils.equals(Enumerations.ConceptMapEquivalence.UNMATCHED.toCode(), t)
|
||||||
|
|| StringUtils.equals(Enumerations.ConceptMapEquivalence.DISJOINT.toCode(), t));
|
||||||
|
}
|
||||||
|
|
||||||
private boolean alreadyContainsMapping(
|
private boolean alreadyContainsMapping(
|
||||||
List<TranslateConceptResult> elements, TranslateConceptResult translationMatch) {
|
List<TranslateConceptResult> elements, TranslateConceptResult translationMatch) {
|
||||||
for (TranslateConceptResult nextExistingElement : elements) {
|
for (TranslateConceptResult nextExistingElement : elements) {
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.hl7.fhir.r4.model.BooleanType;
|
||||||
import org.hl7.fhir.r4.model.CodeType;
|
import org.hl7.fhir.r4.model.CodeType;
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
|
import org.hl7.fhir.r4.model.Enumerations;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
import org.hl7.fhir.r4.model.Parameters;
|
import org.hl7.fhir.r4.model.Parameters;
|
||||||
import org.hl7.fhir.r4.model.StringType;
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
|
@ -218,13 +219,17 @@ public class TermConceptMappingSvcImpl extends TermConceptClientMappingSvcImpl i
|
||||||
if (element.hasTarget()) {
|
if (element.hasTarget()) {
|
||||||
TermConceptMapGroupElementTarget termConceptMapGroupElementTarget;
|
TermConceptMapGroupElementTarget termConceptMapGroupElementTarget;
|
||||||
for (ConceptMap.TargetElementComponent elementTarget : element.getTarget()) {
|
for (ConceptMap.TargetElementComponent elementTarget : element.getTarget()) {
|
||||||
if (isBlank(elementTarget.getCode())) {
|
if (isBlank(elementTarget.getCode())
|
||||||
|
&& elementTarget.getEquivalence()
|
||||||
|
!= Enumerations.ConceptMapEquivalence.UNMATCHED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
termConceptMapGroupElementTarget = new TermConceptMapGroupElementTarget();
|
termConceptMapGroupElementTarget = new TermConceptMapGroupElementTarget();
|
||||||
termConceptMapGroupElementTarget.setConceptMapGroupElement(termConceptMapGroupElement);
|
termConceptMapGroupElementTarget.setConceptMapGroupElement(termConceptMapGroupElement);
|
||||||
termConceptMapGroupElementTarget.setCode(elementTarget.getCode());
|
if (isNotBlank(elementTarget.getCode())) {
|
||||||
termConceptMapGroupElementTarget.setDisplay(elementTarget.getDisplay());
|
termConceptMapGroupElementTarget.setCode(elementTarget.getCode());
|
||||||
|
termConceptMapGroupElementTarget.setDisplay(elementTarget.getDisplay());
|
||||||
|
}
|
||||||
termConceptMapGroupElementTarget.setEquivalence(elementTarget.getEquivalence());
|
termConceptMapGroupElementTarget.setEquivalence(elementTarget.getEquivalence());
|
||||||
termConceptMapGroupElement
|
termConceptMapGroupElement
|
||||||
.getConceptMapGroupElementTargets()
|
.getConceptMapGroupElementTargets()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
-- we can't use convering index until the autovacuum runs for those rows, which kills index performance
|
-- we can't use covering index until the autovacuum runs for those rows, which kills index performance
|
||||||
ALTER TABLE hfj_resource SET (autovacuum_vacuum_scale_factor = 0.01);
|
ALTER TABLE hfj_resource SET (autovacuum_vacuum_scale_factor = 0.01);
|
||||||
ALTER TABLE hfj_forced_id SET (autovacuum_vacuum_scale_factor = 0.01);
|
ALTER TABLE hfj_forced_id SET (autovacuum_vacuum_scale_factor = 0.01);
|
||||||
ALTER TABLE hfj_res_link SET (autovacuum_vacuum_scale_factor = 0.01);
|
ALTER TABLE hfj_res_link SET (autovacuum_vacuum_scale_factor = 0.01);
|
||||||
|
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -29,7 +29,6 @@ import jakarta.persistence.Enumerated;
|
||||||
import jakarta.persistence.MappedSuperclass;
|
import jakarta.persistence.MappedSuperclass;
|
||||||
import jakarta.persistence.Temporal;
|
import jakarta.persistence.Temporal;
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
import jakarta.persistence.Transient;
|
|
||||||
import org.hibernate.annotations.OptimisticLock;
|
import org.hibernate.annotations.OptimisticLock;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -65,22 +64,6 @@ public abstract class BaseHasResource extends BasePartitionable
|
||||||
@OptimisticLock(excluded = true)
|
@OptimisticLock(excluded = true)
|
||||||
private Date myUpdated;
|
private Date myUpdated;
|
||||||
|
|
||||||
/**
|
|
||||||
* This is stored as an optimization to avoid needing to query for this
|
|
||||||
* after an update
|
|
||||||
*/
|
|
||||||
@Transient
|
|
||||||
// TODO MB forced_id delete this in step 3
|
|
||||||
private transient String myTransientForcedId;
|
|
||||||
|
|
||||||
public String getTransientForcedId() {
|
|
||||||
return myTransientForcedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransientForcedId(String theTransientForcedId) {
|
|
||||||
myTransientForcedId = theTransientForcedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract BaseTag addTag(TagDefinition theDef);
|
public abstract BaseTag addTag(TagDefinition theDef);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -97,13 +80,6 @@ public abstract class BaseHasResource extends BasePartitionable
|
||||||
myFhirVersion = theFhirVersion;
|
myFhirVersion = theFhirVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract ForcedId getForcedId();
|
|
||||||
|
|
||||||
public abstract void setForcedId(ForcedId theForcedId);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract Long getId();
|
|
||||||
|
|
||||||
public void setDeleted(Date theDate) {
|
public void setDeleted(Date theDate) {
|
||||||
myDeleted = theDate;
|
myDeleted = theDate;
|
||||||
}
|
}
|
||||||
|
@ -129,12 +105,6 @@ public abstract class BaseHasResource extends BasePartitionable
|
||||||
myPublished = thePublished.getValue();
|
myPublished = thePublished.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract Long getResourceId();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract String getResourceType();
|
|
||||||
|
|
||||||
public abstract Collection<? extends BaseTag> getTags();
|
public abstract Collection<? extends BaseTag> getTags();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -151,9 +121,6 @@ public abstract class BaseHasResource extends BasePartitionable
|
||||||
myUpdated = theUpdated;
|
myUpdated = theUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract long getVersion();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isHasTags() {
|
public boolean isHasTags() {
|
||||||
return myHasTags;
|
return myHasTags;
|
||||||
|
|
|
@ -21,51 +21,24 @@ package ca.uhn.fhir.jpa.model.entity;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.ForeignKey;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import jakarta.persistence.GenerationType;
|
import jakarta.persistence.GenerationType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Index;
|
|
||||||
import jakarta.persistence.JoinColumn;
|
|
||||||
import jakarta.persistence.OneToOne;
|
|
||||||
import jakarta.persistence.SequenceGenerator;
|
import jakarta.persistence.SequenceGenerator;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import jakarta.persistence.UniqueConstraint;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import org.hibernate.annotations.ColumnDefault;
|
import org.hibernate.annotations.ColumnDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The old way we handled client-assigned resource ids.
|
||||||
|
* Replaced by {@link ResourceTable#myFhirId}.
|
||||||
|
* @deprecated This is unused, and only kept for history and upgrade migration testing.
|
||||||
|
*/
|
||||||
@Entity()
|
@Entity()
|
||||||
@Table(
|
@Table(name = ForcedId.HFJ_FORCED_ID)
|
||||||
name = ForcedId.HFJ_FORCED_ID,
|
@Deprecated(since = "7.1", forRemoval = true)
|
||||||
uniqueConstraints = {
|
class ForcedId extends BasePartitionable {
|
||||||
@UniqueConstraint(
|
|
||||||
name = "IDX_FORCEDID_RESID",
|
|
||||||
columnNames = {"RESOURCE_PID"}),
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This index is called IDX_FORCEDID_TYPE_FID and guarantees
|
|
||||||
* uniqueness of RESOURCE_TYPE,FORCED_ID. This doesn't make sense
|
|
||||||
* for partitioned servers, so we replace it on those servers
|
|
||||||
* with IDX_FORCEDID_TYPE_PFID covering
|
|
||||||
* PARTITION_ID,RESOURCE_TYPE,FORCED_ID
|
|
||||||
*/
|
|
||||||
@UniqueConstraint(
|
|
||||||
name = ForcedId.IDX_FORCEDID_TYPE_FID,
|
|
||||||
columnNames = {"RESOURCE_TYPE", "FORCED_ID"})
|
|
||||||
},
|
|
||||||
indexes = {
|
|
||||||
/*
|
|
||||||
* NB: We previously had indexes named
|
|
||||||
* - IDX_FORCEDID_TYPE_FORCEDID
|
|
||||||
* - IDX_FORCEDID_TYPE_RESID
|
|
||||||
* so don't reuse these names
|
|
||||||
*/
|
|
||||||
@Index(name = "IDX_FORCEID_FID", columnList = "FORCED_ID"),
|
|
||||||
// @Index(name = "IDX_FORCEID_RESID", columnList = "RESOURCE_PID"),
|
|
||||||
})
|
|
||||||
public class ForcedId extends BasePartitionable {
|
|
||||||
|
|
||||||
public static final int MAX_FORCED_ID_LENGTH = 100;
|
public static final int MAX_FORCED_ID_LENGTH = 100;
|
||||||
public static final String IDX_FORCEDID_TYPE_FID = "IDX_FORCEDID_TYPE_FID";
|
public static final String IDX_FORCEDID_TYPE_FID = "IDX_FORCEDID_TYPE_FID";
|
||||||
|
@ -80,14 +53,6 @@ public class ForcedId extends BasePartitionable {
|
||||||
@Column(name = "PID")
|
@Column(name = "PID")
|
||||||
private Long myId;
|
private Long myId;
|
||||||
|
|
||||||
@JoinColumn(
|
|
||||||
name = "RESOURCE_PID",
|
|
||||||
nullable = false,
|
|
||||||
updatable = false,
|
|
||||||
foreignKey = @ForeignKey(name = "FK_FORCEDID_RESOURCE"))
|
|
||||||
@OneToOne(fetch = FetchType.LAZY)
|
|
||||||
private ResourceTable myResource;
|
|
||||||
|
|
||||||
@Column(name = "RESOURCE_PID", nullable = false, updatable = false, insertable = false)
|
@Column(name = "RESOURCE_PID", nullable = false, updatable = false, insertable = false)
|
||||||
private Long myResourcePid;
|
private Long myResourcePid;
|
||||||
|
|
||||||
|
@ -112,10 +77,6 @@ public class ForcedId extends BasePartitionable {
|
||||||
myForcedId = theForcedId;
|
myForcedId = theForcedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResource(ResourceTable theResource) {
|
|
||||||
myResource = theResource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getResourceType() {
|
public String getResourceType() {
|
||||||
return myResourceType;
|
return myResourceType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,26 @@ package ca.uhn.fhir.jpa.model.entity;
|
||||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.ForeignKey;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Index;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.Lob;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import jakarta.persistence.SequenceGenerator;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.persistence.Transient;
|
||||||
|
import jakarta.persistence.UniqueConstraint;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import org.hibernate.Length;
|
import org.hibernate.Length;
|
||||||
|
@ -111,6 +130,12 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private transient ResourceHistoryProvenanceEntity myNewHistoryProvenanceEntity;
|
private transient ResourceHistoryProvenanceEntity myNewHistoryProvenanceEntity;
|
||||||
|
/**
|
||||||
|
* This is stored as an optimization to avoid needing to fetch ResourceTable
|
||||||
|
* to access the resource id.
|
||||||
|
*/
|
||||||
|
@Transient
|
||||||
|
private transient String myTransientForcedId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -280,16 +305,6 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
return new IdDt(getResourceType() + '/' + resourceIdPart + '/' + Constants.PARAM_HISTORY + '/' + getVersion());
|
return new IdDt(getResourceType() + '/' + resourceIdPart + '/' + Constants.PARAM_HISTORY + '/' + getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForcedId getForcedId() {
|
|
||||||
return getResourceTable().getForcedId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setForcedId(ForcedId theForcedId) {
|
|
||||||
getResourceTable().setForcedId(theForcedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if there is a populated resource text (i.e.
|
* Returns <code>true</code> if there is a populated resource text (i.e.
|
||||||
* either {@link #getResource()} or {@link #getResourceTextVc()} return a non null
|
* either {@link #getResource()} or {@link #getResourceTextVc()} return a non null
|
||||||
|
@ -311,4 +326,12 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
}
|
}
|
||||||
return myNewHistoryProvenanceEntity;
|
return myNewHistoryProvenanceEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTransientForcedId() {
|
||||||
|
return myTransientForcedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransientForcedId(String theTransientForcedId) {
|
||||||
|
myTransientForcedId = theTransientForcedId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Index;
|
import jakarta.persistence.Index;
|
||||||
import jakarta.persistence.NamedEntityGraph;
|
import jakarta.persistence.NamedEntityGraph;
|
||||||
import jakarta.persistence.OneToMany;
|
import jakarta.persistence.OneToMany;
|
||||||
import jakarta.persistence.OneToOne;
|
|
||||||
import jakarta.persistence.PostPersist;
|
import jakarta.persistence.PostPersist;
|
||||||
import jakarta.persistence.PrePersist;
|
import jakarta.persistence.PrePersist;
|
||||||
import jakarta.persistence.PreUpdate;
|
import jakarta.persistence.PreUpdate;
|
||||||
|
@ -420,15 +419,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
||||||
@Transient
|
@Transient
|
||||||
private transient boolean myVersionUpdatedInCurrentTransaction;
|
private transient boolean myVersionUpdatedInCurrentTransaction;
|
||||||
|
|
||||||
@OneToOne(
|
|
||||||
optional = true,
|
|
||||||
fetch = FetchType.EAGER,
|
|
||||||
cascade = {},
|
|
||||||
orphanRemoval = false,
|
|
||||||
mappedBy = "myResource")
|
|
||||||
@OptimisticLock(excluded = true)
|
|
||||||
private ForcedId myForcedId;
|
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private volatile String myCreatedByMatchUrl;
|
private volatile String myCreatedByMatchUrl;
|
||||||
|
|
||||||
|
@ -889,10 +879,9 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
||||||
|
|
||||||
retVal.setResourceId(myId);
|
retVal.setResourceId(myId);
|
||||||
retVal.setResourceType(myResourceType);
|
retVal.setResourceType(myResourceType);
|
||||||
retVal.setTransientForcedId(getTransientForcedId());
|
retVal.setTransientForcedId(getFhirId());
|
||||||
retVal.setFhirVersion(getFhirVersion());
|
retVal.setFhirVersion(getFhirVersion());
|
||||||
retVal.setResourceTable(this);
|
retVal.setResourceTable(this);
|
||||||
retVal.setForcedId(getForcedId());
|
|
||||||
retVal.setPartitionId(getPartitionId());
|
retVal.setPartitionId(getPartitionId());
|
||||||
|
|
||||||
retVal.setHasTags(isHasTags());
|
retVal.setHasTags(isHasTags());
|
||||||
|
@ -923,6 +912,7 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
||||||
public String toString() {
|
public String toString() {
|
||||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||||
b.append("pid", myId);
|
b.append("pid", myId);
|
||||||
|
b.append("fhirId", myFhirId);
|
||||||
b.append("resourceType", myResourceType);
|
b.append("resourceType", myResourceType);
|
||||||
b.append("version", myVersion);
|
b.append("version", myVersion);
|
||||||
if (getPartitionId() != null) {
|
if (getPartitionId() != null) {
|
||||||
|
@ -970,16 +960,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
||||||
return JpaPid.fromId(getId());
|
return JpaPid.fromId(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForcedId getForcedId() {
|
|
||||||
return myForcedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setForcedId(ForcedId theForcedId) {
|
|
||||||
myForcedId = theForcedId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdDt getIdDt() {
|
public IdDt getIdDt() {
|
||||||
IdDt retVal = new IdDt();
|
IdDt retVal = new IdDt();
|
||||||
|
@ -997,10 +977,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
|
||||||
String resourceId;
|
String resourceId;
|
||||||
if (myFhirId != null && !myFhirId.isEmpty()) {
|
if (myFhirId != null && !myFhirId.isEmpty()) {
|
||||||
resourceId = myFhirId;
|
resourceId = myFhirId;
|
||||||
} else if (getTransientForcedId() != null) {
|
|
||||||
resourceId = getTransientForcedId();
|
|
||||||
} else if (myForcedId != null) {
|
|
||||||
resourceId = myForcedId.getForcedId();
|
|
||||||
} else {
|
} else {
|
||||||
Long id = this.getResourceId();
|
Long id = this.getResourceId();
|
||||||
resourceId = Long.toString(id);
|
resourceId = Long.toString(id);
|
||||||
|
|
|
@ -25,17 +25,15 @@ public class ResourceTableTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@CsvSource(value={
|
@CsvSource(value={
|
||||||
|
"123, null, Patient/123/_history/1",
|
||||||
"123, 123, Patient/123/_history/1",
|
"123, 123, Patient/123/_history/1",
|
||||||
", 123, Patient/123/_history/1",
|
"123, 456, Patient/456/_history/1"
|
||||||
"null, 456, Patient/456/_history/1"
|
|
||||||
},nullValues={"null"})
|
},nullValues={"null"})
|
||||||
public void testPopulateId(String theFhirId, String theForcedId, String theExpected) {
|
public void testPopulateId(Long theResId, String theFhirId, String theExpected) {
|
||||||
// Given
|
// Given
|
||||||
ResourceTable t = new ResourceTable();
|
ResourceTable t = new ResourceTable();
|
||||||
|
t.setId(theResId);
|
||||||
t.setFhirId(theFhirId);
|
t.setFhirId(theFhirId);
|
||||||
ForcedId forcedId = new ForcedId();
|
|
||||||
forcedId.setForcedId(theForcedId);
|
|
||||||
t.setForcedId(forcedId);
|
|
||||||
t.setResourceType(new Patient().getResourceType().name());
|
t.setResourceType(new Patient().getResourceType().name());
|
||||||
t.setVersionForUnitTest(1);
|
t.setVersionForUnitTest(1);
|
||||||
|
|
||||||
|
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.api.model.HistoryCountModeEnum;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseStorageDao;
|
import ca.uhn.fhir.jpa.dao.BaseStorageDao;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoTestUtils;
|
import ca.uhn.fhir.jpa.dao.DaoTestUtils;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|
||||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
|
||||||
|
@ -82,7 +81,6 @@ import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -112,8 +110,6 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||||
public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2Test.class);
|
||||||
@Autowired
|
|
||||||
private IForcedIdDao myForcedIdDao;
|
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public final void after() {
|
public final void after() {
|
||||||
|
@ -995,9 +991,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
idv2 = myPatientDao.update(patient, mySrd).getId();
|
idv2 = myPatientDao.update(patient, mySrd).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
runInTransaction(() -> {
|
logAllResources();
|
||||||
ourLog.info("Forced IDs:\n{}", myForcedIdDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n")));
|
|
||||||
});
|
|
||||||
|
|
||||||
List<Patient> patients = toList(myPatientDao.history(idv1.toVersionless(), null, null, null, mySrd));
|
List<Patient> patients = toList(myPatientDao.history(idv1.toVersionless(), null, null, null, mySrd));
|
||||||
assertTrue(patients.size() == 2);
|
assertTrue(patients.size() == 2);
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package ca.uhn.fhir.jpa.provider;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.gclient.TokenClientParam;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
public class ResourceProviderLanguageParamDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamEnabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(true);
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.setLanguage(new CodeDt("en"));
|
||||||
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient pat2 = new Patient();
|
||||||
|
pat.setLanguage(new CodeDt("fr"));
|
||||||
|
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
List<String> foundResources;
|
||||||
|
Bundle result;
|
||||||
|
|
||||||
|
result = myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
foundResources = toUnqualifiedVersionlessIdValues(result);
|
||||||
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamDisabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
|
||||||
|
myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
assertThat(exception.getMessage(), containsString(Msg.code(1223)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -626,16 +626,9 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
assertNotNull(readBackView, "found search view");
|
assertNotNull(readBackView, "found search view");
|
||||||
|
|
||||||
// verify the forced id join still works
|
assertEquals(myExpectedId, readBackView.getFhirId(),
|
||||||
if (readBackResource.getForcedId() != null) {
|
"fhir_id populated");
|
||||||
assertEquals(myExpectedId, readBackResource.getForcedId().getForcedId(),
|
}
|
||||||
"legacy join populated");
|
|
||||||
assertEquals(myExpectedId, readBackView.getFhirId(),
|
|
||||||
"legacy join populated");
|
|
||||||
} else {
|
|
||||||
assertEquals(IdStrategyEnum.SEQUENTIAL_NUMERIC, theServerIdStrategy,
|
|
||||||
"hfj_forced_id join column is only empty when using server-assigned ids");
|
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
package ca.uhn.fhir.jpa.provider.dstu3;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.gclient.TokenClientParam;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle;
|
||||||
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
public class ResourceProviderLanguageParamDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamEnabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(true);
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.setLanguage("en");
|
||||||
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient pat2 = new Patient();
|
||||||
|
pat.setLanguage("fr");
|
||||||
|
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
SearchParameterMap map;
|
||||||
|
IBundleProvider results;
|
||||||
|
List<String> foundResources;
|
||||||
|
Bundle result;
|
||||||
|
|
||||||
|
result = myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
foundResources = toUnqualifiedVersionlessIdValues(result);
|
||||||
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamDisabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.setLanguage("en");
|
||||||
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient pat2 = new Patient();
|
||||||
|
pat.setLanguage("fr");
|
||||||
|
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
SearchParameterMap map;
|
||||||
|
IBundleProvider results;
|
||||||
|
List<String> foundResources;
|
||||||
|
Bundle result;
|
||||||
|
|
||||||
|
|
||||||
|
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
|
||||||
|
myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
assertThat(exception.getMessage(), containsString(Msg.code(1223)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -321,6 +321,61 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void reductionStepFailing_willFailJob() throws InterruptedException {
|
||||||
|
// setup
|
||||||
|
String jobId = new Exception().getStackTrace()[0].getMethodName();
|
||||||
|
int totalChunks = 3;
|
||||||
|
AtomicInteger chunkCounter = new AtomicInteger();
|
||||||
|
String error = "this is an error";
|
||||||
|
|
||||||
|
buildAndDefine3StepReductionJob(jobId, new IReductionStepHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void firstStep(StepExecutionDetails<TestJobParameters, VoidModel> theStep, IJobDataSink<FirstStepOutput> theDataSink) {
|
||||||
|
for (int i = 0; i < totalChunks; i++) {
|
||||||
|
theDataSink.accept(new FirstStepOutput());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void secondStep(StepExecutionDetails<TestJobParameters, FirstStepOutput> theStep, IJobDataSink<SecondStepOutput> theDataSink) {
|
||||||
|
SecondStepOutput output = new SecondStepOutput();
|
||||||
|
theDataSink.accept(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reductionStepConsume(ChunkExecutionDetails<TestJobParameters, SecondStepOutput> theChunkDetails, IJobDataSink<ReductionStepOutput> theDataSink) {
|
||||||
|
chunkCounter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reductionStepRun(StepExecutionDetails<TestJobParameters, SecondStepOutput> theStepExecutionDetails, IJobDataSink<ReductionStepOutput> theDataSink) {
|
||||||
|
// always throw
|
||||||
|
throw new RuntimeException(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// test
|
||||||
|
JobInstanceStartRequest request = buildRequest(jobId);
|
||||||
|
myFirstStepLatch.setExpectedCount(1);
|
||||||
|
Batch2JobStartResponse startResponse = myJobCoordinator.startInstance(new SystemRequestDetails(), request);
|
||||||
|
String instanceId = startResponse.getInstanceId();
|
||||||
|
assertNotNull(instanceId);
|
||||||
|
|
||||||
|
// waiting for job to end (any status - but we'll verify failed later)
|
||||||
|
myBatch2JobHelper.awaitJobHasStatus(instanceId, StatusEnum.getEndedStatuses().toArray(new StatusEnum[0]));
|
||||||
|
|
||||||
|
// verify
|
||||||
|
Optional<JobInstance> instanceOp = myJobPersistence.fetchInstance(instanceId);
|
||||||
|
assertTrue(instanceOp.isPresent());
|
||||||
|
JobInstance jobInstance = instanceOp.get();
|
||||||
|
|
||||||
|
assertEquals(totalChunks, chunkCounter.get());
|
||||||
|
|
||||||
|
assertEquals(StatusEnum.FAILED, jobInstance.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testJobWithReductionStepFiresCompletionHandler() throws InterruptedException {
|
public void testJobWithReductionStepFiresCompletionHandler() throws InterruptedException {
|
||||||
// setup
|
// setup
|
||||||
|
|
|
@ -3,7 +3,6 @@ package ca.uhn.fhir.jpa.bulk.imprt2;
|
||||||
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
|
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
|
||||||
import ca.uhn.fhir.batch2.jobs.imprt.ConsumeFilesStep;
|
import ca.uhn.fhir.batch2.jobs.imprt.ConsumeFilesStep;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
|
||||||
import ca.uhn.fhir.jpa.dao.r4.BasePartitioningR4Test;
|
import ca.uhn.fhir.jpa.dao.r4.BasePartitioningR4Test;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
@ -84,7 +83,7 @@ public class ConsumeFilesStepR4Test extends BasePartitioningR4Test {
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
|
|
||||||
assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread(), myCaptureQueriesListener.getInsertQueriesForCurrentThread().stream().map(t->t.getSql(true, false)).collect(Collectors.joining("\n")));
|
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread(), myCaptureQueriesListener.getInsertQueriesForCurrentThread().stream().map(t->t.getSql(true, false)).collect(Collectors.joining("\n")));
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
@ -145,9 +144,9 @@ public class ConsumeFilesStepR4Test extends BasePartitioningR4Test {
|
||||||
// Validate
|
// Validate
|
||||||
|
|
||||||
if (partitionEnabled) {
|
if (partitionEnabled) {
|
||||||
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
|
||||||
} else {
|
|
||||||
assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
|
} else {
|
||||||
|
assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
}
|
}
|
||||||
assertEquals(2, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(2, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(4, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(4, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
|
@ -190,7 +189,7 @@ public class ConsumeFilesStepR4Test extends BasePartitioningR4Test {
|
||||||
assertThat(myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, false),
|
assertThat(myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, false),
|
||||||
either(containsString("rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='B' and rt1_0.PARTITION_ID is null or rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='A' and rt1_0.PARTITION_ID is null"))
|
either(containsString("rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='B' and rt1_0.PARTITION_ID is null or rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='A' and rt1_0.PARTITION_ID is null"))
|
||||||
.or(containsString("rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='A' and rt1_0.PARTITION_ID is null or rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='B' and rt1_0.PARTITION_ID is null")));
|
.or(containsString("rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='A' and rt1_0.PARTITION_ID is null or rt1_0.RES_TYPE='Patient' and rt1_0.FHIR_ID='B' and rt1_0.PARTITION_ID is null")));
|
||||||
assertEquals(52, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(50, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
assertEquals(1, myCaptureQueriesListener.countCommits());
|
assertEquals(1, myCaptureQueriesListener.countCommits());
|
||||||
|
|
|
@ -19,7 +19,6 @@ import ca.uhn.fhir.jpa.dao.tx.HapiTransactionService;
|
||||||
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
|
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
|
||||||
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
|
import ca.uhn.fhir.jpa.delete.DeleteConflictService;
|
||||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
||||||
import ca.uhn.fhir.jpa.search.ResourceSearchUrlSvc;
|
import ca.uhn.fhir.jpa.search.ResourceSearchUrlSvc;
|
||||||
|
@ -227,7 +226,8 @@ class BaseHapiFhirResourceDaoTest {
|
||||||
RequestPartitionId partitionId = Mockito.mock(RequestPartitionId.class);
|
RequestPartitionId partitionId = Mockito.mock(RequestPartitionId.class);
|
||||||
JpaPid jpaPid = JpaPid.fromIdAndVersion(123L, 1L);
|
JpaPid jpaPid = JpaPid.fromIdAndVersion(123L, 1L);
|
||||||
ResourceTable entity = new ResourceTable();
|
ResourceTable entity = new ResourceTable();
|
||||||
entity.setForcedId(new ForcedId());
|
entity.setId(123L);
|
||||||
|
entity.setFhirId("456");
|
||||||
|
|
||||||
// mock
|
// mock
|
||||||
when(myRequestPartitionHelperSvc.determineReadPartitionForRequestForRead(
|
when(myRequestPartitionHelperSvc.determineReadPartitionForRequestForRead(
|
||||||
|
|
|
@ -7,7 +7,6 @@ import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.jpa.entity.PartitionEntity;
|
import ca.uhn.fhir.jpa.entity.PartitionEntity;
|
||||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||||
import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc;
|
import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc;
|
||||||
|
@ -30,6 +29,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.model.entity.ResourceTable.IDX_RES_TYPE_FHIR_ID;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
@ -61,13 +61,6 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
mySrdInterceptorService.unregisterInterceptorsIf(t -> t instanceof MyReadWriteInterceptor);
|
mySrdInterceptorService.unregisterInterceptorsIf(t -> t instanceof MyReadWriteInterceptor);
|
||||||
|
|
||||||
if (myHaveDroppedForcedIdUniqueConstraint) {
|
|
||||||
runInTransaction(() -> {
|
|
||||||
myEntityManager.createNativeQuery("delete from HFJ_FORCED_ID").executeUpdate();
|
|
||||||
myEntityManager.createNativeQuery("alter table HFJ_FORCED_ID add constraint IDX_FORCEDID_TYPE_FID unique (RESOURCE_TYPE, FORCED_ID)");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
myStorageSettings.setIndexMissingFields(new JpaStorageSettings().getIndexMissingFields());
|
myStorageSettings.setIndexMissingFields(new JpaStorageSettings().getIndexMissingFields());
|
||||||
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(new JpaStorageSettings().isAutoCreatePlaceholderReferenceTargets());
|
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(new JpaStorageSettings().isAutoCreatePlaceholderReferenceTargets());
|
||||||
myStorageSettings.setMassIngestionMode(new JpaStorageSettings().isMassIngestionMode());
|
myStorageSettings.setMassIngestionMode(new JpaStorageSettings().isMassIngestionMode());
|
||||||
|
@ -106,6 +99,18 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPurgeDatabase() {
|
||||||
|
super.afterPurgeDatabase();
|
||||||
|
|
||||||
|
if (myHaveDroppedForcedIdUniqueConstraint) {
|
||||||
|
runInTransaction(() -> {
|
||||||
|
myEntityManager.createNativeQuery("delete from HFJ_RESOURCE").executeUpdate();
|
||||||
|
myEntityManager.createNativeQuery("alter table " + ResourceTable.HFJ_RESOURCE +
|
||||||
|
" add constraint " + IDX_RES_TYPE_FHIR_ID + " unique (RES_TYPE, FHIR_ID)").executeUpdate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
protected void createUniqueCompositeSp() {
|
protected void createUniqueCompositeSp() {
|
||||||
addCreateDefaultPartition();
|
addCreateDefaultPartition();
|
||||||
addReadDefaultPartition(); // one for search param validation
|
addReadDefaultPartition(); // one for search param validation
|
||||||
|
@ -137,8 +142,7 @@ public abstract class BasePartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
protected void dropForcedIdUniqueConstraint() {
|
protected void dropForcedIdUniqueConstraint() {
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
myEntityManager.createNativeQuery("alter table " + ForcedId.HFJ_FORCED_ID + " drop constraint " + ForcedId.IDX_FORCEDID_TYPE_FID).executeUpdate();
|
myEntityManager.createNativeQuery("alter table " + ResourceTable.HFJ_RESOURCE + " drop constraint " + IDX_RES_TYPE_FHIR_ID).executeUpdate();
|
||||||
myEntityManager.createNativeQuery("alter table " + ResourceTable.HFJ_RESOURCE + " drop constraint " + ResourceTable.IDX_RES_TYPE_FHIR_ID).executeUpdate();
|
|
||||||
});
|
});
|
||||||
myHaveDroppedForcedIdUniqueConstraint = true;
|
myHaveDroppedForcedIdUniqueConstraint = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum;
|
import ca.uhn.fhir.jpa.entity.TermValueSetPreExpansionStatusEnum;
|
||||||
import ca.uhn.fhir.jpa.interceptor.ForceOffsetSearchModeInterceptor;
|
import ca.uhn.fhir.jpa.interceptor.ForceOffsetSearchModeInterceptor;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||||
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
|
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
|
||||||
|
@ -47,6 +46,7 @@ import ca.uhn.fhir.test.utilities.ProxyUtil;
|
||||||
import ca.uhn.fhir.test.utilities.server.HashMapResourceProviderExtension;
|
import ca.uhn.fhir.test.utilities.server.HashMapResourceProviderExtension;
|
||||||
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
|
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
|
||||||
import ca.uhn.fhir.util.BundleBuilder;
|
import ca.uhn.fhir.util.BundleBuilder;
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
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.instance.model.api.IIdType;
|
||||||
|
@ -90,7 +90,6 @@ import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.util.comparator.ComparableComparator;
|
import org.springframework.util.comparator.ComparableComparator;
|
||||||
|
|
||||||
import jakarta.annotation.Nonnull;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -150,7 +149,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISubscriptionTriggeringSvc mySubscriptionTriggeringSvc;
|
private ISubscriptionTriggeringSvc mySubscriptionTriggeringSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ResourceModifiedSubmitterSvc myResourceModifiedSubmitterSvc;;
|
private ResourceModifiedSubmitterSvc myResourceModifiedSubmitterSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ReindexStep myReindexStep;
|
private ReindexStep myReindexStep;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -221,7 +220,6 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
|
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), not(empty())));
|
|
||||||
|
|
||||||
logAllResources();
|
logAllResources();
|
||||||
|
|
||||||
|
@ -242,11 +240,10 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
assertEquals(47, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(47, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(85, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(80, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +325,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
Group group = createGroup(patientList.subList(0, initialPatientsCount));
|
Group group = createGroup(patientList.subList(0, initialPatientsCount));
|
||||||
|
|
||||||
assertQueryCount(31, 0, 4, 0);
|
assertQueryCount(31, 0, 3, 0);
|
||||||
|
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
group = updateGroup(group, patientList.subList(initialPatientsCount, allPatientsCount));
|
group = updateGroup(group, patientList.subList(initialPatientsCount, allPatientsCount));
|
||||||
|
@ -350,7 +347,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
Group group = createGroup(patientList);
|
Group group = createGroup(patientList);
|
||||||
|
|
||||||
assertQueryCount(31, 0, 4, 0);
|
assertQueryCount(31, 0, 3, 0);
|
||||||
|
|
||||||
// Make a change to the group, but don't touch any references in it
|
// Make a change to the group, but don't touch any references in it
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
|
@ -672,7 +669,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
||||||
|
|
||||||
|
@ -705,24 +702,20 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
||||||
|
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
List<ForcedId> allForcedIds = myForcedIdDao.findAll();
|
|
||||||
for (ForcedId next : allForcedIds) {
|
|
||||||
assertNotNull(next.getResourceId());
|
|
||||||
assertNotNull(next.getForcedId());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ResourceTable> resources = myResourceTableDao.findAll();
|
List<ResourceTable> resources = myResourceTableDao.findAll();
|
||||||
String versions = "Resource Versions:\n * " + resources.stream().map(t -> "Resource " + t.getIdDt() + " has version: " + t.getVersion()).collect(Collectors.joining("\n * "));
|
String versions = "Resource Versions:\n * " + resources.stream().map(t -> "Resource " + t.getIdDt() + " has version: " + t.getVersion()).collect(Collectors.joining("\n * "));
|
||||||
|
|
||||||
for (ResourceTable next : resources) {
|
for (ResourceTable next : resources) {
|
||||||
assertEquals(1, next.getVersion(), versions);
|
assertEquals(1, next.getVersion(), versions);
|
||||||
|
assertNotNull(next.getResourceId());
|
||||||
|
assertNotNull(next.getFhirId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -771,22 +764,18 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
||||||
|
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
List<ForcedId> allForcedIds = myForcedIdDao.findAll();
|
|
||||||
for (ForcedId next : allForcedIds) {
|
|
||||||
assertNotNull(next.getResourceId());
|
|
||||||
assertNotNull(next.getForcedId());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ResourceTable> resources = myResourceTableDao.findAll();
|
List<ResourceTable> resources = myResourceTableDao.findAll();
|
||||||
String versions = "Resource Versions:\n * " + resources.stream().map(t -> "Resource " + t.getIdDt() + " has version: " + t.getVersion()).collect(Collectors.joining("\n * "));
|
String versions = "Resource Versions:\n * " + resources.stream().map(t -> "Resource " + t.getIdDt() + " has version: " + t.getVersion()).collect(Collectors.joining("\n * "));
|
||||||
|
|
||||||
for (ResourceTable next : resources) {
|
for (ResourceTable next : resources) {
|
||||||
assertEquals(1, next.getVersion(), versions);
|
assertEquals(1, next.getVersion(), versions);
|
||||||
|
assertNotNull(next.getResourceId());
|
||||||
|
assertNotNull(next.getFhirId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -819,7 +808,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getUpdateQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(4, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
assertEquals(3, myCaptureQueriesListener.getInsertQueriesForCurrentThread().size());
|
||||||
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
myCaptureQueriesListener.logDeleteQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
assertEquals(0, myCaptureQueriesListener.getDeleteQueriesForCurrentThread().size());
|
||||||
}
|
}
|
||||||
|
@ -838,7 +827,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
DeleteMethodOutcome outcome = myPatientDao.deleteByUrl("Patient?active=true", new SystemRequestDetails());
|
DeleteMethodOutcome outcome = myPatientDao.deleteByUrl("Patient?active=true", new SystemRequestDetails());
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
assertEquals(13, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(12, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(10, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(10, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(10, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(10, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(30, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(30, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
@ -856,7 +845,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
withFamily("Family" + i),
|
withFamily("Family" + i),
|
||||||
withTag("http://foo", "blah"));
|
withTag("http://foo", "blah"));
|
||||||
}
|
}
|
||||||
List<TypedPidJson> pids = runInTransaction(() -> myForcedIdDao
|
List<TypedPidJson> pids = runInTransaction(() -> myResourceTableDao
|
||||||
.findAll()
|
.findAll()
|
||||||
.stream()
|
.stream()
|
||||||
.map(t -> new TypedPidJson(t.getResourceType(), Long.toString(t.getResourceId())))
|
.map(t -> new TypedPidJson(t.getResourceType(), Long.toString(t.getResourceId())))
|
||||||
|
@ -874,7 +863,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(29, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(28, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
assertEquals(10, outcome.getRecordsProcessed());
|
assertEquals(10, outcome.getRecordsProcessed());
|
||||||
runInTransaction(()-> assertEquals(0, myResourceTableDao.count()));
|
runInTransaction(()-> assertEquals(0, myResourceTableDao.count()));
|
||||||
}
|
}
|
||||||
|
@ -1037,10 +1026,10 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@CsvSource({
|
@CsvSource({
|
||||||
// OptimisticLock OptimizeMode ExpectedSelect ExpectedUpdate
|
// OptimisticLock OptimizeMode ExpectedSelect ExpectedUpdate
|
||||||
" false, CURRENT_VERSION, 2, 0",
|
" false, CURRENT_VERSION, 1, 0",
|
||||||
" true, CURRENT_VERSION, 12, 0",
|
" true, CURRENT_VERSION, 11, 0",
|
||||||
" false, ALL_VERSIONS, 12, 0",
|
" false, ALL_VERSIONS, 11, 0",
|
||||||
" true, ALL_VERSIONS, 22, 0",
|
" true, ALL_VERSIONS, 21, 0",
|
||||||
})
|
})
|
||||||
public void testReindexJob_OptimizeStorage(boolean theOptimisticLock, ReindexParameters.OptimizeStorageModeEnum theOptimizeStorageModeEnum, int theExpectedSelectCount, int theExpectedUpdateCount) {
|
public void testReindexJob_OptimizeStorage(boolean theOptimisticLock, ReindexParameters.OptimizeStorageModeEnum theOptimizeStorageModeEnum, int theExpectedSelectCount, int theExpectedUpdateCount) {
|
||||||
// Setup
|
// Setup
|
||||||
|
@ -1839,7 +1828,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(1, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(1, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(21, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(18, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
||||||
|
@ -1852,7 +1841,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(5, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(4, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(2, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(2, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
|
@ -1868,7 +1857,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(5, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(4, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(2, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(2, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
|
@ -1925,7 +1914,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
// Search for IDs and Search for tag definition
|
// Search for IDs and Search for tag definition
|
||||||
assertEquals(3, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(3, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(29, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(26, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
||||||
|
@ -1938,7 +1927,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(9, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(7, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(7, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(7, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
|
@ -1954,7 +1943,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(7, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(5, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
|
@ -2250,7 +2239,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(9, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(8, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
|
@ -2267,7 +2256,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(8, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(7, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
|
@ -2282,7 +2271,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
assertEquals(6, myCaptureQueriesListener.countSelectQueries());
|
assertEquals(5, myCaptureQueriesListener.countSelectQueries());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
|
@ -2453,7 +2442,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(7, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(6, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
@ -3000,7 +2989,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
|
|
||||||
assertEquals(17, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(17, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(6607, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(6189, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(418, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(418, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
assertEquals(2, myCaptureQueriesListener.countCommits());
|
assertEquals(2, myCaptureQueriesListener.countCommits());
|
||||||
|
@ -3368,7 +3357,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
|
mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
|
||||||
assertEquals(2, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(2, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(30, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(29, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
|
||||||
|
@ -3376,7 +3365,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
|
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
Bundle outcome = mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
|
Bundle outcome = mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
|
||||||
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(6, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(6, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
|
@ -3399,7 +3388,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
|
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
outcome = mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
|
outcome = mySystemDao.transaction(new SystemRequestDetails(), supplier.get());
|
||||||
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logInsertQueries();
|
myCaptureQueriesListener.logInsertQueries();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(6, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(6, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
|
@ -3451,7 +3440,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
mySystemDao.transaction(new SystemRequestDetails(), loadResourceFromClasspath(Bundle.class, "r4/transaction-perf-bundle.json"));
|
mySystemDao.transaction(new SystemRequestDetails(), loadResourceFromClasspath(Bundle.class, "r4/transaction-perf-bundle.json"));
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(2, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(2, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(125, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(120, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(1, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
@ -3460,7 +3449,7 @@ public class FhirResourceDaoR4QueryCountTest extends BaseResourceProviderR4Test
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
mySystemDao.transaction(new SystemRequestDetails(), loadResourceFromClasspath(Bundle.class, "r4/transaction-perf-bundle-smallchanges.json"));
|
mySystemDao.transaction(new SystemRequestDetails(), loadResourceFromClasspath(Bundle.class, "r4/transaction-perf-bundle-smallchanges.json"));
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(2, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(2, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(5, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(5, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
|
|
@ -31,9 +31,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.test.utilities.ProxyUtil;
|
import ca.uhn.fhir.test.utilities.ProxyUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.checkerframework.checker.units.qual.A;
|
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.BodyStructure;
|
import org.hl7.fhir.r4.model.BodyStructure;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||||
|
@ -1238,12 +1236,11 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
|
||||||
myPatientDao.update(p).getId().toUnqualifiedVersionless();
|
myPatientDao.update(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(1, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(3, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
assertEquals(1, myResourceTableDao.count());
|
assertEquals(1, myResourceTableDao.count());
|
||||||
assertEquals(1, myResourceHistoryTableDao.count());
|
assertEquals(1, myResourceHistoryTableDao.count());
|
||||||
assertEquals(1, myForcedIdDao.count());
|
|
||||||
assertEquals(1, myResourceIndexedSearchParamTokenDao.count());
|
assertEquals(1, myResourceIndexedSearchParamTokenDao.count());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1264,7 +1261,6 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
assertEquals(1, myResourceTableDao.count());
|
assertEquals(1, myResourceTableDao.count());
|
||||||
assertEquals(2, myResourceHistoryTableDao.count());
|
assertEquals(2, myResourceHistoryTableDao.count());
|
||||||
assertEquals(1, myForcedIdDao.count());
|
|
||||||
assertEquals(1, myResourceIndexedSearchParamTokenDao.count());
|
assertEquals(1, myResourceIndexedSearchParamTokenDao.count());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
|
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
|
import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTag;
|
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTag;
|
||||||
|
@ -589,13 +588,13 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
myPatientDao.update(p, mySrd);
|
myPatientDao.update(p, mySrd);
|
||||||
|
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
// HFJ_FORCED_ID
|
ResourceTable orgResourceTable = myResourceTableDao.findByTypeAndFhirId("Organization", "org").orElseThrow(IllegalArgumentException::new);
|
||||||
List<ForcedId> forcedIds = myForcedIdDao.findAll();
|
assertEquals(myPartitionId, orgResourceTable.getPartitionId().getPartitionId().intValue());
|
||||||
assertEquals(2, forcedIds.size());
|
assertLocalDateFromDbMatches(myPartitionDate, orgResourceTable.getPartitionId().getPartitionDate());
|
||||||
assertEquals(myPartitionId, forcedIds.get(0).getPartitionId().getPartitionId().intValue());
|
|
||||||
assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(0).getPartitionId().getPartitionDate());
|
ResourceTable patientResourceTable = myResourceTableDao.findByTypeAndFhirId("Patient", "pat").orElseThrow(IllegalArgumentException::new);
|
||||||
assertEquals(myPartitionId, forcedIds.get(1).getPartitionId().getPartitionId().intValue());
|
assertEquals(myPartitionId, patientResourceTable.getPartitionId().getPartitionId().intValue());
|
||||||
assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(1).getPartitionId().getPartitionDate());
|
assertLocalDateFromDbMatches(myPartitionDate, patientResourceTable.getPartitionId().getPartitionDate());
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -615,11 +614,11 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
myPatientDao.update(p, mySrd);
|
myPatientDao.update(p, mySrd);
|
||||||
|
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
// HFJ_FORCED_ID
|
ResourceTable orgResourceTable = myResourceTableDao.findByTypeAndFhirId("Organization", "org").orElseThrow(IllegalArgumentException::new);
|
||||||
List<ForcedId> forcedIds = myForcedIdDao.findAll();
|
assertNull(orgResourceTable.getPartitionId());
|
||||||
assertEquals(2, forcedIds.size());
|
|
||||||
assertEquals(null, forcedIds.get(0).getPartitionId());
|
ResourceTable patientResourceTable = myResourceTableDao.findByTypeAndFhirId("Patient", "pat").orElseThrow(IllegalArgumentException::new);
|
||||||
assertEquals(null, forcedIds.get(1).getPartitionId());
|
assertNull(patientResourceTable.getPartitionId());
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -639,13 +638,13 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
myPatientDao.update(p, mySrd);
|
myPatientDao.update(p, mySrd);
|
||||||
|
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
// HFJ_FORCED_ID
|
ResourceTable orgResourceTable = myResourceTableDao.findByTypeAndFhirId("Organization", "org").orElseThrow(IllegalArgumentException::new);
|
||||||
List<ForcedId> forcedIds = myForcedIdDao.findAll();
|
assertNull(orgResourceTable.getPartitionId().getPartitionId());
|
||||||
assertEquals(2, forcedIds.size());
|
assertLocalDateFromDbMatches(myPartitionDate, orgResourceTable.getPartitionId().getPartitionDate());
|
||||||
assertEquals(null, forcedIds.get(0).getPartitionId().getPartitionId());
|
|
||||||
assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(0).getPartitionId().getPartitionDate());
|
ResourceTable patientResourceTable = myResourceTableDao.findByTypeAndFhirId("Patient", "pat").orElseThrow(IllegalArgumentException::new);
|
||||||
assertEquals(null, forcedIds.get(1).getPartitionId().getPartitionId());
|
assertNull(patientResourceTable.getPartitionId().getPartitionId());
|
||||||
assertLocalDateFromDbMatches(myPartitionDate, forcedIds.get(1).getPartitionId().getPartitionDate());
|
assertLocalDateFromDbMatches(myPartitionDate, patientResourceTable.getPartitionId().getPartitionDate());
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -876,8 +875,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
ourLog.info("Search SQL:\n{}", searchSql);
|
ourLog.info("Search SQL:\n{}", searchSql);
|
||||||
|
|
||||||
// Only the read columns should be used, no criteria use partition
|
// Only the read columns should be used, no criteria use partition
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
addReadAllPartitions();
|
addReadAllPartitions();
|
||||||
|
@ -888,8 +887,8 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
ourLog.info("Search SQL:\n{}", searchSql);
|
ourLog.info("Search SQL:\n{}", searchSql);
|
||||||
|
|
||||||
// Only the read columns should be used, no criteria use partition
|
// Only the read columns should be used, no criteria use partition
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,7 +909,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
ourLog.info("Search SQL:\n{}", searchSql);
|
ourLog.info("Search SQL:\n{}", searchSql);
|
||||||
|
|
||||||
// Only the read columns should be used, no criteria use partition
|
// Only the read columns should be used, no criteria use partition
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
||||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID='1'"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID='1'"), searchSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +953,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
|
|
||||||
// Only the read columns should be used, but no selectors on partition ID
|
// Only the read columns should be used, but no selectors on partition ID
|
||||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
||||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID in ("), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID in ("), searchSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,7 +966,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
|
|
||||||
// Only the read columns should be used, but no selectors on partition ID
|
// Only the read columns should be used, but no selectors on partition ID
|
||||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
||||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"), searchSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1008,7 +1007,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
|
|
||||||
// Only the read columns should be used, but no selectors on partition ID
|
// Only the read columns should be used, but no selectors on partition ID
|
||||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
||||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID in ("), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID in ("), searchSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1022,7 +1021,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
|
|
||||||
// Only the read columns should be used, but no selectors on partition ID
|
// Only the read columns should be used, but no selectors on partition ID
|
||||||
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
String searchSql = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, true);
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"), searchSql);
|
||||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"), searchSql);
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"), searchSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,7 +1063,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
ourLog.info("Search SQL:\n{}", searchSql);
|
ourLog.info("Search SQL:\n{}", searchSql);
|
||||||
|
|
||||||
// Only the read columns should be used, no criteria use partition
|
// Only the read columns should be used, no criteria use partition
|
||||||
assertEquals(2, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID,"));
|
||||||
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"));
|
assertEquals(1, StringUtils.countMatches(searchSql, "PARTITION_ID is null"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2843,7 +2842,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(9, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
|
@ -2860,7 +2859,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(7, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
|
@ -2875,7 +2874,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
outcome = mySystemDao.transaction(mySrd, input.get());
|
outcome = mySystemDao.transaction(mySrd, input.get());
|
||||||
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
ourLog.debug("Resp: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(6, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(5, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
myCaptureQueriesListener.logInsertQueriesForCurrentThread();
|
||||||
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(4, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
myCaptureQueriesListener.logUpdateQueriesForCurrentThread();
|
||||||
|
@ -2899,7 +2898,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
|
|
||||||
assertEquals(18, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(18, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(6607, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(6189, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(418, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(418, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
assertEquals(2, myCaptureQueriesListener.countCommits());
|
assertEquals(2, myCaptureQueriesListener.countCommits());
|
||||||
|
@ -2925,7 +2924,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
|
||||||
output = mySystemDao.transaction(requestDetails, input);
|
output = mySystemDao.transaction(requestDetails, input);
|
||||||
myCaptureQueriesListener.logSelectQueries();
|
myCaptureQueriesListener.logSelectQueries();
|
||||||
|
|
||||||
assertEquals(29, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(26, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
|
|
@ -27,8 +27,6 @@ import ca.uhn.fhir.util.MultimapCollector;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
@ -47,7 +45,6 @@ import org.junit.jupiter.api.AfterEach;
|
||||||
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.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -64,8 +61,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
|
|
||||||
public class PatientIdPartitionInterceptorTest extends BaseResourceProviderR4Test {
|
public class PatientIdPartitionInterceptorTest extends BaseResourceProviderR4Test {
|
||||||
public static final int ALTERNATE_DEFAULT_ID = -1;
|
public static final int ALTERNATE_DEFAULT_ID = -1;
|
||||||
|
@ -355,7 +350,6 @@ public class PatientIdPartitionInterceptorTest extends BaseResourceProviderR4Tes
|
||||||
org.setName("name 2");
|
org.setName("name 2");
|
||||||
|
|
||||||
logAllResources();
|
logAllResources();
|
||||||
logAllForcedIds();
|
|
||||||
|
|
||||||
myOrganizationDao.update(org);
|
myOrganizationDao.update(org);
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,15 @@ import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||||
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
|
||||||
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
|
||||||
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
|
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaSearchFirstPageBundleProvider;
|
import ca.uhn.fhir.jpa.search.PersistedJpaSearchFirstPageBundleProvider;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||||
|
@ -379,7 +378,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), not(empty())));
|
|
||||||
|
|
||||||
myPatientDao.expunge(new ExpungeOptions()
|
myPatientDao.expunge(new ExpungeOptions()
|
||||||
.setExpungeDeletedResources(true)
|
.setExpungeDeletedResources(true)
|
||||||
|
@ -387,7 +385,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +406,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), not(empty())));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), not(empty())));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), not(empty())));
|
|
||||||
|
|
||||||
// Test
|
// Test
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
|
@ -421,11 +417,10 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(8, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(9, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(8, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,7 +744,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
.setExpungeOldVersions(true), null);
|
.setExpungeOldVersions(true), null);
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
|
|
||||||
|
|
||||||
// Create again with the same forced ID
|
// Create again with the same forced ID
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -788,7 +782,6 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
.setExpungeOldVersions(true), null);
|
.setExpungeOldVersions(true), null);
|
||||||
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
|
||||||
runInTransaction(() -> assertThat(myForcedIdDao.findAll(), empty()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,6 +1054,5 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
assertThat(myTermConceptDao.findAll(), empty());
|
assertThat(myTermConceptDao.findAll(), empty());
|
||||||
assertThat(myResourceTableDao.findAll(), empty());
|
assertThat(myResourceTableDao.findAll(), empty());
|
||||||
assertThat(myResourceHistoryTableDao.findAll(), empty());
|
assertThat(myResourceHistoryTableDao.findAll(), empty());
|
||||||
assertThat(myForcedIdDao.findAll(), empty());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package ca.uhn.fhir.jpa.provider.r4;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
|
import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.gclient.TokenClientParam;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
public class ResourceProviderLanguageParamR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamEnabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(true);
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.setLanguage("en");
|
||||||
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient pat2 = new Patient();
|
||||||
|
pat.setLanguage("fr");
|
||||||
|
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
List<String> foundResources;
|
||||||
|
Bundle result;
|
||||||
|
|
||||||
|
result = myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
foundResources = toUnqualifiedVersionlessIdValues(result);
|
||||||
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamDisabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
|
||||||
|
myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
assertThat(exception.getMessage(), containsString(Msg.code(1223)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -307,6 +307,86 @@ public class ResourceProviderR4ConceptMapTest extends BaseResourceProviderR4Test
|
||||||
assertFalse(hasParameterByName(respParams, "match"));
|
assertFalse(hasParameterByName(respParams, "match"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTranslateByCodeSystemsAndSourceCodeMappedToCodelessTarget() {
|
||||||
|
// ensure that the current behaviour when a target does not have a code is preserved, and no matches returned
|
||||||
|
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
|
||||||
|
|
||||||
|
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||||
|
|
||||||
|
Parameters inParams = new Parameters();
|
||||||
|
inParams.addParameter().setName("system").setValue(new UriType(CS_URL_4));
|
||||||
|
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
|
||||||
|
inParams.addParameter().setName("code").setValue(new CodeType("89012"));
|
||||||
|
|
||||||
|
ourLog.debug("Request Parameters:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
|
||||||
|
|
||||||
|
Parameters respParams = myClient
|
||||||
|
.operation()
|
||||||
|
.onType(ConceptMap.class)
|
||||||
|
.named("translate")
|
||||||
|
.withParameters(inParams)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
ourLog.debug("Response Parameters\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
|
||||||
|
|
||||||
|
ParametersParameterComponent param = getParameterByName(respParams, "result");
|
||||||
|
assertFalse(((BooleanType) param.getValue()).booleanValue());
|
||||||
|
|
||||||
|
param = getParameterByName(respParams, "message");
|
||||||
|
assertEquals("No Matches found", ((StringType) param.getValue()).getValueAsString());
|
||||||
|
|
||||||
|
assertFalse(hasParameterByName(respParams, "match"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTranslateByCodeSystemsAndSourceCodeWithEquivalenceUnmatched() {
|
||||||
|
// the equivalence code 'unmatched' is an exception - it does not normally have a target code,
|
||||||
|
// so it will be included in the collection of matches even if there is no code present
|
||||||
|
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId, mySrd);
|
||||||
|
|
||||||
|
ourLog.debug("ConceptMap:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||||
|
|
||||||
|
Parameters inParams = new Parameters();
|
||||||
|
inParams.addParameter().setName("system").setValue(new UriType(CS_URL_4));
|
||||||
|
inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
|
||||||
|
inParams.addParameter().setName("code").setValue(new CodeType("89123"));
|
||||||
|
|
||||||
|
ourLog.debug("Request Parameters:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
|
||||||
|
|
||||||
|
Parameters respParams = myClient
|
||||||
|
.operation()
|
||||||
|
.onType(ConceptMap.class)
|
||||||
|
.named("translate")
|
||||||
|
.withParameters(inParams)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
ourLog.debug("Response Parameters\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
|
||||||
|
|
||||||
|
ParametersParameterComponent param = getParameterByName(respParams, "result");
|
||||||
|
assertFalse(((BooleanType) param.getValue()).booleanValue());
|
||||||
|
|
||||||
|
param = getParameterByName(respParams, "message");
|
||||||
|
assertEquals("Only negative matches found", ((StringType) param.getValue()).getValueAsString());
|
||||||
|
|
||||||
|
assertEquals(1, getNumberOfParametersByName(respParams, "match"));
|
||||||
|
|
||||||
|
param = getParameterByName(respParams, "match");
|
||||||
|
assertEquals(3, param.getPart().size());
|
||||||
|
ParametersParameterComponent part = getPartByName(param, "equivalence");
|
||||||
|
assertEquals("unmatched", ((CodeType) part.getValue()).getCode());
|
||||||
|
part = getPartByName(param, "concept");
|
||||||
|
Coding coding = (Coding) part.getValue();
|
||||||
|
assertNull(coding.getCode());
|
||||||
|
assertNull(coding.getDisplay());
|
||||||
|
assertFalse(coding.getUserSelected());
|
||||||
|
assertEquals(CS_URL_3, coding.getSystem());
|
||||||
|
assertEquals("Version 1", coding.getVersion());
|
||||||
|
part = getPartByName(param, "source");
|
||||||
|
assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTranslateUsingPredicatesWithCodeOnly() {
|
public void testTranslateUsingPredicatesWithCodeOnly() {
|
||||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||||
|
|
|
@ -346,7 +346,7 @@ public class ServerCapabilityStatementProviderJpaR4Test extends BaseResourceProv
|
||||||
CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute();
|
CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute();
|
||||||
for (CapabilityStatement.CapabilityStatementRestResourceComponent nextResource : cs.getRestFirstRep().getResource()) {
|
for (CapabilityStatement.CapabilityStatementRestResourceComponent nextResource : cs.getRestFirstRep().getResource()) {
|
||||||
for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSp : nextResource.getSearchParam()) {
|
for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSp : nextResource.getSearchParam()) {
|
||||||
if (nextSp.getName().equals("_has") || nextSp.getName().equals("_list")) {
|
if (nextSp.getName().equals("_has") || nextSp.getName().equals("_list") || nextSp.getName().equals("_language")) {
|
||||||
if (nextSp.getDefinition() == null) {
|
if (nextSp.getDefinition() == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(2, outcome.getRecordsProcessed());
|
assertEquals(2, outcome.getRecordsProcessed());
|
||||||
assertEquals(6, myCaptureQueriesListener.logSelectQueries().size());
|
assertEquals(5, myCaptureQueriesListener.logSelectQueries().size());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
|
||||||
myCaptureQueriesListener.logUpdateQueries();
|
myCaptureQueriesListener.logUpdateQueries();
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
||||||
|
@ -95,7 +95,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(2, outcome.getRecordsProcessed());
|
assertEquals(2, outcome.getRecordsProcessed());
|
||||||
assertEquals(8, myCaptureQueriesListener.logSelectQueries().size());
|
assertEquals(7, myCaptureQueriesListener.logSelectQueries().size());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
||||||
|
@ -128,7 +128,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(2, outcome.getRecordsProcessed());
|
assertEquals(2, outcome.getRecordsProcessed());
|
||||||
assertEquals(6, myCaptureQueriesListener.logSelectQueries().size());
|
assertEquals(5, myCaptureQueriesListener.logSelectQueries().size());
|
||||||
// name, family, phonetic, deceased, active
|
// name, family, phonetic, deceased, active
|
||||||
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueries());
|
||||||
|
@ -196,7 +196,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(2, outcome.getRecordsProcessed());
|
assertEquals(2, outcome.getRecordsProcessed());
|
||||||
assertEquals(10, myCaptureQueriesListener.logSelectQueries().size());
|
assertEquals(9, myCaptureQueriesListener.logSelectQueries().size());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueries());
|
||||||
assertEquals(4, myCaptureQueriesListener.countUpdateQueries());
|
assertEquals(4, myCaptureQueriesListener.countUpdateQueries());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
||||||
|
@ -241,7 +241,7 @@ public class ReindexStepTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(4, outcome.getRecordsProcessed());
|
assertEquals(4, outcome.getRecordsProcessed());
|
||||||
assertEquals(9, myCaptureQueriesListener.logSelectQueries().size());
|
assertEquals(8, myCaptureQueriesListener.logSelectQueries().size());
|
||||||
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
|
assertEquals(5, myCaptureQueriesListener.countInsertQueries());
|
||||||
assertEquals(2, myCaptureQueriesListener.countUpdateQueries());
|
assertEquals(2, myCaptureQueriesListener.countUpdateQueries());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueries());
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -18,7 +18,6 @@ import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
|
||||||
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
|
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
|
||||||
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
|
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
|
||||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboStringUniqueDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboStringUniqueDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamDateDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamDateDao;
|
||||||
|
@ -64,6 +63,7 @@ import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
||||||
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
||||||
import ca.uhn.fhir.validation.FhirValidator;
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
import ca.uhn.fhir.validation.ValidationResult;
|
import ca.uhn.fhir.validation.ValidationResult;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
||||||
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.instance.model.api.IIdType;
|
||||||
|
@ -124,7 +124,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -280,8 +279,6 @@ public abstract class BaseJpaR4BTest extends BaseJpaTest implements ITestDataBui
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IResourceHistoryTableDao myResourceHistoryTableDao;
|
protected IResourceHistoryTableDao myResourceHistoryTableDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IForcedIdDao myForcedIdDao;
|
|
||||||
@Autowired
|
|
||||||
@Qualifier("myCoverageDaoR4B")
|
@Qualifier("myCoverageDaoR4B")
|
||||||
protected IFhirResourceDao<Coverage> myCoverageDao;
|
protected IFhirResourceDao<Coverage> myCoverageDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package ca.uhn.fhir.jpa.provider.r4b;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.gclient.TokenClientParam;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.r4b.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4b.model.Patient;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
public class ResourceProviderLanguageParamR4BTest extends BaseResourceProviderR4BTest {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamEnabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(true);
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.setLanguage("en");
|
||||||
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient pat2 = new Patient();
|
||||||
|
pat.setLanguage("fr");
|
||||||
|
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
List<String> foundResources;
|
||||||
|
Bundle result;
|
||||||
|
|
||||||
|
result = myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
foundResources = toUnqualifiedVersionlessIdValues(result);
|
||||||
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamDisabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
|
||||||
|
myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
assertThat(exception.getMessage(), containsString(Msg.code(1223)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -19,7 +19,6 @@ import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
|
||||||
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
|
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
|
||||||
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
|
import ca.uhn.fhir.jpa.bulk.export.api.IBulkDataExportJobSchedulingHelper;
|
||||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTagDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTagDao;
|
||||||
|
@ -72,6 +71,7 @@ import ca.uhn.fhir.rest.server.BasePagingProvider;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
|
||||||
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
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.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r5.model.AllergyIntolerance;
|
import org.hl7.fhir.r5.model.AllergyIntolerance;
|
||||||
|
@ -134,7 +134,6 @@ import org.springframework.test.util.AopTestUtils;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -303,8 +302,6 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IResourceHistoryProvenanceDao myResourceHistoryProvenanceDao;
|
protected IResourceHistoryProvenanceDao myResourceHistoryProvenanceDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IForcedIdDao myForcedIdDao;
|
|
||||||
@Autowired
|
|
||||||
@Qualifier("myCoverageDaoR5")
|
@Qualifier("myCoverageDaoR5")
|
||||||
protected IFhirResourceDao<Coverage> myCoverageDao;
|
protected IFhirResourceDao<Coverage> myCoverageDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||||
import ca.uhn.fhir.util.BundleBuilder;
|
import ca.uhn.fhir.util.BundleBuilder;
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
import org.hl7.fhir.r5.model.BooleanType;
|
import org.hl7.fhir.r5.model.BooleanType;
|
||||||
import org.hl7.fhir.r5.model.Bundle;
|
import org.hl7.fhir.r5.model.Bundle;
|
||||||
import org.hl7.fhir.r5.model.CodeType;
|
import org.hl7.fhir.r5.model.CodeType;
|
||||||
|
@ -20,7 +21,6 @@ import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.CsvSource;
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
import jakarta.annotation.Nonnull;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ import static org.apache.commons.lang3.StringUtils.countMatches;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
import static org.hamcrest.Matchers.in;
|
|
||||||
import static org.hamcrest.Matchers.matchesPattern;
|
import static org.hamcrest.Matchers.matchesPattern;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
@ -151,7 +150,7 @@ public class FhirSystemDaoTransactionR5Test extends BaseJpaR5Test {
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
|
|
||||||
assertEquals(theMatchUrlCacheEnabled ? 4 : 5, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(theMatchUrlCacheEnabled ? 3 : 4, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
@ -203,7 +202,7 @@ public class FhirSystemDaoTransactionR5Test extends BaseJpaR5Test {
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
|
|
||||||
assertEquals(theMatchUrlCacheEnabled ? 4 : 5, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(theMatchUrlCacheEnabled ? 3 : 4, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countInsertQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countUpdateQueriesForCurrentThread());
|
||||||
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
assertEquals(0, myCaptureQueriesListener.countDeleteQueriesForCurrentThread());
|
||||||
|
|
|
@ -401,7 +401,7 @@ public class UpliftedRefchainsAndChainedSortingR5Test extends BaseJpaR5Test {
|
||||||
|
|
||||||
// 1- Resolve resource forced IDs, and 2- Resolve Practitioner/PR1 reference
|
// 1- Resolve resource forced IDs, and 2- Resolve Practitioner/PR1 reference
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
assertEquals(10, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
assertEquals(9, myCaptureQueriesListener.countSelectQueriesForCurrentThread());
|
||||||
|
|
||||||
// Verify correct indexes are written
|
// Verify correct indexes are written
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ public class UpliftedRefchainsAndChainedSortingR5Test extends BaseJpaR5Test {
|
||||||
bb.addTransactionUpdateEntry(newEncounter(ENCOUNTER_E2, p2Id));
|
bb.addTransactionUpdateEntry(newEncounter(ENCOUNTER_E2, p2Id));
|
||||||
bb.addTransactionCreateEntry(newPatientP1_HomerSimpson().setId(p1Id)).conditional("identifier=http://system|200");
|
bb.addTransactionCreateEntry(newPatientP1_HomerSimpson().setId(p1Id)).conditional("identifier=http://system|200");
|
||||||
bb.addTransactionCreateEntry(newPatientP2_MargeSimpson().setId(p2Id)).conditional("identifier=http://system|300");
|
bb.addTransactionCreateEntry(newPatientP2_MargeSimpson().setId(p2Id)).conditional("identifier=http://system|300");
|
||||||
;
|
|
||||||
Bundle requestBundle = bb.getBundleTyped();
|
Bundle requestBundle = bb.getBundleTyped();
|
||||||
|
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
|
@ -496,7 +496,7 @@ public class UpliftedRefchainsAndChainedSortingR5Test extends BaseJpaR5Test {
|
||||||
bb.addTransactionUpdateEntry(newEncounter(ENCOUNTER_E2, p2Id));
|
bb.addTransactionUpdateEntry(newEncounter(ENCOUNTER_E2, p2Id));
|
||||||
bb.addTransactionCreateEntry(new Patient().addIdentifier(new Identifier().setSystem("http://system").setValue("200")).setId(p1Id)).conditional("identifier=http://system|200");
|
bb.addTransactionCreateEntry(new Patient().addIdentifier(new Identifier().setSystem("http://system").setValue("200")).setId(p1Id)).conditional("identifier=http://system|200");
|
||||||
bb.addTransactionCreateEntry(new Patient().addIdentifier(new Identifier().setSystem("http://system").setValue("300")).setId(p2Id)).conditional("identifier=http://system|300");
|
bb.addTransactionCreateEntry(new Patient().addIdentifier(new Identifier().setSystem("http://system").setValue("300")).setId(p2Id)).conditional("identifier=http://system|300");
|
||||||
;
|
|
||||||
Bundle requestBundle = bb.getBundleTyped();
|
Bundle requestBundle = bb.getBundleTyped();
|
||||||
|
|
||||||
myCaptureQueriesListener.clear();
|
myCaptureQueriesListener.clear();
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package ca.uhn.fhir.jpa.provider.r5;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.gclient.TokenClientParam;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.r5.model.Bundle;
|
||||||
|
import org.hl7.fhir.r5.model.Patient;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
public class ResourceProviderLanguageParamR5Test extends BaseResourceProviderR5Test {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamEnabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(true);
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.setLanguage("en");
|
||||||
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient pat2 = new Patient();
|
||||||
|
pat.setLanguage("fr");
|
||||||
|
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
List<String> foundResources;
|
||||||
|
Bundle result;
|
||||||
|
|
||||||
|
result = myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
foundResources = toUnqualifiedVersionlessIdValues(result);
|
||||||
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test
|
||||||
|
public void testSearchWithLanguageParamDisabled() {
|
||||||
|
myStorageSettings.setLanguageSearchParameterEnabled(new JpaStorageSettings().isLanguageSearchParameterEnabled());
|
||||||
|
mySearchParamRegistry.forceRefresh();
|
||||||
|
|
||||||
|
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
|
||||||
|
myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(new TokenClientParam(Constants.PARAM_LANGUAGE).exactly().code("en"))
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
assertThat(exception.getMessage(), containsString(Msg.code(1223)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
package ca.uhn.fhir.jpa.test;
|
package ca.uhn.fhir.jpa.test;
|
||||||
|
|
||||||
import ca.uhn.fhir.batch2.jobs.export.BulkDataExportProvider;
|
import ca.uhn.fhir.batch2.jobs.export.BulkDataExportProvider;
|
||||||
import ca.uhn.fhir.batch2.jobs.reindex.ReindexAppCtx;
|
|
||||||
import ca.uhn.fhir.batch2.model.JobInstance;
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||||
|
@ -45,7 +43,6 @@ import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||||
import ca.uhn.fhir.jpa.dao.TestDaoSearch;
|
import ca.uhn.fhir.jpa.dao.TestDaoSearch;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IBatch2JobInstanceRepository;
|
import ca.uhn.fhir.jpa.dao.data.IBatch2JobInstanceRepository;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkRepository;
|
import ca.uhn.fhir.jpa.dao.data.IBatch2WorkChunkRepository;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IMdmLinkJpaRepository;
|
import ca.uhn.fhir.jpa.dao.data.IMdmLinkJpaRepository;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IPartitionDao;
|
import ca.uhn.fhir.jpa.dao.data.IPartitionDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryProvenanceDao;
|
||||||
|
@ -116,6 +113,7 @@ import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import ca.uhn.fhir.validation.FhirValidator;
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
import ca.uhn.fhir.validation.ValidationResult;
|
import ca.uhn.fhir.validation.ValidationResult;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
|
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
|
||||||
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
@ -208,7 +206,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
import org.springframework.test.util.AopTestUtils;
|
import org.springframework.test.util.AopTestUtils;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -935,6 +932,28 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
|
||||||
target.setDisplay("Target Code 34567");
|
target.setDisplay("Target Code 34567");
|
||||||
target.setEquivalence(ConceptMapEquivalence.NARROWER);
|
target.setEquivalence(ConceptMapEquivalence.NARROWER);
|
||||||
|
|
||||||
|
group = conceptMap.addGroup();
|
||||||
|
group.setSource(CS_URL_4);
|
||||||
|
group.setSourceVersion("Version 1");
|
||||||
|
group.setTarget(CS_URL_3);
|
||||||
|
group.setTargetVersion("Version 1");
|
||||||
|
|
||||||
|
// This one should not show up in the results because it doesn't have a code
|
||||||
|
element = group.addElement();
|
||||||
|
element.setCode("89012");
|
||||||
|
element.setDisplay("Source Code 89012");
|
||||||
|
|
||||||
|
target = element.addTarget();
|
||||||
|
target.setEquivalence(ConceptMapEquivalence.DISJOINT);
|
||||||
|
|
||||||
|
// This one should show up in the results because unmatched targets are allowed to be codeless
|
||||||
|
element = group.addElement();
|
||||||
|
element.setCode("89123");
|
||||||
|
element.setDisplay("Source Code 89123");
|
||||||
|
|
||||||
|
target = element.addTarget();
|
||||||
|
target.setEquivalence(ConceptMapEquivalence.UNMATCHED);
|
||||||
|
|
||||||
return conceptMap;
|
return conceptMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import ca.uhn.fhir.jpa.config.JpaConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||||
import ca.uhn.fhir.jpa.dao.JpaPersistedResourceValidationSupport;
|
import ca.uhn.fhir.jpa.dao.JpaPersistedResourceValidationSupport;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboTokensNonUniqueDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboTokensNonUniqueDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamCoordsDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamCoordsDao;
|
||||||
|
@ -61,7 +60,6 @@ import ca.uhn.fhir.jpa.entity.TermConceptProperty;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
|
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
|
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboTokenNonUnique;
|
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedComboTokenNonUnique;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
|
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords;
|
||||||
|
@ -99,6 +97,8 @@ import ca.uhn.fhir.util.ClasspathUtil;
|
||||||
import ca.uhn.fhir.util.FhirVersionIndependentConcept;
|
import ca.uhn.fhir.util.FhirVersionIndependentConcept;
|
||||||
import ca.uhn.fhir.util.StopWatch;
|
import ca.uhn.fhir.util.StopWatch;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
|
@ -129,8 +129,6 @@ import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import jakarta.annotation.Nonnull;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
@ -257,8 +255,6 @@ public abstract class BaseJpaTest extends BaseTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IResourceHistoryTableDao myResourceHistoryTableDao;
|
private IResourceHistoryTableDao myResourceHistoryTableDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IForcedIdDao myForcedIdDao;
|
|
||||||
@Autowired
|
|
||||||
private DaoRegistry myDaoRegistry;
|
private DaoRegistry myDaoRegistry;
|
||||||
private final List<Object> myRegisteredInterceptors = new ArrayList<>(1);
|
private final List<Object> myRegisteredInterceptors = new ArrayList<>(1);
|
||||||
|
|
||||||
|
@ -517,14 +513,6 @@ public abstract class BaseJpaTest extends BaseTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int logAllForcedIds() {
|
|
||||||
return runInTransaction(() -> {
|
|
||||||
List<ForcedId> forcedIds = myForcedIdDao.findAll();
|
|
||||||
ourLog.info("Resources:\n * {}", forcedIds.stream().map(ForcedId::toString).collect(Collectors.joining("\n * ")));
|
|
||||||
return forcedIds.size();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void logAllDateIndexes() {
|
protected void logAllDateIndexes() {
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
ourLog.info("Date indexes:\n * {}", myResourceIndexedSearchParamDateDao.findAll().stream().map(ResourceIndexedSearchParamDate::toString).collect(Collectors.joining("\n * ")));
|
ourLog.info("Date indexes:\n * {}", myResourceIndexedSearchParamDateDao.findAll().stream().map(ResourceIndexedSearchParamDate::toString).collect(Collectors.joining("\n * ")));
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO TRM_CONCEPT_MAP_GRP_ELM_TGT (PID, TARGET_CODE, CONCEPT_MAP_URL, TARGET_DISPLAY, TARGET_EQUIVALENCE, SYSTEM_URL, SYSTEM_VERSION, VALUESET_URL, CONCEPT_MAP_GRP_ELM_PID) VALUES (61, NULL, NULL, 'PYRIDOXINE', 'UNMATCHED', NULL, NULL, NULL, 60);
|
|
@ -3,16 +3,17 @@ package ca.uhn.fhir.jpa.cache;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.cache.ResourcePersistentIdMap;
|
|
||||||
import ca.uhn.fhir.jpa.cache.ResourceVersionSvcDaoImpl;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
import jakarta.persistence.criteria.Path;
|
||||||
|
import jakarta.persistence.criteria.Root;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -23,11 +24,6 @@ import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import jakarta.persistence.TypedQuery;
|
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
|
||||||
import jakarta.persistence.criteria.Path;
|
|
||||||
import jakarta.persistence.criteria.Root;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -36,7 +32,6 @@ import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ -85,8 +80,6 @@ public class ResourceVersionSvcTest {
|
||||||
CriteriaQuery<ResourceTable> criteriaQuery = Mockito.mock(CriteriaQuery.class);
|
CriteriaQuery<ResourceTable> criteriaQuery = Mockito.mock(CriteriaQuery.class);
|
||||||
Root<ResourceTable> from = Mockito.mock(Root.class);
|
Root<ResourceTable> from = Mockito.mock(Root.class);
|
||||||
Path path = Mockito.mock(Path.class);
|
Path path = Mockito.mock(Path.class);
|
||||||
|
|
||||||
TypedQuery<ForcedId> queryMock = Mockito.mock(TypedQuery.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -83,7 +83,8 @@ public class HapiSchemaMigrationTest {
|
||||||
VersionEnum.V5_4_0,
|
VersionEnum.V5_4_0,
|
||||||
VersionEnum.V5_5_0,
|
VersionEnum.V5_5_0,
|
||||||
VersionEnum.V6_0_0,
|
VersionEnum.V6_0_0,
|
||||||
VersionEnum.V6_6_0
|
VersionEnum.V6_6_0,
|
||||||
|
VersionEnum.V7_2_0
|
||||||
);
|
);
|
||||||
|
|
||||||
int fromVersion = 0;
|
int fromVersion = 0;
|
||||||
|
@ -92,6 +93,7 @@ public class HapiSchemaMigrationTest {
|
||||||
|
|
||||||
for (int i = 0; i < allVersions.length; i++) {
|
for (int i = 0; i < allVersions.length; i++) {
|
||||||
toVersion = allVersions[i];
|
toVersion = allVersions[i];
|
||||||
|
ourLog.info("Applying migrations for {}", toVersion);
|
||||||
migrate(theDriverType, dataSource, hapiMigrationStorageSvc, toVersion);
|
migrate(theDriverType, dataSource, hapiMigrationStorageSvc, toVersion);
|
||||||
if (dataVersions.contains(toVersion)) {
|
if (dataVersions.contains(toVersion)) {
|
||||||
myEmbeddedServersExtension.insertPersistenceTestData(theDriverType, toVersion);
|
myEmbeddedServersExtension.insertPersistenceTestData(theDriverType, toVersion);
|
||||||
|
|
|
@ -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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-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.1.7-SNAPSHOT</version>
|
<version>7.1.8-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -32,6 +32,8 @@ import jakarta.annotation.PreDestroy;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MdmProviderLoader {
|
public class MdmProviderLoader {
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -58,26 +60,28 @@ public class MdmProviderLoader {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
private BaseMdmProvider myMdmProvider;
|
private Supplier<Object> myMdmProviderSupplier;
|
||||||
private MdmLinkHistoryProviderDstu3Plus myMdmHistoryProvider;
|
private Supplier<Object> myMdmHistoryProviderSupplier;
|
||||||
|
|
||||||
public void loadProvider() {
|
public void loadProvider() {
|
||||||
switch (myFhirContext.getVersion().getVersion()) {
|
switch (myFhirContext.getVersion().getVersion()) {
|
||||||
case DSTU3:
|
case DSTU3:
|
||||||
case R4:
|
case R4:
|
||||||
case R5:
|
case R5:
|
||||||
myResourceProviderFactory.addSupplier(() -> new MdmProviderDstu3Plus(
|
// We store the supplier so that removeSupplier works properly
|
||||||
|
myMdmProviderSupplier = () -> new MdmProviderDstu3Plus(
|
||||||
myFhirContext,
|
myFhirContext,
|
||||||
myMdmControllerSvc,
|
myMdmControllerSvc,
|
||||||
myMdmControllerHelper,
|
myMdmControllerHelper,
|
||||||
myMdmSubmitSvc,
|
myMdmSubmitSvc,
|
||||||
myInterceptorBroadcaster,
|
myInterceptorBroadcaster,
|
||||||
myMdmSettings));
|
myMdmSettings);
|
||||||
|
// We store the supplier so that removeSupplier works properly
|
||||||
|
myResourceProviderFactory.addSupplier(myMdmProviderSupplier);
|
||||||
if (myStorageSettings.isNonResourceDbHistoryEnabled()) {
|
if (myStorageSettings.isNonResourceDbHistoryEnabled()) {
|
||||||
myResourceProviderFactory.addSupplier(() -> {
|
myMdmHistoryProviderSupplier = () -> new MdmLinkHistoryProviderDstu3Plus(
|
||||||
return new MdmLinkHistoryProviderDstu3Plus(
|
myFhirContext, myMdmControllerSvc, myInterceptorBroadcaster);
|
||||||
myFhirContext, myMdmControllerSvc, myInterceptorBroadcaster);
|
myResourceProviderFactory.addSupplier(myMdmHistoryProviderSupplier);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -88,11 +92,11 @@ public class MdmProviderLoader {
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
public void unloadProvider() {
|
public void unloadProvider() {
|
||||||
if (myMdmProvider != null) {
|
if (myMdmProviderSupplier != null) {
|
||||||
myResourceProviderFactory.removeSupplier(() -> myMdmProvider);
|
myResourceProviderFactory.removeSupplier(myMdmProviderSupplier);
|
||||||
}
|
}
|
||||||
if (myMdmHistoryProvider != null) {
|
if (myMdmHistoryProviderSupplier != null) {
|
||||||
myResourceProviderFactory.removeSupplier(() -> myMdmHistoryProvider);
|
myResourceProviderFactory.removeSupplier(myMdmHistoryProviderSupplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue