adding pointcuts for mdm operations (#5116)
* adding pointcuts for mdm operations * adding changelog * cleanup * cleaning up * formatting * review fixes * formatting * more cleanup * cleanup * moving changelog * fixing a bug * cleanup * formatting * version bump * fixing broken merge * fixing the version --------- Co-authored-by: leif stawnyczy <leifstawnyczy@leifs-MacBook-Pro.local>
This commit is contained in:
parent
fd5c2c2862
commit
a48c602f71
|
@ -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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -2250,7 +2250,7 @@ public enum Pointcut implements IPointcut {
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage - This parameter should not be modified as processing is complete when this hook is invoked.</li>
|
* <li>ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage - This parameter should not be modified as processing is complete when this hook is invoked.</li>
|
||||||
* <li>ca.uhn.fhir.rest.server.TransactionLogMessages - This parameter is for informational messages provided by the MDM module during MDM processing.</li>
|
* <li>ca.uhn.fhir.rest.server.TransactionLogMessages - This parameter is for informational messages provided by the MDM module during MDM processing.</li>
|
||||||
* <li>ca.uhn.fhir.mdm.api.MdmLinkChangeEvent - Contains information about the change event, including target and golden resource IDs and the operation type.</li>
|
* <li>ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent - Contains information about the change event, including target and golden resource IDs and the operation type.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -2261,7 +2261,192 @@ public enum Pointcut implements IPointcut {
|
||||||
void.class,
|
void.class,
|
||||||
"ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage",
|
"ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage",
|
||||||
"ca.uhn.fhir.rest.server.TransactionLogMessages",
|
"ca.uhn.fhir.rest.server.TransactionLogMessages",
|
||||||
"ca.uhn.fhir.mdm.api.MdmLinkEvent"),
|
"ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>MDM Create Link</b>
|
||||||
|
* This hook is invoked after an MDM link is created,
|
||||||
|
* and changes have been persisted to the database.
|
||||||
|
* <p>
|
||||||
|
* Hook may accept the following parameters:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.rest.api.server.RequestDetails - An object containing details about the request that is about to be processed, including details such as the
|
||||||
|
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||||
|
* pulled out of the servlet request.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.mdm.api.MdmLinkChangeEvent - Contains information about the link event, including target and golden resource IDs and the operation type.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* Hooks should return <code>void</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
MDM_POST_CREATE_LINK(
|
||||||
|
void.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>MDM Update Link</b>
|
||||||
|
* This hook is invoked after an MDM link is updated,
|
||||||
|
* and changes have been persisted to the database.
|
||||||
|
* <p>
|
||||||
|
* Hook may accept the following parameters:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.rest.api.server.RequestDetails - An object containing details about the request that is about to be processed, including details such as the
|
||||||
|
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||||
|
* pulled out of the servlet request.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.mdm.api.MdmLinkChangeEvent - Contains information about the link event, including target and golden resource IDs and the operation type.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* Hooks should return <code>void</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
MDM_POST_UPDATE_LINK(
|
||||||
|
void.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>MDM Merge Golden Resources</b>
|
||||||
|
* This hook is invoked after 2 golden resources have been
|
||||||
|
* merged together and results persisted.
|
||||||
|
* <p>
|
||||||
|
* Hook may accept the following parameters:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.rest.api.server.RequestDetails - An object containing details about the request that is about to be processed, including details such as the
|
||||||
|
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||||
|
* pulled out of the servlet request.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.mdm.model.mdmevents.MdmMergeEvent - Contains information about the from and to resources.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* Hooks should return <code>void</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
MDM_POST_MERGE_GOLDEN_RESOURCES(
|
||||||
|
void.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.mdm.model.mdmevents.MdmMergeEvent"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>MDM Link History Hook:</b>
|
||||||
|
* This hook is invoked after link histories are queried,
|
||||||
|
* but before the results are returned to the caller.
|
||||||
|
* <p>
|
||||||
|
* Hook may accept the following parameters:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.rest.api.server.RequestDetails - An object containing details about the request that is about to be processed.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.mdm.model.mdmevents.MdmHistoryEvent - An MDM History Event containing
|
||||||
|
* information about the requested golden resource ids and/or source ids input, and
|
||||||
|
* the returned link histories.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
MDM_POST_LINK_HISTORY(
|
||||||
|
void.class,
|
||||||
|
"ca.uhn.fhir.rest.api.server.RequestDetails",
|
||||||
|
"ca.uhn.fhir.mdm.model.mdmevents.MdmHistoryEvent"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>MDM Not Duplicate/Unduplicate Hook:</b>
|
||||||
|
* This hook is invoked after 2 golden resources with an existing link
|
||||||
|
* of "POSSIBLE_DUPLICATE" get unlinked/unduplicated.
|
||||||
|
* <p>
|
||||||
|
* This hook accepts the following parameters:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.rest.api.server.RequestDetails - An object containing details about the request that is about to be processed.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent - the resulting final link
|
||||||
|
* between the 2 golden resources; now a NO_MATCH link.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
MDM_POST_NOT_DUPLICATE(
|
||||||
|
void.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>MDM Clear Hook:</b>
|
||||||
|
* This hook is invoked when an mdm clear operation is requested.
|
||||||
|
* <p>
|
||||||
|
* This hook accepts the following parameters:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.rest.api.server.RequestDetails - An object containing details about the request that is about to be processed.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.mdm.model.mdmevents.MdmClearEvent - the event containing information on the clear command,
|
||||||
|
* including the type filter (if any) and the batch size (if any).
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
MDM_CLEAR(
|
||||||
|
void.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.mdm.model.mdmevents.MdmClearEvent"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>MDM Submit Hook:</b>
|
||||||
|
* This hook is invoked whenever when mdm submit operation is requested.
|
||||||
|
* MDM submits can be invoked in multiple ways.
|
||||||
|
* Some of which accept asynchronous calling, and some of which do not.
|
||||||
|
* <p>
|
||||||
|
* If the MDM Submit operation is asynchronous
|
||||||
|
* (typically because the Prefer: respond-async header has been provided)
|
||||||
|
* this hook will be invoked after the job is submitted, but before it has
|
||||||
|
* necessarily been executed.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* If the MDM Submit operation is synchronous,
|
||||||
|
* this hook will be invoked immediately after the submit operation
|
||||||
|
* has been executed, but before the call is returned to the caller.
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* On Patient Type. Can be synchronous or asynchronous.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* On Practitioner Type. Can be synchronous or asynchronous.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* On specific patient instances. Is always synchronous.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* On specific practitioner instances. Is always synchronous.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* On the server (ie, not on any resource) with or without a resource filter.
|
||||||
|
* Can be synchronous or asynchronous.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* In all cases, this hook will take the following parameters:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.rest.api.server.RequestDetails - An object containing details about the request that is about to be processed.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* ca.uhn.fhir.mdm.model.mdmevents.MdmSubmitEvent - An event with the Mdm Submit information
|
||||||
|
* (urls specifying paths that will be searched for MDM submit, as well as
|
||||||
|
* if this was an asynchronous request or not).
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
MDM_SUBMIT(
|
||||||
|
void.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.mdm.model.mdmevents.MdmSubmitEvent"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <b>JPA Hook:</b>
|
* <b>JPA Hook:</b>
|
||||||
|
|
|
@ -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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-cli</artifactId>
|
<artifactId>hapi-fhir-cli</artifactId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
type: add
|
||||||
|
issue: 5090
|
||||||
|
jira: SMILE-5987
|
||||||
|
title: "Adding pointcuts for the following MDM Operations:
|
||||||
|
MDM_CREATE_LINK, MDM_UPDATE_LINK, MDM_MERGE_GOLDEN_RESOURCES,
|
||||||
|
MDM_LINK_HISTORY, MDM_NOT_DUPLICATE, MDM_CLEAR, MDM_SUBMIT.
|
||||||
|
"
|
|
@ -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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ import ca.uhn.fhir.jpa.mdm.svc.candidate.TooManyCandidatesException;
|
||||||
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
|
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
|
||||||
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
|
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
|
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
package ca.uhn.fhir.jpa.mdm.svc;
|
package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
||||||
|
@ -30,11 +33,15 @@ import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmMergeGoldenResourcesParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmEventResource;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmMergeEvent;
|
||||||
import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
|
import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
|
||||||
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
||||||
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
@ -71,64 +78,90 @@ public class GoldenResourceMergerSvcImpl implements IGoldenResourceMergerSvc {
|
||||||
@Autowired
|
@Autowired
|
||||||
MdmPartitionHelper myMdmPartitionHelper;
|
MdmPartitionHelper myMdmPartitionHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public IAnyResource mergeGoldenResources(
|
public IAnyResource mergeGoldenResources(MdmMergeGoldenResourcesParams theParams) {
|
||||||
IAnyResource theFromGoldenResource,
|
MdmTransactionContext mdmTransactionContext = theParams.getMdmTransactionContext();
|
||||||
IAnyResource theMergedResource,
|
IAnyResource mergedResource = theParams.getManuallyMergedResource();
|
||||||
IAnyResource theToGoldenResource,
|
IAnyResource fromGoldenResource = theParams.getFromGoldenResource();
|
||||||
MdmTransactionContext theMdmTransactionContext) {
|
IAnyResource toGoldenResource = theParams.getToGoldenResource();
|
||||||
String resourceType = theMdmTransactionContext.getResourceType();
|
|
||||||
|
|
||||||
if (theMergedResource != null) {
|
String resourceType = mdmTransactionContext.getResourceType();
|
||||||
if (myGoldenResourceHelper.hasIdentifier(theMergedResource)) {
|
|
||||||
|
if (mergedResource != null) {
|
||||||
|
if (myGoldenResourceHelper.hasIdentifier(mergedResource)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
Msg.code(751) + "Manually merged resource can not contain identifiers");
|
Msg.code(751) + "Manually merged resource can not contain identifiers");
|
||||||
}
|
}
|
||||||
myGoldenResourceHelper.mergeIndentifierFields(
|
myGoldenResourceHelper.mergeIndentifierFields(fromGoldenResource, mergedResource, mdmTransactionContext);
|
||||||
theFromGoldenResource, theMergedResource, theMdmTransactionContext);
|
myGoldenResourceHelper.mergeIndentifierFields(toGoldenResource, mergedResource, mdmTransactionContext);
|
||||||
myGoldenResourceHelper.mergeIndentifierFields(
|
|
||||||
theToGoldenResource, theMergedResource, theMdmTransactionContext);
|
|
||||||
|
|
||||||
theMergedResource.setId(theToGoldenResource.getId());
|
mergedResource.setId(toGoldenResource.getId());
|
||||||
theToGoldenResource = (IAnyResource) myMdmResourceDaoSvc
|
toGoldenResource = (IAnyResource) myMdmResourceDaoSvc
|
||||||
.upsertGoldenResource(theMergedResource, resourceType)
|
.upsertGoldenResource(mergedResource, resourceType)
|
||||||
.getResource();
|
.getResource();
|
||||||
} else {
|
} else {
|
||||||
myGoldenResourceHelper.mergeIndentifierFields(
|
myGoldenResourceHelper.mergeIndentifierFields(fromGoldenResource, toGoldenResource, mdmTransactionContext);
|
||||||
theFromGoldenResource, theToGoldenResource, theMdmTransactionContext);
|
myGoldenResourceHelper.mergeNonIdentiferFields(fromGoldenResource, toGoldenResource, mdmTransactionContext);
|
||||||
myGoldenResourceHelper.mergeNonIdentiferFields(
|
|
||||||
theFromGoldenResource, theToGoldenResource, theMdmTransactionContext);
|
|
||||||
// Save changes to the golden resource
|
// Save changes to the golden resource
|
||||||
myMdmResourceDaoSvc.upsertGoldenResource(theToGoldenResource, resourceType);
|
myMdmResourceDaoSvc.upsertGoldenResource(toGoldenResource, resourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
myMdmPartitionHelper.validateMdmResourcesPartitionMatches(theFromGoldenResource, theToGoldenResource);
|
myMdmPartitionHelper.validateMdmResourcesPartitionMatches(fromGoldenResource, toGoldenResource);
|
||||||
|
|
||||||
// Merge the links from the FROM to the TO resource. Clean up dangling links.
|
// Merge the links from the FROM to the TO resource. Clean up dangling links.
|
||||||
mergeGoldenResourceLinks(
|
mergeGoldenResourceLinks(
|
||||||
theFromGoldenResource,
|
fromGoldenResource, toGoldenResource, fromGoldenResource.getIdElement(), mdmTransactionContext);
|
||||||
theToGoldenResource,
|
|
||||||
theFromGoldenResource.getIdElement(),
|
|
||||||
theMdmTransactionContext);
|
|
||||||
|
|
||||||
// Create the new REDIRECT link
|
// Create the new REDIRECT link
|
||||||
addMergeLink(theToGoldenResource, theFromGoldenResource, resourceType, theMdmTransactionContext);
|
addMergeLink(toGoldenResource, fromGoldenResource, resourceType, mdmTransactionContext);
|
||||||
|
|
||||||
// Strip the golden resource tag from the now-deprecated resource.
|
// Strip the golden resource tag from the now-deprecated resource.
|
||||||
myMdmResourceDaoSvc.removeGoldenResourceTag(theFromGoldenResource, resourceType);
|
myMdmResourceDaoSvc.removeGoldenResourceTag(fromGoldenResource, resourceType);
|
||||||
|
|
||||||
// Add the REDIRECT tag to that same deprecated resource.
|
// Add the REDIRECT tag to that same deprecated resource.
|
||||||
MdmResourceUtil.setGoldenResourceRedirected(theFromGoldenResource);
|
MdmResourceUtil.setGoldenResourceRedirected(fromGoldenResource);
|
||||||
|
|
||||||
// Save the deprecated resource.
|
// Save the deprecated resource.
|
||||||
myMdmResourceDaoSvc.upsertGoldenResource(theFromGoldenResource, resourceType);
|
myMdmResourceDaoSvc.upsertGoldenResource(fromGoldenResource, resourceType);
|
||||||
|
|
||||||
log(
|
log(
|
||||||
theMdmTransactionContext,
|
mdmTransactionContext,
|
||||||
"Merged " + theFromGoldenResource.getIdElement().toVersionless() + " into "
|
"Merged " + fromGoldenResource.getIdElement().toVersionless() + " into "
|
||||||
+ theToGoldenResource.getIdElement().toVersionless());
|
+ toGoldenResource.getIdElement().toVersionless());
|
||||||
return theToGoldenResource;
|
|
||||||
|
// invoke hooks
|
||||||
|
invokeMdmMergeGoldenResourcesHook(theParams, fromGoldenResource, toGoldenResource);
|
||||||
|
|
||||||
|
return toGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invokeMdmMergeGoldenResourcesHook(
|
||||||
|
MdmMergeGoldenResourcesParams theParams, IAnyResource fromGoldenResource, IAnyResource toGoldenResource) {
|
||||||
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_POST_MERGE_GOLDEN_RESOURCES)) {
|
||||||
|
// pointcut for MDM_POST_MERGE_GOLDEN_RESOURCES
|
||||||
|
MdmMergeEvent event = new MdmMergeEvent();
|
||||||
|
MdmEventResource from = new MdmEventResource();
|
||||||
|
from.setId(
|
||||||
|
fromGoldenResource.getIdElement().toUnqualifiedVersionless().getValue());
|
||||||
|
from.setResourceType(fromGoldenResource.fhirType());
|
||||||
|
from.setIsGoldenResource(true);
|
||||||
|
event.setFromResource(from);
|
||||||
|
|
||||||
|
MdmEventResource to = new MdmEventResource();
|
||||||
|
to.setId(toGoldenResource.getIdElement().toUnqualifiedVersionless().getValue());
|
||||||
|
to.setResourceType(toGoldenResource.fhirType());
|
||||||
|
to.setIsGoldenResource(true);
|
||||||
|
event.setToResource(to);
|
||||||
|
|
||||||
|
HookParams params = new HookParams();
|
||||||
|
params.add(MdmMergeEvent.class, event);
|
||||||
|
params.add(RequestDetails.class, theParams.getRequestDetails());
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_POST_MERGE_GOLDEN_RESOURCES, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
package ca.uhn.fhir.jpa.mdm.svc;
|
package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLink;
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract for decoupling API dependency from the base / JPA modules.
|
* Contract for decoupling API dependency from the base / JPA modules.
|
||||||
|
|
|
@ -22,6 +22,9 @@ package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
import ca.uhn.fhir.batch2.api.IJobCoordinator;
|
import ca.uhn.fhir.batch2.api.IJobCoordinator;
|
||||||
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
|
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.interceptor.model.ReadPartitionIdRequestDetails;
|
import ca.uhn.fhir.interceptor.model.ReadPartitionIdRequestDetails;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
|
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
|
||||||
|
@ -32,8 +35,6 @@ import ca.uhn.fhir.mdm.api.IMdmLinkCreateSvc;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
|
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc;
|
import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
||||||
|
@ -41,9 +42,15 @@ import ca.uhn.fhir.mdm.batch2.clear.MdmClearAppCtx;
|
||||||
import ca.uhn.fhir.mdm.batch2.clear.MdmClearJobParameters;
|
import ca.uhn.fhir.mdm.batch2.clear.MdmClearJobParameters;
|
||||||
import ca.uhn.fhir.mdm.batch2.submit.MdmSubmitAppCtx;
|
import ca.uhn.fhir.mdm.batch2.submit.MdmSubmitAppCtx;
|
||||||
import ca.uhn.fhir.mdm.batch2.submit.MdmSubmitJobParameters;
|
import ca.uhn.fhir.mdm.batch2.submit.MdmSubmitJobParameters;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmMergeGoldenResourcesParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmUnduplicateGoldenResourceParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmClearEvent;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmSubmitEvent;
|
||||||
import ca.uhn.fhir.mdm.provider.MdmControllerHelper;
|
import ca.uhn.fhir.mdm.provider.MdmControllerHelper;
|
||||||
import ca.uhn.fhir.mdm.provider.MdmControllerUtil;
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||||
|
@ -93,24 +100,43 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
@Autowired
|
@Autowired
|
||||||
IJobCoordinator myJobCoordinator;
|
IJobCoordinator myJobCoordinator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
public MdmControllerSvcImpl() {}
|
public MdmControllerSvcImpl() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IAnyResource mergeGoldenResources(
|
public IAnyResource mergeGoldenResources(MdmMergeGoldenResourcesParams theParams) {
|
||||||
String theFromGoldenResourceId,
|
if (theParams.getFromGoldenResource() == null) {
|
||||||
String theToGoldenResourceId,
|
theParams.setFromGoldenResource(myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
||||||
IAnyResource theManuallyMergedGoldenResource,
|
ProviderConstants.MDM_MERGE_GR_FROM_GOLDEN_RESOURCE_ID, theParams.getFromGoldenResourceId()));
|
||||||
MdmTransactionContext theMdmTransactionContext) {
|
}
|
||||||
IAnyResource fromGoldenResource = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
IAnyResource fromGoldenResource = theParams.getFromGoldenResource();
|
||||||
ProviderConstants.MDM_MERGE_GR_FROM_GOLDEN_RESOURCE_ID, theFromGoldenResourceId);
|
;
|
||||||
IAnyResource toGoldenResource = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
if (theParams.getToGoldenResource() == null) {
|
||||||
ProviderConstants.MDM_MERGE_GR_TO_GOLDEN_RESOURCE_ID, theToGoldenResourceId);
|
theParams.setToGoldenResource(myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
||||||
|
ProviderConstants.MDM_MERGE_GR_TO_GOLDEN_RESOURCE_ID, theParams.getToGoldenResourceId()));
|
||||||
|
}
|
||||||
|
IAnyResource toGoldenResource = theParams.getToGoldenResource();
|
||||||
myMdmControllerHelper.validateMergeResources(fromGoldenResource, toGoldenResource);
|
myMdmControllerHelper.validateMergeResources(fromGoldenResource, toGoldenResource);
|
||||||
myMdmControllerHelper.validateSameVersion(fromGoldenResource, theFromGoldenResourceId);
|
myMdmControllerHelper.validateSameVersion(fromGoldenResource, theParams.getFromGoldenResourceId());
|
||||||
myMdmControllerHelper.validateSameVersion(toGoldenResource, theToGoldenResourceId);
|
myMdmControllerHelper.validateSameVersion(toGoldenResource, theParams.getToGoldenResourceId());
|
||||||
|
|
||||||
return myGoldenResourceMergerSvc.mergeGoldenResources(
|
return myGoldenResourceMergerSvc.mergeGoldenResources(theParams);
|
||||||
fromGoldenResource, theManuallyMergedGoldenResource, toGoldenResource, theMdmTransactionContext);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IAnyResource updateLink(
|
||||||
|
String theGoldenResourceId,
|
||||||
|
String theSourceResourceId,
|
||||||
|
String theMatchResult,
|
||||||
|
MdmTransactionContext theMdmTransactionContext) {
|
||||||
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
|
params.setResourceId(theSourceResourceId);
|
||||||
|
params.setGoldenResourceId(theGoldenResourceId);
|
||||||
|
params.setMdmContext(theMdmTransactionContext);
|
||||||
|
params.setMatchResult(MdmMatchResultEnum.valueOf(theMatchResult));
|
||||||
|
return updateLink(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -228,21 +254,25 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
return resultPage;
|
return resultPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void convertAndValidateParameters(MdmCreateOrUpdateParams theParams) {
|
||||||
public IAnyResource updateLink(
|
if (theParams.getGoldenResource() == null) {
|
||||||
String theGoldenResourceId,
|
IAnyResource goldenResource = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
||||||
String theSourceResourceId,
|
ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theParams.getGoldenResourceId());
|
||||||
String theMatchResult,
|
theParams.setGoldenResource(goldenResource);
|
||||||
MdmTransactionContext theMdmTransactionContext) {
|
}
|
||||||
MdmMatchResultEnum matchResult = MdmControllerUtil.extractMatchResultOrNull(theMatchResult);
|
if (theParams.getSourceResource() == null) {
|
||||||
IAnyResource goldenResource = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
IAnyResource source = myMdmControllerHelper.getLatestSourceFromIdOrThrowException(
|
||||||
ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId);
|
ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theParams.getResourceId());
|
||||||
IAnyResource source = myMdmControllerHelper.getLatestSourceFromIdOrThrowException(
|
theParams.setSourceResource(source);
|
||||||
ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theSourceResourceId);
|
}
|
||||||
myMdmControllerHelper.validateSameVersion(goldenResource, theGoldenResourceId);
|
myMdmControllerHelper.validateSameVersion(theParams.getGoldenResource(), theParams.getGoldenResourceId());
|
||||||
myMdmControllerHelper.validateSameVersion(source, theSourceResourceId);
|
myMdmControllerHelper.validateSameVersion(theParams.getSourceResource(), theParams.getResourceId());
|
||||||
|
}
|
||||||
|
|
||||||
return myIMdmLinkUpdaterSvc.updateLink(goldenResource, source, matchResult, theMdmTransactionContext);
|
@Override
|
||||||
|
public IAnyResource updateLink(MdmCreateOrUpdateParams theParams) {
|
||||||
|
convertAndValidateParameters(theParams);
|
||||||
|
return myIMdmLinkUpdaterSvc.updateLink(theParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -251,15 +281,21 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
String theSourceResourceId,
|
String theSourceResourceId,
|
||||||
@Nullable String theMatchResult,
|
@Nullable String theMatchResult,
|
||||||
MdmTransactionContext theMdmTransactionContext) {
|
MdmTransactionContext theMdmTransactionContext) {
|
||||||
MdmMatchResultEnum matchResult = MdmControllerUtil.extractMatchResultOrNull(theMatchResult);
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
IAnyResource goldenResource = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
params.setGoldenResourceId(theGoldenResourceId);
|
||||||
ProviderConstants.MDM_CREATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId);
|
params.setResourceId(theSourceResourceId);
|
||||||
IAnyResource source = myMdmControllerHelper.getLatestSourceFromIdOrThrowException(
|
params.setMdmContext(theMdmTransactionContext);
|
||||||
ProviderConstants.MDM_CREATE_LINK_RESOURCE_ID, theSourceResourceId);
|
if (theMatchResult != null) {
|
||||||
myMdmControllerHelper.validateSameVersion(goldenResource, theGoldenResourceId);
|
params.setMatchResult(MdmMatchResultEnum.valueOf(theMatchResult));
|
||||||
myMdmControllerHelper.validateSameVersion(source, theSourceResourceId);
|
}
|
||||||
|
return createLink(params);
|
||||||
|
}
|
||||||
|
|
||||||
return myIMdmLinkCreateSvc.createLink(goldenResource, source, matchResult, theMdmTransactionContext);
|
@Override
|
||||||
|
public IAnyResource createLink(MdmCreateOrUpdateParams theParams) {
|
||||||
|
convertAndValidateParameters(theParams);
|
||||||
|
|
||||||
|
return myIMdmLinkCreateSvc.createLink(theParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -269,9 +305,10 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
ServletRequestDetails theRequestDetails) {
|
ServletRequestDetails theRequestDetails) {
|
||||||
MdmClearJobParameters params = new MdmClearJobParameters();
|
MdmClearJobParameters params = new MdmClearJobParameters();
|
||||||
params.setResourceNames(theResourceNames);
|
params.setResourceNames(theResourceNames);
|
||||||
if (theBatchSize != null
|
boolean hasBatchSize = theBatchSize != null
|
||||||
&& theBatchSize.getValue() != null
|
&& theBatchSize.getValue() != null
|
||||||
&& theBatchSize.getValue().longValue() > 0) {
|
&& theBatchSize.getValue().longValue() > 0;
|
||||||
|
if (hasBatchSize) {
|
||||||
params.setBatchSize(theBatchSize.getValue().intValue());
|
params.setBatchSize(theBatchSize.getValue().intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +324,20 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
Batch2JobStartResponse response = myJobCoordinator.startInstance(theRequestDetails, request);
|
Batch2JobStartResponse response = myJobCoordinator.startInstance(theRequestDetails, request);
|
||||||
String id = response.getInstanceId();
|
String id = response.getInstanceId();
|
||||||
|
|
||||||
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_CLEAR)) {
|
||||||
|
// MDM_CLEAR hook:
|
||||||
|
MdmClearEvent event = new MdmClearEvent();
|
||||||
|
event.setResourceTypes(theResourceNames);
|
||||||
|
if (hasBatchSize) {
|
||||||
|
event.setBatchSize(theBatchSize.getValue().longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
HookParams hookParams = new HookParams();
|
||||||
|
hookParams.add(RequestDetails.class, theRequestDetails);
|
||||||
|
hookParams.add(MdmClearEvent.class, event);
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_CLEAR, hookParams);
|
||||||
|
}
|
||||||
|
|
||||||
IBaseParameters retVal = ParametersUtil.newInstance(myFhirContext);
|
IBaseParameters retVal = ParametersUtil.newInstance(myFhirContext);
|
||||||
ParametersUtil.addParameterToParametersString(
|
ParametersUtil.addParameterToParametersString(
|
||||||
myFhirContext, retVal, ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, id);
|
myFhirContext, retVal, ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, id);
|
||||||
|
@ -297,10 +348,10 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
public IBaseParameters submitMdmSubmitJob(
|
public IBaseParameters submitMdmSubmitJob(
|
||||||
List<String> theUrls, IPrimitiveType<BigDecimal> theBatchSize, ServletRequestDetails theRequestDetails) {
|
List<String> theUrls, IPrimitiveType<BigDecimal> theBatchSize, ServletRequestDetails theRequestDetails) {
|
||||||
MdmSubmitJobParameters params = new MdmSubmitJobParameters();
|
MdmSubmitJobParameters params = new MdmSubmitJobParameters();
|
||||||
|
boolean hasBatchSize = theBatchSize != null
|
||||||
if (theBatchSize != null
|
|
||||||
&& theBatchSize.getValue() != null
|
&& theBatchSize.getValue() != null
|
||||||
&& theBatchSize.getValue().longValue() > 0) {
|
&& theBatchSize.getValue().longValue() > 0;
|
||||||
|
if (hasBatchSize) {
|
||||||
params.setBatchSize(theBatchSize.getValue().intValue());
|
params.setBatchSize(theBatchSize.getValue().intValue());
|
||||||
}
|
}
|
||||||
params.setRequestPartitionId(RequestPartitionId.allPartitions());
|
params.setRequestPartitionId(RequestPartitionId.allPartitions());
|
||||||
|
@ -317,6 +368,22 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
IBaseParameters retVal = ParametersUtil.newInstance(myFhirContext);
|
IBaseParameters retVal = ParametersUtil.newInstance(myFhirContext);
|
||||||
ParametersUtil.addParameterToParametersString(
|
ParametersUtil.addParameterToParametersString(
|
||||||
myFhirContext, retVal, ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, id);
|
myFhirContext, retVal, ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, id);
|
||||||
|
|
||||||
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_SUBMIT)) {
|
||||||
|
// MDM_SUBMIT batch submit job
|
||||||
|
MdmSubmitEvent event = new MdmSubmitEvent();
|
||||||
|
event.setBatchJob(true);
|
||||||
|
event.setUrls(theUrls);
|
||||||
|
if (hasBatchSize) {
|
||||||
|
event.setBatchSize(theBatchSize.getValue().longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
HookParams hookParams = new HookParams();
|
||||||
|
hookParams.add(RequestDetails.class, theRequestDetails);
|
||||||
|
hookParams.add(MdmSubmitEvent.class, event);
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_SUBMIT, hookParams);
|
||||||
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,12 +392,43 @@ public class MdmControllerSvcImpl implements IMdmControllerSvc {
|
||||||
String theGoldenResourceId,
|
String theGoldenResourceId,
|
||||||
String theTargetGoldenResourceId,
|
String theTargetGoldenResourceId,
|
||||||
MdmTransactionContext theMdmTransactionContext) {
|
MdmTransactionContext theMdmTransactionContext) {
|
||||||
IAnyResource goldenResource = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
MdmUnduplicateGoldenResourceParams params = new MdmUnduplicateGoldenResourceParams();
|
||||||
ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId);
|
params.setTargetGoldenResourceId(theTargetGoldenResourceId);
|
||||||
IAnyResource target = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
params.setGoldenResourceId(theGoldenResourceId);
|
||||||
ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theTargetGoldenResourceId);
|
params.setMdmContext(theMdmTransactionContext);
|
||||||
|
|
||||||
myIMdmLinkUpdaterSvc.notDuplicateGoldenResource(goldenResource, target, theMdmTransactionContext);
|
unduplicateGoldenResource(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unduplicateGoldenResource(MdmUnduplicateGoldenResourceParams theParams) {
|
||||||
|
if (theParams.getGoldenResource() == null) {
|
||||||
|
IAnyResource goldenResource = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
||||||
|
ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theParams.getGoldenResourceId());
|
||||||
|
theParams.setGoldenResource(goldenResource);
|
||||||
|
}
|
||||||
|
if (theParams.getTargetGoldenResource() == null) {
|
||||||
|
IAnyResource target = myMdmControllerHelper.getLatestGoldenResourceFromIdOrThrowException(
|
||||||
|
ProviderConstants.MDM_UPDATE_LINK_RESOURCE_ID, theParams.getTargetGoldenResourceId());
|
||||||
|
theParams.setTargetGoldenResource(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
myIMdmLinkUpdaterSvc.unduplicateGoldenResource(theParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IAnyResource mergeGoldenResources(
|
||||||
|
String theFromGoldenResourceId,
|
||||||
|
String theToGoldenResourceId,
|
||||||
|
IAnyResource theManuallyMergedGoldenResource,
|
||||||
|
MdmTransactionContext theMdmTransactionContext) {
|
||||||
|
MdmMergeGoldenResourcesParams params = new MdmMergeGoldenResourcesParams();
|
||||||
|
params.setToGoldenResourceId(theToGoldenResourceId);
|
||||||
|
params.setFromGoldenResourceId(theFromGoldenResourceId);
|
||||||
|
params.setToGoldenResourceId(theToGoldenResourceId);
|
||||||
|
params.setManuallyMergedResource(theManuallyMergedGoldenResource);
|
||||||
|
params.setMdmTransactionContext(theMdmTransactionContext);
|
||||||
|
return mergeGoldenResources(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateMdmQueryPermissions(
|
private void validateMdmQueryPermissions(
|
||||||
|
|
|
@ -21,6 +21,9 @@ package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
||||||
|
@ -31,11 +34,13 @@ import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent;
|
||||||
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
||||||
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
||||||
import ca.uhn.fhir.mdm.util.MessageHelper;
|
import ca.uhn.fhir.mdm.util.MessageHelper;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
@ -53,9 +58,11 @@ public class MdmLinkCreateSvcImpl implements IMdmLinkCreateSvc {
|
||||||
@Autowired
|
@Autowired
|
||||||
FhirContext myFhirContext;
|
FhirContext myFhirContext;
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Autowired
|
@Autowired
|
||||||
IIdHelperService myIdHelperService;
|
IIdHelperService myIdHelperService;
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Autowired
|
@Autowired
|
||||||
MdmLinkDaoSvc myMdmLinkDaoSvc;
|
MdmLinkDaoSvc myMdmLinkDaoSvc;
|
||||||
|
|
||||||
|
@ -68,49 +75,56 @@ public class MdmLinkCreateSvcImpl implements IMdmLinkCreateSvc {
|
||||||
@Autowired
|
@Autowired
|
||||||
MdmPartitionHelper myMdmPartitionHelper;
|
MdmPartitionHelper myMdmPartitionHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IMdmModelConverterSvc myModelConverter;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public IAnyResource createLink(
|
public IAnyResource createLink(MdmCreateOrUpdateParams theParams) {
|
||||||
IAnyResource theGoldenResource,
|
IAnyResource sourceResource = theParams.getSourceResource();
|
||||||
IAnyResource theSourceResource,
|
IAnyResource goldenResource = theParams.getGoldenResource();
|
||||||
MdmMatchResultEnum theMatchResult,
|
MdmMatchResultEnum matchResult = theParams.getMatchResult();
|
||||||
MdmTransactionContext theMdmContext) {
|
|
||||||
String sourceType = myFhirContext.getResourceType(theSourceResource);
|
|
||||||
|
|
||||||
validateCreateLinkRequest(theGoldenResource, theSourceResource, sourceType);
|
String sourceType = myFhirContext.getResourceType(sourceResource);
|
||||||
|
|
||||||
IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
|
validateCreateLinkRequest(goldenResource, sourceResource, sourceType);
|
||||||
IResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(theSourceResource);
|
|
||||||
|
IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(goldenResource);
|
||||||
|
IResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(sourceResource);
|
||||||
|
|
||||||
// check if the golden resource and the source resource are in the same partition, throw error if not
|
// check if the golden resource and the source resource are in the same partition, throw error if not
|
||||||
myMdmPartitionHelper.validateMdmResourcesPartitionMatches(theGoldenResource, theSourceResource);
|
myMdmPartitionHelper.validateMdmResourcesPartitionMatches(goldenResource, sourceResource);
|
||||||
|
|
||||||
Optional<? extends IMdmLink> optionalMdmLink =
|
Optional<? extends IMdmLink> optionalMdmLink =
|
||||||
myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, targetId);
|
myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, targetId);
|
||||||
if (optionalMdmLink.isPresent()) {
|
if (optionalMdmLink.isPresent()) {
|
||||||
throw new InvalidRequestException(
|
throw new InvalidRequestException(
|
||||||
Msg.code(753) + myMessageHelper.getMessageForPresentLink(theGoldenResource, theSourceResource));
|
Msg.code(753) + myMessageHelper.getMessageForPresentLink(goldenResource, sourceResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<? extends IMdmLink> mdmLinks =
|
List<? extends IMdmLink> mdmLinks =
|
||||||
myMdmLinkDaoSvc.getMdmLinksBySourcePidAndMatchResult(targetId, MdmMatchResultEnum.MATCH);
|
myMdmLinkDaoSvc.getMdmLinksBySourcePidAndMatchResult(targetId, MdmMatchResultEnum.MATCH);
|
||||||
if (mdmLinks.size() > 0 && theMatchResult == MdmMatchResultEnum.MATCH) {
|
if (mdmLinks.size() > 0 && matchResult == MdmMatchResultEnum.MATCH) {
|
||||||
throw new InvalidRequestException(
|
throw new InvalidRequestException(
|
||||||
Msg.code(754) + myMessageHelper.getMessageForMultipleGoldenRecords(theSourceResource));
|
Msg.code(754) + myMessageHelper.getMessageForMultipleGoldenRecords(sourceResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
IMdmLink mdmLink = myMdmLinkDaoSvc.getOrCreateMdmLinkByGoldenResourceAndSourceResource(
|
IMdmLink mdmLink =
|
||||||
theGoldenResource, theSourceResource);
|
myMdmLinkDaoSvc.getOrCreateMdmLinkByGoldenResourceAndSourceResource(goldenResource, sourceResource);
|
||||||
mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL);
|
mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL);
|
||||||
mdmLink.setMdmSourceType(sourceType);
|
mdmLink.setMdmSourceType(sourceType);
|
||||||
if (theMatchResult == null) {
|
if (matchResult == null) {
|
||||||
mdmLink.setMatchResult(MdmMatchResultEnum.MATCH);
|
mdmLink.setMatchResult(MdmMatchResultEnum.MATCH);
|
||||||
} else {
|
} else {
|
||||||
mdmLink.setMatchResult(theMatchResult);
|
mdmLink.setMatchResult(matchResult);
|
||||||
}
|
}
|
||||||
// Add partition for the mdm link if it doesn't exist
|
// Add partition for the mdm link if it doesn't exist
|
||||||
RequestPartitionId goldenResourcePartitionId =
|
RequestPartitionId goldenResourcePartitionId =
|
||||||
(RequestPartitionId) theGoldenResource.getUserData(Constants.RESOURCE_PARTITION_ID);
|
(RequestPartitionId) goldenResource.getUserData(Constants.RESOURCE_PARTITION_ID);
|
||||||
if (goldenResourcePartitionId != null
|
if (goldenResourcePartitionId != null
|
||||||
&& goldenResourcePartitionId.hasPartitionIds()
|
&& goldenResourcePartitionId.hasPartitionIds()
|
||||||
&& goldenResourcePartitionId.getFirstPartitionIdOrNull() != null
|
&& goldenResourcePartitionId.getFirstPartitionIdOrNull() != null
|
||||||
|
@ -119,11 +133,20 @@ public class MdmLinkCreateSvcImpl implements IMdmLinkCreateSvc {
|
||||||
goldenResourcePartitionId.getFirstPartitionIdOrNull(),
|
goldenResourcePartitionId.getFirstPartitionIdOrNull(),
|
||||||
goldenResourcePartitionId.getPartitionDate()));
|
goldenResourcePartitionId.getPartitionDate()));
|
||||||
}
|
}
|
||||||
ourLog.info("Manually creating a " + theGoldenResource.getIdElement().toVersionless() + " to "
|
ourLog.info("Manually creating a " + goldenResource.getIdElement().toVersionless() + " to "
|
||||||
+ theSourceResource.getIdElement().toVersionless() + " mdm link.");
|
+ sourceResource.getIdElement().toVersionless() + " mdm link.");
|
||||||
myMdmLinkDaoSvc.save(mdmLink);
|
myMdmLinkDaoSvc.save(mdmLink);
|
||||||
|
|
||||||
return theGoldenResource;
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_POST_CREATE_LINK)) {
|
||||||
|
// pointcut for MDM_POST_CREATE_LINK
|
||||||
|
MdmLinkEvent event = new MdmLinkEvent();
|
||||||
|
event.addMdmLink(myModelConverter.toJson(mdmLink));
|
||||||
|
HookParams hookParams = new HookParams();
|
||||||
|
hookParams.add(RequestDetails.class, theParams.getRequestDetails()).add(MdmLinkEvent.class, event);
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_POST_CREATE_LINK, hookParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
return goldenResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateCreateLinkRequest(
|
private void validateCreateLinkRequest(
|
||||||
|
|
|
@ -23,14 +23,14 @@ import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLink;
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
|
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
|
@ -21,6 +21,9 @@ package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
||||||
|
@ -32,11 +35,15 @@ import ca.uhn.fhir.mdm.api.IMdmSurvivorshipService;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.log.Logs;
|
import ca.uhn.fhir.mdm.log.Logs;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmUnduplicateGoldenResourceParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent;
|
||||||
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
||||||
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
||||||
import ca.uhn.fhir.mdm.util.MessageHelper;
|
import ca.uhn.fhir.mdm.util.MessageHelper;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||||
|
@ -56,9 +63,11 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
|
||||||
@Autowired
|
@Autowired
|
||||||
FhirContext myFhirContext;
|
FhirContext myFhirContext;
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Autowired
|
@Autowired
|
||||||
IIdHelperService myIdHelperService;
|
IIdHelperService myIdHelperService;
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Autowired
|
@Autowired
|
||||||
MdmLinkDaoSvc myMdmLinkDaoSvc;
|
MdmLinkDaoSvc myMdmLinkDaoSvc;
|
||||||
|
|
||||||
|
@ -80,52 +89,60 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
|
||||||
@Autowired
|
@Autowired
|
||||||
MdmPartitionHelper myMdmPartitionHelper;
|
MdmPartitionHelper myMdmPartitionHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IMdmModelConverterSvc myModelConverter;
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public IAnyResource updateLink(
|
public IAnyResource updateLink(MdmCreateOrUpdateParams theParams) {
|
||||||
IAnyResource theGoldenResource,
|
IAnyResource sourceResource = theParams.getSourceResource();
|
||||||
IAnyResource theSourceResource,
|
IAnyResource goldenResource = theParams.getGoldenResource();
|
||||||
MdmMatchResultEnum theMatchResult,
|
MdmTransactionContext mdmContext = theParams.getMdmContext();
|
||||||
MdmTransactionContext theMdmContext) {
|
MdmMatchResultEnum matchResult = theParams.getMatchResult();
|
||||||
String sourceType = myFhirContext.getResourceType(theSourceResource);
|
|
||||||
|
|
||||||
validateUpdateLinkRequest(theGoldenResource, theSourceResource, theMatchResult, sourceType);
|
String sourceType = myFhirContext.getResourceType(sourceResource);
|
||||||
|
|
||||||
IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
|
validateUpdateLinkRequest(goldenResource, sourceResource, matchResult, sourceType);
|
||||||
IResourcePersistentId sourceResourceId = myIdHelperService.getPidOrThrowException(theSourceResource);
|
|
||||||
|
IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(goldenResource);
|
||||||
|
IResourcePersistentId sourceResourceId = myIdHelperService.getPidOrThrowException(sourceResource);
|
||||||
|
|
||||||
// check if the golden resource and the source resource are in the same partition if cross partition mdm is not
|
// check if the golden resource and the source resource are in the same partition if cross partition mdm is not
|
||||||
// allowed, throw error if not
|
// allowed, throw error if not
|
||||||
myMdmPartitionHelper.validateMdmResourcesPartitionMatches(theGoldenResource, theSourceResource);
|
myMdmPartitionHelper.validateMdmResourcesPartitionMatches(goldenResource, sourceResource);
|
||||||
|
|
||||||
Optional<? extends IMdmLink> optionalMdmLink =
|
Optional<? extends IMdmLink> optionalMdmLink =
|
||||||
myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, sourceResourceId);
|
myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, sourceResourceId);
|
||||||
if (optionalMdmLink.isEmpty()) {
|
if (optionalMdmLink.isEmpty()) {
|
||||||
throw new InvalidRequestException(
|
throw new InvalidRequestException(
|
||||||
Msg.code(738) + myMessageHelper.getMessageForNoLink(theGoldenResource, theSourceResource));
|
Msg.code(738) + myMessageHelper.getMessageForNoLink(goldenResource, sourceResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
IMdmLink mdmLink = optionalMdmLink.get();
|
IMdmLink mdmLink = optionalMdmLink.get();
|
||||||
|
|
||||||
validateNoMatchPresentWhenAcceptingPossibleMatch(theSourceResource, goldenResourceId, theMatchResult);
|
validateNoMatchPresentWhenAcceptingPossibleMatch(sourceResource, goldenResourceId, matchResult);
|
||||||
|
|
||||||
if (mdmLink.getMatchResult() == theMatchResult) {
|
if (mdmLink.getMatchResult() == matchResult) {
|
||||||
ourLog.warn("MDM Link for " + theGoldenResource.getIdElement().toVersionless() + ", "
|
ourLog.warn("MDM Link for " + goldenResource.getIdElement().toVersionless() + ", "
|
||||||
+ theSourceResource.getIdElement().toVersionless() + " already has value " + theMatchResult
|
+ sourceResource.getIdElement().toVersionless() + " already has value " + matchResult
|
||||||
+ ". Nothing to do.");
|
+ ". Nothing to do.");
|
||||||
return theGoldenResource;
|
return goldenResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Manually updating MDM Link for "
|
ourLog.info("Manually updating MDM Link for "
|
||||||
+ theGoldenResource.getIdElement().toVersionless() + ", "
|
+ goldenResource.getIdElement().toVersionless() + ", "
|
||||||
+ theSourceResource.getIdElement().toVersionless() + " from " + mdmLink.getMatchResult() + " to "
|
+ sourceResource.getIdElement().toVersionless() + " from " + mdmLink.getMatchResult() + " to "
|
||||||
+ theMatchResult + ".");
|
+ matchResult + ".");
|
||||||
mdmLink.setMatchResult(theMatchResult);
|
mdmLink.setMatchResult(matchResult);
|
||||||
mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL);
|
mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL);
|
||||||
|
|
||||||
// Add partition for the mdm link if it doesn't exist
|
// Add partition for the mdm link if it doesn't exist
|
||||||
RequestPartitionId goldenResourcePartitionId =
|
RequestPartitionId goldenResourcePartitionId =
|
||||||
(RequestPartitionId) theGoldenResource.getUserData(Constants.RESOURCE_PARTITION_ID);
|
(RequestPartitionId) goldenResource.getUserData(Constants.RESOURCE_PARTITION_ID);
|
||||||
if (goldenResourcePartitionId != null
|
if (goldenResourcePartitionId != null
|
||||||
&& goldenResourcePartitionId.hasPartitionIds()
|
&& goldenResourcePartitionId.hasPartitionIds()
|
||||||
&& goldenResourcePartitionId.getFirstPartitionIdOrNull() != null
|
&& goldenResourcePartitionId.getFirstPartitionIdOrNull() != null
|
||||||
|
@ -136,29 +153,39 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
|
||||||
}
|
}
|
||||||
myMdmLinkDaoSvc.save(mdmLink);
|
myMdmLinkDaoSvc.save(mdmLink);
|
||||||
|
|
||||||
if (theMatchResult == MdmMatchResultEnum.MATCH) {
|
if (matchResult == MdmMatchResultEnum.MATCH) {
|
||||||
// only apply survivorship rules in case of a match
|
// only apply survivorship rules in case of a match
|
||||||
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(
|
myMdmSurvivorshipService.applySurvivorshipRulesToGoldenResource(sourceResource, goldenResource, mdmContext);
|
||||||
theSourceResource, theGoldenResource, theMdmContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myMdmResourceDaoSvc.upsertGoldenResource(theGoldenResource, theMdmContext.getResourceType());
|
myMdmResourceDaoSvc.upsertGoldenResource(goldenResource, mdmContext.getResourceType());
|
||||||
if (theMatchResult == MdmMatchResultEnum.NO_MATCH) {
|
if (matchResult == MdmMatchResultEnum.NO_MATCH) {
|
||||||
// We need to return no match for when a Golden Resource has already been found elsewhere
|
// We need to return no match for when a Golden Resource has already been found elsewhere
|
||||||
if (myMdmLinkDaoSvc
|
if (myMdmLinkDaoSvc
|
||||||
.getMdmLinksBySourcePidAndMatchResult(sourceResourceId, MdmMatchResultEnum.MATCH)
|
.getMdmLinksBySourcePidAndMatchResult(sourceResourceId, MdmMatchResultEnum.MATCH)
|
||||||
.isEmpty()) {
|
.isEmpty()) {
|
||||||
// Need to find a new Golden Resource to link this target to
|
// Need to find a new Golden Resource to link this target to
|
||||||
myMdmMatchLinkSvc.updateMdmLinksForMdmSource(theSourceResource, theMdmContext);
|
myMdmMatchLinkSvc.updateMdmLinksForMdmSource(sourceResource, mdmContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return theGoldenResource;
|
|
||||||
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_POST_UPDATE_LINK)) {
|
||||||
|
// pointcut for MDM_POST_UPDATE_LINK
|
||||||
|
MdmLinkEvent event = new MdmLinkEvent();
|
||||||
|
event.addMdmLink(myModelConverter.toJson(mdmLink));
|
||||||
|
HookParams hookParams = new HookParams();
|
||||||
|
hookParams.add(RequestDetails.class, theParams.getRequestDetails()).add(MdmLinkEvent.class, event);
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_POST_UPDATE_LINK, hookParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
return goldenResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When updating POSSIBLE_MATCH link to a MATCH we need to validate that a MATCH to a different golden resource
|
* When updating POSSIBLE_MATCH link to a MATCH we need to validate that a MATCH to a different golden resource
|
||||||
* doesn't exist, because a resource mustn't be a MATCH to more than one golden resource
|
* doesn't exist, because a resource mustn't be a MATCH to more than one golden resource
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
private void validateNoMatchPresentWhenAcceptingPossibleMatch(
|
private void validateNoMatchPresentWhenAcceptingPossibleMatch(
|
||||||
IAnyResource theSourceResource,
|
IAnyResource theSourceResource,
|
||||||
IResourcePersistentId theGoldenResourceId,
|
IResourcePersistentId theGoldenResourceId,
|
||||||
|
@ -221,31 +248,45 @@ public class MdmLinkUpdaterSvcImpl implements IMdmLinkUpdaterSvc {
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public void notDuplicateGoldenResource(
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
IAnyResource theGoldenResource, IAnyResource theTargetGoldenResource, MdmTransactionContext theMdmContext) {
|
public void unduplicateGoldenResource(MdmUnduplicateGoldenResourceParams theParams) {
|
||||||
validateNotDuplicateGoldenResourceRequest(theGoldenResource, theTargetGoldenResource);
|
IAnyResource goldenResource = theParams.getGoldenResource();
|
||||||
|
IAnyResource targetGoldenResource = theParams.getTargetGoldenResource();
|
||||||
|
|
||||||
IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(theGoldenResource);
|
validateNotDuplicateGoldenResourceRequest(goldenResource, targetGoldenResource);
|
||||||
IResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(theTargetGoldenResource);
|
|
||||||
|
IResourcePersistentId goldenResourceId = myIdHelperService.getPidOrThrowException(goldenResource);
|
||||||
|
IResourcePersistentId targetId = myIdHelperService.getPidOrThrowException(targetGoldenResource);
|
||||||
|
|
||||||
Optional<? extends IMdmLink> oMdmLink =
|
Optional<? extends IMdmLink> oMdmLink =
|
||||||
myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, targetId);
|
myMdmLinkDaoSvc.getLinkByGoldenResourcePidAndSourceResourcePid(goldenResourceId, targetId);
|
||||||
if (oMdmLink.isEmpty()) {
|
if (oMdmLink.isEmpty()) {
|
||||||
throw new InvalidRequestException(Msg.code(745) + "No link exists between "
|
throw new InvalidRequestException(Msg.code(745) + "No link exists between "
|
||||||
+ theGoldenResource.getIdElement().toVersionless() + " and "
|
+ goldenResource.getIdElement().toVersionless() + " and "
|
||||||
+ theTargetGoldenResource.getIdElement().toVersionless());
|
+ targetGoldenResource.getIdElement().toVersionless());
|
||||||
}
|
}
|
||||||
|
|
||||||
IMdmLink mdmLink = oMdmLink.get();
|
IMdmLink mdmLink = oMdmLink.get();
|
||||||
if (!mdmLink.isPossibleDuplicate()) {
|
if (!mdmLink.isPossibleDuplicate()) {
|
||||||
throw new InvalidRequestException(
|
throw new InvalidRequestException(
|
||||||
Msg.code(746) + theGoldenResource.getIdElement().toVersionless() + " and "
|
Msg.code(746) + goldenResource.getIdElement().toVersionless() + " and "
|
||||||
+ theTargetGoldenResource.getIdElement().toVersionless()
|
+ targetGoldenResource.getIdElement().toVersionless()
|
||||||
+ " are not linked as POSSIBLE_DUPLICATE.");
|
+ " are not linked as POSSIBLE_DUPLICATE.");
|
||||||
}
|
}
|
||||||
mdmLink.setMatchResult(MdmMatchResultEnum.NO_MATCH);
|
mdmLink.setMatchResult(MdmMatchResultEnum.NO_MATCH);
|
||||||
mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL);
|
mdmLink.setLinkSource(MdmLinkSourceEnum.MANUAL);
|
||||||
myMdmLinkDaoSvc.save(mdmLink);
|
IMdmLink retval = myMdmLinkDaoSvc.save(mdmLink);
|
||||||
|
|
||||||
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_POST_NOT_DUPLICATE)) {
|
||||||
|
// MDM_POST_NOT_DUPLICATE hook
|
||||||
|
MdmLinkEvent event = new MdmLinkEvent();
|
||||||
|
event.addMdmLink(myModelConverter.toJson(retval));
|
||||||
|
|
||||||
|
HookParams params = new HookParams();
|
||||||
|
params.add(RequestDetails.class, theParams.getRequestDetails());
|
||||||
|
params.add(MdmLinkEvent.class, event);
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_POST_NOT_DUPLICATE, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,9 +21,9 @@ package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLink;
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
public class MdmModelConverterSvcImpl implements IMdmModelConverterSvc {
|
public class MdmModelConverterSvcImpl implements IMdmModelConverterSvc {
|
||||||
|
|
|
@ -133,7 +133,7 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test {
|
||||||
@Autowired
|
@Autowired
|
||||||
SearchParamRegistryImpl mySearchParamRegistry;
|
SearchParamRegistryImpl mySearchParamRegistry;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
protected IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
@Autowired
|
@Autowired
|
||||||
private DaoRegistry myDaoRegistry;
|
private DaoRegistry myDaoRegistry;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -5,7 +5,7 @@ import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent;
|
||||||
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
||||||
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
||||||
import ca.uhn.test.concurrency.PointcutLatch;
|
import ca.uhn.test.concurrency.PointcutLatch;
|
||||||
|
|
|
@ -4,8 +4,8 @@ import ca.uhn.fhir.jpa.entity.MdmLink;
|
||||||
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
||||||
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
|
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
|
||||||
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
|
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkEvent;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
import ca.uhn.fhir.rest.server.messaging.ResourceOperationMessage;
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.List;
|
||||||
public abstract class BaseProviderR4Test extends BaseMdmR4Test {
|
public abstract class BaseProviderR4Test extends BaseMdmR4Test {
|
||||||
protected MdmProviderDstu3Plus myMdmProvider;
|
protected MdmProviderDstu3Plus myMdmProvider;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IMdmControllerSvc myMdmControllerSvc;
|
protected IMdmControllerSvc myMdmControllerSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IMdmSubmitSvc myMdmSubmitSvc;
|
private IMdmSubmitSvc myMdmSubmitSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -56,7 +56,12 @@ public abstract class BaseProviderR4Test extends BaseMdmR4Test {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void before() throws Exception {
|
public void before() throws Exception {
|
||||||
myMdmProvider = new MdmProviderDstu3Plus(myFhirContext, myMdmControllerSvc, myMdmHelper, myMdmSubmitSvc, myMdmSettings);
|
myMdmProvider = new MdmProviderDstu3Plus(myFhirContext,
|
||||||
|
myMdmControllerSvc,
|
||||||
|
myMdmHelper,
|
||||||
|
myMdmSubmitSvc,
|
||||||
|
myInterceptorBroadcaster,
|
||||||
|
myMdmSettings);
|
||||||
defaultScript = myMdmSettings.getScriptText();
|
defaultScript = myMdmSettings.getScriptText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,602 @@
|
||||||
|
package ca.uhn.fhir.jpa.mdm.provider;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.batch2.api.IJobCoordinator;
|
||||||
|
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Hook;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
|
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
|
||||||
|
import ca.uhn.fhir.jpa.entity.MdmLink;
|
||||||
|
import ca.uhn.fhir.jpa.mdm.helper.MdmLinkHelper;
|
||||||
|
import ca.uhn.fhir.jpa.mdm.helper.testmodels.MDMState;
|
||||||
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
|
import ca.uhn.fhir.mdm.api.IMdmSubmitSvc;
|
||||||
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmClearEvent;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmHistoryEvent;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkEvent;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmMergeEvent;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmSubmitEvent;
|
||||||
|
import ca.uhn.fhir.mdm.provider.MdmLinkHistoryProviderDstu3Plus;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
|
import ca.uhn.test.concurrency.PointcutLatch;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.Practitioner;
|
||||||
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
|
public class MdmOperationPointcutsIT extends BaseProviderR4Test {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mdm link history can submit by
|
||||||
|
* sourceids, goldenids, or both.
|
||||||
|
* We will use this enum in the MDM_LINK_HISTORY pointcut
|
||||||
|
* test.
|
||||||
|
*/
|
||||||
|
private enum LinkHistoryParameters {
|
||||||
|
SOURCE_IDS,
|
||||||
|
GOLDEN_IDS,
|
||||||
|
BOTH
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There are multiple way to do an $mdm-submit batch job.
|
||||||
|
* This enum tracks the various ways.
|
||||||
|
* All of them should hit our interceptor.
|
||||||
|
*/
|
||||||
|
private enum MdmSubmitEndpoint {
|
||||||
|
PATIENT_INSTANCE(false,false),
|
||||||
|
PATIENT_TYPE(true, true, false),
|
||||||
|
PRACTITIONER_INSTANCE(false, false),
|
||||||
|
PRACTITIONER_TYPE(true, true, false),
|
||||||
|
RANDOM_MDM_RESOURCE(true, false),
|
||||||
|
ALL_RESOURCES(true, false);
|
||||||
|
|
||||||
|
private final boolean[] myAsyncOptions;
|
||||||
|
|
||||||
|
private final boolean myTakesCriteria;
|
||||||
|
|
||||||
|
MdmSubmitEndpoint(boolean theHasCriteria, boolean... theOptions) {
|
||||||
|
myTakesCriteria = theHasCriteria;
|
||||||
|
myAsyncOptions = theOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean[] getAsyncOptions() {
|
||||||
|
return myAsyncOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canTakeCriteria() {
|
||||||
|
return myTakesCriteria;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(MdmOperationPointcutsIT.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MdmLinkHelper myMdmLinkHelper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IInterceptorService myInterceptorService;
|
||||||
|
|
||||||
|
@SpyBean
|
||||||
|
private IJobCoordinator myJobCoordinator;
|
||||||
|
|
||||||
|
@SpyBean
|
||||||
|
private IMdmSubmitSvc myMdmSubmitSvc;
|
||||||
|
|
||||||
|
private MdmLinkHistoryProviderDstu3Plus myLinkHistoryProvider;
|
||||||
|
|
||||||
|
private final List<Object> myInterceptors = new ArrayList<>();
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void before() throws Exception {
|
||||||
|
super.before();
|
||||||
|
|
||||||
|
myLinkHistoryProvider = new MdmLinkHistoryProviderDstu3Plus(
|
||||||
|
myFhirContext,
|
||||||
|
myMdmControllerSvc,
|
||||||
|
myInterceptorBroadcaster
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void after() throws IOException {
|
||||||
|
super.after();
|
||||||
|
myInterceptorService.unregisterInterceptors(myInterceptors);
|
||||||
|
myInterceptors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class MdmProviderDstu3PlusTest {
|
||||||
|
@Test
|
||||||
|
public void mergeGoldenResources_withInterceptor_firesHook() {
|
||||||
|
// setup
|
||||||
|
AtomicBoolean called = new AtomicBoolean(false);
|
||||||
|
String inputState = """
|
||||||
|
GP1, AUTO, POSSIBLE_DUPLICATE, GP2
|
||||||
|
""";
|
||||||
|
MDMState<Patient, JpaPid> state = new MDMState<>();
|
||||||
|
state.setInputState(inputState);
|
||||||
|
|
||||||
|
// we won't use for validation, just setup
|
||||||
|
myMdmLinkHelper.setup(state);
|
||||||
|
|
||||||
|
Patient gp1 = state.getParameter("GP1");
|
||||||
|
Patient gp2 = state.getParameter("GP2");
|
||||||
|
|
||||||
|
Object intereptor = new Object() {
|
||||||
|
@Hook(Pointcut.MDM_POST_MERGE_GOLDEN_RESOURCES)
|
||||||
|
void onUpdate(RequestDetails theDetails, MdmMergeEvent theEvent) {
|
||||||
|
called.getAndSet(true);
|
||||||
|
assertEquals("Patient/" + gp1.getIdPart(), theEvent.getFromResource().getId());
|
||||||
|
assertEquals("Patient/" + gp2.getIdPart(), theEvent.getToResource().getId());
|
||||||
|
assertTrue(theEvent.getFromResource().isGoldenResource() && theEvent.getToResource().isGoldenResource());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myInterceptors.add(intereptor);
|
||||||
|
myInterceptorService.registerInterceptor(intereptor);
|
||||||
|
|
||||||
|
// test
|
||||||
|
myMdmProvider.mergeGoldenResources(
|
||||||
|
new StringType(gp1.getId()), // from
|
||||||
|
new StringType(gp2.getId()), // to
|
||||||
|
null, // merged resource
|
||||||
|
new SystemRequestDetails() // request details
|
||||||
|
);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertTrue(called.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mdmUpdate_withInterceptor_firesHook() {
|
||||||
|
// setup
|
||||||
|
Patient p1 = createPatient();
|
||||||
|
Patient gp1 = createGoldenPatient();
|
||||||
|
MdmLink link = (MdmLink) myMdmLinkDaoSvc.newMdmLink();
|
||||||
|
link.setLinkSource(MdmLinkSourceEnum.AUTO);
|
||||||
|
link.setMatchResult(MdmMatchResultEnum.POSSIBLE_MATCH);
|
||||||
|
link.setCreated(new Date());
|
||||||
|
link.setGoldenResourcePersistenceId(runInTransaction(() -> myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), gp1)));
|
||||||
|
link.setSourcePersistenceId(runInTransaction(() -> myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), p1)));
|
||||||
|
myMdmLinkDaoSvc.save(link);
|
||||||
|
|
||||||
|
MdmMatchResultEnum toSave = MdmMatchResultEnum.MATCH;
|
||||||
|
AtomicBoolean called = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
Object intereptor = new Object() {
|
||||||
|
@Hook(Pointcut.MDM_POST_UPDATE_LINK)
|
||||||
|
void onUpdate(RequestDetails theDetails, MdmLinkEvent theEvent) {
|
||||||
|
called.getAndSet(true);
|
||||||
|
assertEquals(1, theEvent.getMdmLinks().size());
|
||||||
|
MdmLinkJson link = theEvent.getMdmLinks().get(0);
|
||||||
|
assertEquals(toSave, link.getMatchResult());
|
||||||
|
assertEquals("Patient/" + p1.getIdPart(), link.getSourceId());
|
||||||
|
assertEquals("Patient/" + gp1.getIdPart(), link.getGoldenResourceId());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myInterceptors.add(intereptor);
|
||||||
|
myInterceptorService.registerInterceptor(intereptor);
|
||||||
|
|
||||||
|
// test
|
||||||
|
myMdmProvider.updateLink(
|
||||||
|
new StringType(gp1.getId()), // golden resource id
|
||||||
|
new StringType(p1.getId()), // resource id
|
||||||
|
new StringType(toSave.name()), // link type
|
||||||
|
new ServletRequestDetails() // request details
|
||||||
|
);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertTrue(called.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createLink_withInterceptor_firesHook() {
|
||||||
|
// setup
|
||||||
|
AtomicBoolean called = new AtomicBoolean(false);
|
||||||
|
Patient patient = createPatient();
|
||||||
|
Patient golden = createGoldenPatient();
|
||||||
|
MdmMatchResultEnum match = MdmMatchResultEnum.MATCH;
|
||||||
|
|
||||||
|
Object intereptor = new Object() {
|
||||||
|
@Hook(Pointcut.MDM_POST_CREATE_LINK)
|
||||||
|
void onCreate(RequestDetails theDetails, MdmLinkEvent theEvent) {
|
||||||
|
called.getAndSet(true);
|
||||||
|
assertEquals(1, theEvent.getMdmLinks().size());
|
||||||
|
MdmLinkJson link = theEvent.getMdmLinks().get(0);
|
||||||
|
assertEquals(match, link.getMatchResult());
|
||||||
|
assertEquals("Patient/" + patient.getIdPart(), link.getSourceId());
|
||||||
|
assertEquals("Patient/" + golden.getIdPart(), link.getGoldenResourceId());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myInterceptors.add(intereptor);
|
||||||
|
myInterceptorService.registerInterceptor(intereptor);
|
||||||
|
|
||||||
|
// test
|
||||||
|
myMdmProvider.createLink(
|
||||||
|
new StringType(golden.getId()),
|
||||||
|
new StringType(patient.getId()),
|
||||||
|
new StringType(match.name()),
|
||||||
|
new ServletRequestDetails()
|
||||||
|
);
|
||||||
|
|
||||||
|
// validation
|
||||||
|
assertTrue(called.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void notDuplicate_withInterceptor_firesHook() {
|
||||||
|
// setup
|
||||||
|
AtomicBoolean called = new AtomicBoolean();
|
||||||
|
String initialState = """
|
||||||
|
GP1, AUTO, POSSIBLE_DUPLICATE, GP2
|
||||||
|
""";
|
||||||
|
MDMState<Patient, JpaPid> state = new MDMState<>();
|
||||||
|
state.setInputState(initialState);
|
||||||
|
|
||||||
|
// we won't use for validation, just setup
|
||||||
|
myMdmLinkHelper.setup(state);
|
||||||
|
|
||||||
|
Patient gp1 = state.getParameter("GP1");
|
||||||
|
Patient gp2 = state.getParameter("GP2");
|
||||||
|
|
||||||
|
// interceptor
|
||||||
|
Object interceptor = new Object() {
|
||||||
|
@Hook(Pointcut.MDM_POST_NOT_DUPLICATE)
|
||||||
|
void call(RequestDetails theRequestDetails, MdmLinkEvent theEvent) {
|
||||||
|
called.getAndSet(true);
|
||||||
|
|
||||||
|
assertEquals(1, theEvent.getMdmLinks().size());
|
||||||
|
MdmLinkJson link = theEvent.getMdmLinks().get(0);
|
||||||
|
assertEquals("Patient/" + gp2.getIdPart(), link.getSourceId());
|
||||||
|
assertEquals("Patient/" + gp1.getIdPart(), link.getGoldenResourceId());
|
||||||
|
assertEquals(MdmMatchResultEnum.NO_MATCH, link.getMatchResult());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myInterceptors.add(interceptor);
|
||||||
|
myInterceptorRegistry.registerInterceptor(interceptor);
|
||||||
|
|
||||||
|
// test
|
||||||
|
myMdmProvider.notDuplicate(
|
||||||
|
new StringType(gp1.getId()),
|
||||||
|
new StringType(gp2.getId()),
|
||||||
|
new ServletRequestDetails()
|
||||||
|
);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertTrue(called.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {
|
||||||
|
"Patient,Practitioner,Medication",
|
||||||
|
"Patient",
|
||||||
|
""
|
||||||
|
})
|
||||||
|
public void clearMdmLinks_withHook_firesInterceptor(String theResourceTypes) {
|
||||||
|
// setup
|
||||||
|
AtomicBoolean called = new AtomicBoolean();
|
||||||
|
Batch2JobStartResponse response = new Batch2JobStartResponse();
|
||||||
|
response.setInstanceId("test");
|
||||||
|
|
||||||
|
List<IPrimitiveType<String>> resourceTypes = new ArrayList<>();
|
||||||
|
if (isNotBlank(theResourceTypes)) {
|
||||||
|
String[] rts = theResourceTypes.split(",");
|
||||||
|
for (String rt : rts) {
|
||||||
|
resourceTypes.add(new StringType(rt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
// we don't care to actually submit the job, so we'll mock it here
|
||||||
|
doReturn(response)
|
||||||
|
.when(myJobCoordinator).startInstance(any(RequestDetails.class), any(JobInstanceStartRequest.class));
|
||||||
|
|
||||||
|
// interceptor
|
||||||
|
Object interceptor = new Object() {
|
||||||
|
@Hook(Pointcut.MDM_CLEAR)
|
||||||
|
void call(RequestDetails theRequestDetails, MdmClearEvent theEvent) {
|
||||||
|
called.set(true);
|
||||||
|
|
||||||
|
assertNotNull(theEvent.getResourceTypes());
|
||||||
|
if (isNotBlank(theResourceTypes)) {
|
||||||
|
assertEquals(resourceTypes.size(), theEvent.getResourceTypes().size());
|
||||||
|
|
||||||
|
for (IPrimitiveType<String> resourceName : resourceTypes) {
|
||||||
|
assertTrue(theEvent.getResourceTypes()
|
||||||
|
.contains(resourceName.getValueAsString()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// null or empty resource types means all
|
||||||
|
// mdm resource types
|
||||||
|
myMdmSettings.getMdmRules()
|
||||||
|
.getMdmTypes().forEach(rtype -> {
|
||||||
|
assertTrue(theEvent.getResourceTypes().contains(rtype));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myInterceptors.add(interceptor);
|
||||||
|
myInterceptorRegistry.registerInterceptor(interceptor);
|
||||||
|
|
||||||
|
// test
|
||||||
|
myMdmProvider.clearMdmLinks(
|
||||||
|
resourceTypes, // resource type filter
|
||||||
|
null, // batchsize
|
||||||
|
new ServletRequestDetails()
|
||||||
|
);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertTrue(called.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnumSource(MdmSubmitEndpoint.class)
|
||||||
|
public void mdmSubmit_interceptor_differentPaths(MdmSubmitEndpoint theMdmSubmitEndpoint) throws InterruptedException {
|
||||||
|
// setup
|
||||||
|
AtomicBoolean called = new AtomicBoolean();
|
||||||
|
Batch2JobStartResponse res = new Batch2JobStartResponse();
|
||||||
|
res.setInstanceId("test");
|
||||||
|
List<String> urls = new ArrayList<>();
|
||||||
|
boolean[] asyncValue = new boolean[1];
|
||||||
|
PointcutLatch latch = new PointcutLatch(theMdmSubmitEndpoint.name());
|
||||||
|
|
||||||
|
// when
|
||||||
|
// we don't actually want to start batch jobs, so we'll mock it
|
||||||
|
doReturn(res)
|
||||||
|
.when(myJobCoordinator).startInstance(any(RequestDetails.class), any(JobInstanceStartRequest.class));
|
||||||
|
doReturn(1L)
|
||||||
|
.when(myMdmSubmitSvc).submitSourceResourceTypeToMdm(anyString(), any(), any(RequestDetails.class));
|
||||||
|
|
||||||
|
// use identifier because it's on almost every resource type
|
||||||
|
StringType[] criteria = theMdmSubmitEndpoint.canTakeCriteria() ?
|
||||||
|
new StringType[] { new StringType("identifier=true"), null }
|
||||||
|
: new StringType[] { null };
|
||||||
|
ServletRequestDetails request = new ServletRequestDetails();
|
||||||
|
|
||||||
|
// register an interceptor
|
||||||
|
Object interceptor = new Object() {
|
||||||
|
@Hook(Pointcut.MDM_SUBMIT)
|
||||||
|
void call(RequestDetails theRequestDetails, MdmSubmitEvent theEvent) {
|
||||||
|
called.set(true);
|
||||||
|
|
||||||
|
assertEquals(asyncValue[0], theEvent.isBatchJob());
|
||||||
|
|
||||||
|
String urlStr = String.join(", ", urls);
|
||||||
|
assertEquals(urls.size(), theEvent.getUrls().size(),
|
||||||
|
urlStr + " <-> " + String.join(", ", theEvent.getUrls()));
|
||||||
|
for (String url : urls) {
|
||||||
|
assertTrue(theEvent.getUrls().contains(url), "[" + urlStr + "] does not contain " + url + ".");
|
||||||
|
}
|
||||||
|
latch.call(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myInterceptors.add(interceptor);
|
||||||
|
myInterceptorRegistry.registerInterceptor(interceptor);
|
||||||
|
|
||||||
|
for (StringType criterion : criteria) {
|
||||||
|
for (boolean respondAsync : theMdmSubmitEndpoint.getAsyncOptions()) {
|
||||||
|
ourLog.info("\nRunning test for {}; async: {}", theMdmSubmitEndpoint.name(), respondAsync);
|
||||||
|
|
||||||
|
// reset
|
||||||
|
asyncValue[0] = respondAsync;
|
||||||
|
called.set(false);
|
||||||
|
urls.clear();
|
||||||
|
|
||||||
|
ServletRequestDetails req = spy(request);
|
||||||
|
doReturn(respondAsync).when(req).isPreferRespondAsync();
|
||||||
|
|
||||||
|
// test
|
||||||
|
latch.setExpectedCount(1);
|
||||||
|
switch (theMdmSubmitEndpoint) {
|
||||||
|
case PATIENT_INSTANCE:
|
||||||
|
// patient must exist to do the mdm submit
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setActive(true);
|
||||||
|
p.addName()
|
||||||
|
.setFamily("Simpson")
|
||||||
|
.addGiven("Homer");
|
||||||
|
long patientId = myPatientDao.create(p)
|
||||||
|
.getId().getIdPartAsLong();
|
||||||
|
|
||||||
|
IdType patientIdType = new IdType("Patient/" + patientId);
|
||||||
|
|
||||||
|
urls.add(patientIdType.getValue());
|
||||||
|
|
||||||
|
myMdmProvider.mdmBatchPatientInstance(
|
||||||
|
patientIdType,
|
||||||
|
req
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case PATIENT_TYPE:
|
||||||
|
if (respondAsync) {
|
||||||
|
urls.add("Patient?");
|
||||||
|
} else {
|
||||||
|
urls.add(createUrl("Patient", criterion));
|
||||||
|
}
|
||||||
|
|
||||||
|
myMdmProvider.mdmBatchPatientType(
|
||||||
|
criterion, // criteria
|
||||||
|
null, // batch size
|
||||||
|
req // request
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case PRACTITIONER_INSTANCE:
|
||||||
|
// practitioner must exist to do mdm submit
|
||||||
|
Practitioner practitioner = new Practitioner();
|
||||||
|
practitioner.setActive(true);
|
||||||
|
practitioner.addName()
|
||||||
|
.setFamily("Hibbert")
|
||||||
|
.addGiven("Julius");
|
||||||
|
long practitionerId = myPractitionerDao.create(practitioner)
|
||||||
|
.getId().getIdPartAsLong();
|
||||||
|
IdType practitionerIdType = new IdType("Practitioner/" + practitionerId);
|
||||||
|
|
||||||
|
urls.add(practitionerIdType.getValue());
|
||||||
|
|
||||||
|
myMdmProvider.mdmBatchPractitionerInstance(
|
||||||
|
practitionerIdType,
|
||||||
|
req
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case PRACTITIONER_TYPE:
|
||||||
|
if (respondAsync) {
|
||||||
|
urls.add("Practitioner?");
|
||||||
|
} else {
|
||||||
|
urls.add(createUrl("Practitioner", criterion));
|
||||||
|
}
|
||||||
|
|
||||||
|
myMdmProvider.mdmBatchPractitionerType(
|
||||||
|
criterion, // criteria
|
||||||
|
null, // batchsize
|
||||||
|
req // request
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case RANDOM_MDM_RESOURCE:
|
||||||
|
// these tests use the mdm rules in:
|
||||||
|
// resources/mdm/mdm-rules.json
|
||||||
|
// Medication is one of the allowable mdm types
|
||||||
|
String resourceType = "Medication";
|
||||||
|
urls.add(createUrl(resourceType, criterion));
|
||||||
|
myMdmProvider.mdmBatchOnAllSourceResources(
|
||||||
|
new StringType(resourceType),
|
||||||
|
criterion,
|
||||||
|
null,
|
||||||
|
req
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ALL_RESOURCES:
|
||||||
|
myMdmSettings.getMdmRules()
|
||||||
|
.getMdmTypes().forEach(rtype -> {
|
||||||
|
urls.add(createUrl(rtype, criterion));
|
||||||
|
});
|
||||||
|
|
||||||
|
myMdmProvider.mdmBatchOnAllSourceResources(
|
||||||
|
null, // resource type (null is all)
|
||||||
|
criterion, // criteria
|
||||||
|
null, // batchsize
|
||||||
|
req
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify
|
||||||
|
latch.awaitExpected();
|
||||||
|
assertTrue(called.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createUrl(String theResourceType, StringType theCriteria) {
|
||||||
|
String url = theResourceType;
|
||||||
|
if (theCriteria != null) {
|
||||||
|
url += "?" + theCriteria.getValueAsString();
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class MdmLinkHistoryProviderDstu3PlusTest {
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnumSource(LinkHistoryParameters.class)
|
||||||
|
public void historyLinks_withPointcut_firesHook(LinkHistoryParameters theParametersToSend) {
|
||||||
|
// setup
|
||||||
|
AtomicBoolean called = new AtomicBoolean();
|
||||||
|
|
||||||
|
List<IPrimitiveType<String>> sourceIds = new ArrayList<>();
|
||||||
|
List<IPrimitiveType<String>> goldenResourceIds = new ArrayList<>();
|
||||||
|
|
||||||
|
Patient p1 = createPatient();
|
||||||
|
sourceIds.add(new StringType("Patient/" + p1.getIdPart()));
|
||||||
|
Patient gp1 = createGoldenPatient();
|
||||||
|
goldenResourceIds.add(new StringType("Patient/" + gp1.getIdPart()));
|
||||||
|
MdmLink link = (MdmLink) myMdmLinkDaoSvc.newMdmLink();
|
||||||
|
link.setLinkSource(MdmLinkSourceEnum.AUTO);
|
||||||
|
link.setMatchResult(MdmMatchResultEnum.POSSIBLE_MATCH);
|
||||||
|
link.setCreated(new Date());
|
||||||
|
link.setGoldenResourcePersistenceId(runInTransaction(() -> myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), gp1)));
|
||||||
|
link.setSourcePersistenceId(runInTransaction(() -> myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), p1)));
|
||||||
|
myMdmLinkDaoSvc.save(link);
|
||||||
|
|
||||||
|
// save a change
|
||||||
|
link.setMatchResult(MdmMatchResultEnum.MATCH);
|
||||||
|
myMdmLinkDaoSvc.save(link);
|
||||||
|
|
||||||
|
// interceptor
|
||||||
|
Object interceptor = new Object() {
|
||||||
|
@Hook(Pointcut.MDM_POST_LINK_HISTORY)
|
||||||
|
void onHistory(RequestDetails theRequestDetails, MdmHistoryEvent theEvent) {
|
||||||
|
called.getAndSet(true);
|
||||||
|
|
||||||
|
List<MdmLinkWithRevisionJson> history = theEvent.getMdmLinkRevisions();
|
||||||
|
List<String> gids = theEvent.getGoldenResourceIds();
|
||||||
|
List<String> sids = theEvent.getSourceIds();
|
||||||
|
|
||||||
|
if (theParametersToSend == LinkHistoryParameters.SOURCE_IDS) {
|
||||||
|
assertTrue(gids.isEmpty());
|
||||||
|
} else if (theParametersToSend == LinkHistoryParameters.GOLDEN_IDS) {
|
||||||
|
assertTrue(sids.isEmpty());
|
||||||
|
} else {
|
||||||
|
assertFalse(sids.isEmpty() && gids.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertFalse(history.isEmpty());
|
||||||
|
assertEquals(2, history.size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myInterceptors.add(interceptor);
|
||||||
|
myInterceptorRegistry.registerInterceptor(interceptor);
|
||||||
|
|
||||||
|
// test
|
||||||
|
List<IPrimitiveType<String>> sourceIdsToSend = theParametersToSend != LinkHistoryParameters.GOLDEN_IDS ? sourceIds : new ArrayList<>();
|
||||||
|
List<IPrimitiveType<String>> goldenIdsToSend = theParametersToSend != LinkHistoryParameters.SOURCE_IDS ? goldenResourceIds : new ArrayList<>();
|
||||||
|
IBaseParameters retval = myLinkHistoryProvider.historyLinks(
|
||||||
|
goldenIdsToSend,
|
||||||
|
sourceIdsToSend,
|
||||||
|
new ServletRequestDetails()
|
||||||
|
);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertTrue(called.get());
|
||||||
|
assertFalse(retval.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import ca.uhn.fhir.jpa.mdm.provider.BaseLinkR4Test;
|
||||||
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
|
||||||
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
|
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
||||||
|
|
|
@ -13,7 +13,9 @@ import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.interceptor.IMdmStorageInterceptor;
|
import ca.uhn.fhir.mdm.interceptor.IMdmStorageInterceptor;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmMergeGoldenResourcesParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
@ -107,11 +109,15 @@ public class MdmGoldenResourceMergerSvcTest extends BaseMdmR4Test {
|
||||||
assertEquals(0, redirectLinkCount());
|
assertEquals(0, redirectLinkCount());
|
||||||
Patient from = theFlipToAndFromGoldenResources ? myToGoldenPatient : myFromGoldenPatient;
|
Patient from = theFlipToAndFromGoldenResources ? myToGoldenPatient : myFromGoldenPatient;
|
||||||
Patient to = theFlipToAndFromGoldenResources ? myFromGoldenPatient : myToGoldenPatient;
|
Patient to = theFlipToAndFromGoldenResources ? myFromGoldenPatient : myToGoldenPatient;
|
||||||
|
|
||||||
|
MdmMergeGoldenResourcesParams params = new MdmMergeGoldenResourcesParams();
|
||||||
|
params.setFromGoldenResource(from);
|
||||||
|
params.setToGoldenResource(to);
|
||||||
|
params.setMdmTransactionContext(createMdmContext());
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
|
|
||||||
Patient retval = (Patient) myGoldenResourceMergerSvc.mergeGoldenResources(
|
Patient retval = (Patient) myGoldenResourceMergerSvc.mergeGoldenResources(
|
||||||
from,
|
params
|
||||||
null,
|
|
||||||
to,
|
|
||||||
createMdmContext()
|
|
||||||
);
|
);
|
||||||
assertEquals(1, redirectLinkCount());
|
assertEquals(1, redirectLinkCount());
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -214,8 +220,15 @@ public class MdmGoldenResourceMergerSvcTest extends BaseMdmR4Test {
|
||||||
|
|
||||||
MdmTransactionContext ctx = createMdmContext();
|
MdmTransactionContext ctx = createMdmContext();
|
||||||
ctx.setRestOperation(MdmTransactionContext.OperationType.MANUAL_MERGE_GOLDEN_RESOURCES);
|
ctx.setRestOperation(MdmTransactionContext.OperationType.MANUAL_MERGE_GOLDEN_RESOURCES);
|
||||||
|
|
||||||
|
MdmMergeGoldenResourcesParams params = new MdmMergeGoldenResourcesParams();
|
||||||
|
params.setFromGoldenResource(myFromGoldenPatient);
|
||||||
|
params.setManuallyMergedResource(manuallyMergedPatient);
|
||||||
|
params.setToGoldenResource(myToGoldenPatient);
|
||||||
|
params.setMdmTransactionContext(ctx);
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
Patient mergedSourcePatient = (Patient) myGoldenResourceMergerSvc
|
Patient mergedSourcePatient = (Patient) myGoldenResourceMergerSvc
|
||||||
.mergeGoldenResources(myFromGoldenPatient, manuallyMergedPatient, myToGoldenPatient, ctx);
|
.mergeGoldenResources(params);
|
||||||
|
|
||||||
HumanName returnedName = mergedSourcePatient.getNameFirstRep();
|
HumanName returnedName = mergedSourcePatient.getNameFirstRep();
|
||||||
assertEquals("TestGiven TestFamily", returnedName.getNameAsSingleString());
|
assertEquals("TestGiven TestFamily", returnedName.getNameAsSingleString());
|
||||||
|
@ -243,11 +256,13 @@ public class MdmGoldenResourceMergerSvcTest extends BaseMdmR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Patient mergeGoldenResources(Patient theFrom, Patient theTo) {
|
private Patient mergeGoldenResources(Patient theFrom, Patient theTo) {
|
||||||
|
MdmMergeGoldenResourcesParams params = new MdmMergeGoldenResourcesParams();
|
||||||
|
params.setFromGoldenResource(theFrom);
|
||||||
|
params.setToGoldenResource(theTo);
|
||||||
|
params.setMdmTransactionContext(createMdmContext());
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
Patient retval = (Patient) myGoldenResourceMergerSvc.mergeGoldenResources(
|
Patient retval = (Patient) myGoldenResourceMergerSvc.mergeGoldenResources(
|
||||||
theFrom,
|
params
|
||||||
null,
|
|
||||||
theTo,
|
|
||||||
createMdmContext()
|
|
||||||
);
|
);
|
||||||
assertEquals(1, redirectLinkCount());
|
assertEquals(1, redirectLinkCount());
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
package ca.uhn.fhir.jpa.mdm.svc;
|
package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
||||||
import ca.uhn.fhir.jpa.entity.MdmLink;
|
import ca.uhn.fhir.jpa.entity.MdmLink;
|
||||||
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
import ca.uhn.fhir.jpa.mdm.dao.MdmLinkDaoSvc;
|
||||||
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
|
||||||
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
import ca.uhn.fhir.jpa.model.dao.JpaPid;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLink;
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.util.MdmPartitionHelper;
|
||||||
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
||||||
import ca.uhn.fhir.mdm.util.MessageHelper;
|
import ca.uhn.fhir.mdm.util.MessageHelper;
|
||||||
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.BaseResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.BaseResourcePersistentId;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -36,8 +39,10 @@ class MdmLinkCreateSvcImplTest {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Spy
|
@Spy
|
||||||
FhirContext myFhirContext = FhirContext.forR4();
|
FhirContext myFhirContext = FhirContext.forR4();
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Mock
|
@Mock
|
||||||
IIdHelperService myIdHelperService;
|
IIdHelperService myIdHelperService;
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Mock
|
@Mock
|
||||||
MdmLinkDaoSvc myMdmLinkDaoSvc;
|
MdmLinkDaoSvc myMdmLinkDaoSvc;
|
||||||
@Mock
|
@Mock
|
||||||
|
@ -47,9 +52,16 @@ class MdmLinkCreateSvcImplTest {
|
||||||
@Mock
|
@Mock
|
||||||
MdmPartitionHelper myMdmPartitionHelper;
|
MdmPartitionHelper myMdmPartitionHelper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
IMdmModelConverterSvc myIMdmModelConverterSvc;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
MdmLinkCreateSvcImpl myMdmLinkCreateSvc = new MdmLinkCreateSvcImpl();
|
MdmLinkCreateSvcImpl myMdmLinkCreateSvc = new MdmLinkCreateSvcImpl();
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLink() {
|
public void testCreateLink() {
|
||||||
ArgumentCaptor<IMdmLink> mdmLinkCaptor = ArgumentCaptor.forClass(IMdmLink.class);
|
ArgumentCaptor<IMdmLink> mdmLinkCaptor = ArgumentCaptor.forClass(IMdmLink.class);
|
||||||
|
@ -63,7 +75,13 @@ class MdmLinkCreateSvcImplTest {
|
||||||
Patient sourcePatient = new Patient();
|
Patient sourcePatient = new Patient();
|
||||||
MdmTransactionContext ctx = new MdmTransactionContext();
|
MdmTransactionContext ctx = new MdmTransactionContext();
|
||||||
|
|
||||||
myMdmLinkCreateSvc.createLink(goldenPatient, sourcePatient, MdmMatchResultEnum.MATCH, ctx);
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
|
params.setGoldenResource(goldenPatient);
|
||||||
|
params.setSourceResource(sourcePatient);
|
||||||
|
params.setMatchResult(MdmMatchResultEnum.MATCH);
|
||||||
|
params.setMdmContext(ctx);
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
|
myMdmLinkCreateSvc.createLink(params);
|
||||||
|
|
||||||
IMdmLink mdmLink = mdmLinkCaptor.getValue();
|
IMdmLink mdmLink = mdmLinkCaptor.getValue();
|
||||||
|
|
||||||
|
@ -72,6 +90,7 @@ class MdmLinkCreateSvcImplTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
JpaPid goldenId = JpaPid.fromId(1L);
|
JpaPid goldenId = JpaPid.fromId(1L);
|
||||||
|
|
|
@ -6,8 +6,8 @@ import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
|
import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -3,14 +3,13 @@ package ca.uhn.fhir.jpa.mdm.svc;
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
||||||
import ca.uhn.fhir.jpa.mdm.helper.MdmLinkHelper;
|
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLink;
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc;
|
import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
import ca.uhn.fhir.mdm.rules.json.MdmRulesJson;
|
|
||||||
import ca.uhn.fhir.mdm.util.MessageHelper;
|
import ca.uhn.fhir.mdm.util.MessageHelper;
|
||||||
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
@ -18,10 +17,8 @@ import org.hl7.fhir.r4.model.Patient;
|
||||||
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.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -63,12 +60,21 @@ class MdmLinkUpdaterSvcImplIT extends BaseMdmR4Test {
|
||||||
Patient patientC = createPatientFromJsonInputFileWithPossibleMatches( List.of(goldenA, goldenB) );
|
Patient patientC = createPatientFromJsonInputFileWithPossibleMatches( List.of(goldenA, goldenB) );
|
||||||
|
|
||||||
MdmTransactionContext mdmTransactionContext = getPatientUpdateLinkContext();
|
MdmTransactionContext mdmTransactionContext = getPatientUpdateLinkContext();
|
||||||
// update POSSIBLE_MATCH Patient C -> GR A to MATCH (should work OK)
|
|
||||||
myMdmLinkUpdaterSvc.updateLink(goldenA, patientC, MdmMatchResultEnum.MATCH, mdmTransactionContext);
|
|
||||||
|
|
||||||
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
|
params.setMdmContext(mdmTransactionContext);
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
|
params.setGoldenResource(goldenA);
|
||||||
|
params.setSourceResource(patientC);
|
||||||
|
params.setMatchResult(MdmMatchResultEnum.MATCH);
|
||||||
|
|
||||||
|
// update POSSIBLE_MATCH Patient C -> GR A to MATCH (should work OK)
|
||||||
|
myMdmLinkUpdaterSvc.updateLink(params);
|
||||||
|
|
||||||
|
params.setGoldenResource(goldenB);
|
||||||
// update POSSIBLE_MATCH Patient C -> GR B to MATCH (should throw exception)
|
// update POSSIBLE_MATCH Patient C -> GR B to MATCH (should throw exception)
|
||||||
InvalidRequestException thrown = assertThrows(InvalidRequestException.class,
|
InvalidRequestException thrown = assertThrows(InvalidRequestException.class,
|
||||||
() -> myMdmLinkUpdaterSvc.updateLink(goldenB, patientC, MdmMatchResultEnum.MATCH, mdmTransactionContext));
|
() -> myMdmLinkUpdaterSvc.updateLink(params));
|
||||||
|
|
||||||
String expectedExceptionMessage = Msg.code(2218) + myMessageHelper.getMessageForAlreadyAcceptedLink(goldenA, patientC);
|
String expectedExceptionMessage = Msg.code(2218) + myMessageHelper.getMessageForAlreadyAcceptedLink(goldenA, patientC);
|
||||||
assertEquals(expectedExceptionMessage, thrown.getMessage());
|
assertEquals(expectedExceptionMessage, thrown.getMessage());
|
||||||
|
@ -88,11 +94,21 @@ class MdmLinkUpdaterSvcImplIT extends BaseMdmR4Test {
|
||||||
Patient patientC = createPatientFromJsonInputFileWithPossibleMatches( List.of(goldenA, goldenB) );
|
Patient patientC = createPatientFromJsonInputFileWithPossibleMatches( List.of(goldenA, goldenB) );
|
||||||
MdmTransactionContext mdmTransactionContext = getPatientUpdateLinkContext();
|
MdmTransactionContext mdmTransactionContext = getPatientUpdateLinkContext();
|
||||||
|
|
||||||
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
|
params.setGoldenResource(goldenA);
|
||||||
|
params.setSourceResource(patientC);
|
||||||
|
params.setMdmContext(mdmTransactionContext);
|
||||||
|
params.setMatchResult(MdmMatchResultEnum.MATCH);
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
|
|
||||||
// update POSSIBLE_MATCH Patient C -> GR A to MATCH (should work OK)
|
// update POSSIBLE_MATCH Patient C -> GR A to MATCH (should work OK)
|
||||||
myMdmLinkUpdaterSvc.updateLink(goldenA, patientC, MdmMatchResultEnum.MATCH, mdmTransactionContext);
|
myMdmLinkUpdaterSvc.updateLink(params);
|
||||||
|
|
||||||
|
params.setMatchResult(MdmMatchResultEnum.NO_MATCH);
|
||||||
|
params.setGoldenResource(goldenB);
|
||||||
|
|
||||||
// update POSSIBLE_MATCH Patient C -> GR B to NO_MATCH (should work OK)
|
// update POSSIBLE_MATCH Patient C -> GR B to NO_MATCH (should work OK)
|
||||||
myMdmLinkUpdaterSvc.updateLink(goldenB, patientC, MdmMatchResultEnum.NO_MATCH, mdmTransactionContext);
|
myMdmLinkUpdaterSvc.updateLink(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Patient createPatientFromJsonInputFileWithPossibleMatches(List<Patient> theGoldens) throws Exception {
|
private Patient createPatientFromJsonInputFileWithPossibleMatches(List<Patient> theGoldens) throws Exception {
|
||||||
|
|
|
@ -5,7 +5,9 @@ import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc;
|
import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -41,7 +43,13 @@ class MdmLinkUpdaterSvcImplTest extends BaseMdmR4Test {
|
||||||
|
|
||||||
MdmTransactionContext mdmCtx = buildUpdateLinkMdmTransactionContext();
|
MdmTransactionContext mdmCtx = buildUpdateLinkMdmTransactionContext();
|
||||||
|
|
||||||
myMdmLinkUpdaterSvc.updateLink(originalJaneGolden, jane, NO_MATCH, mdmCtx);
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
|
params.setMdmContext(mdmCtx);
|
||||||
|
params.setGoldenResource(originalJaneGolden);
|
||||||
|
params.setSourceResource(jane);
|
||||||
|
params.setMatchResult(NO_MATCH);
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
|
myMdmLinkUpdaterSvc.updateLink(params);
|
||||||
Patient newJaneGolden = getGoldenResourceFromTargetResource(jane);
|
Patient newJaneGolden = getGoldenResourceFromTargetResource(jane);
|
||||||
|
|
||||||
assertNotEquals(newJaneGolden.getId(), originalJaneGolden.getId());
|
assertNotEquals(newJaneGolden.getId(), originalJaneGolden.getId());
|
||||||
|
@ -83,7 +91,13 @@ class MdmLinkUpdaterSvcImplTest extends BaseMdmR4Test {
|
||||||
|
|
||||||
myMdmSettings.getMdmRules().setVersion("2");
|
myMdmSettings.getMdmRules().setVersion("2");
|
||||||
|
|
||||||
myMdmLinkUpdaterSvc.updateLink(goldenPatient, patient1, MATCH, mdmCtx);
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
|
params.setGoldenResource(goldenPatient);
|
||||||
|
params.setSourceResource(patient1);
|
||||||
|
params.setMatchResult(MATCH);
|
||||||
|
params.setMdmContext(mdmCtx);
|
||||||
|
myMdmLinkUpdaterSvc.updateLink(params);
|
||||||
|
|
||||||
final List<MdmLink> targets = myMdmLinkDaoSvc.findMdmLinksByGoldenResource(goldenPatient);
|
final List<MdmLink> targets = myMdmLinkDaoSvc.findMdmLinksByGoldenResource(goldenPatient);
|
||||||
assertFalse(targets.isEmpty());
|
assertFalse(targets.isEmpty());
|
||||||
|
|
|
@ -20,11 +20,13 @@ import ca.uhn.fhir.mdm.blocklist.json.BlockListJson;
|
||||||
import ca.uhn.fhir.mdm.blocklist.json.BlockListRuleJson;
|
import ca.uhn.fhir.mdm.blocklist.json.BlockListRuleJson;
|
||||||
import ca.uhn.fhir.mdm.blocklist.svc.IBlockListRuleProvider;
|
import ca.uhn.fhir.mdm.blocklist.svc.IBlockListRuleProvider;
|
||||||
import ca.uhn.fhir.mdm.model.CanonicalEID;
|
import ca.uhn.fhir.mdm.model.CanonicalEID;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
import ca.uhn.fhir.mdm.util.EIDHelper;
|
import ca.uhn.fhir.mdm.util.EIDHelper;
|
||||||
import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
|
import ca.uhn.fhir.mdm.util.GoldenResourceHelper;
|
||||||
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
import ca.uhn.fhir.mdm.util.MdmResourceUtil;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
@ -661,7 +663,13 @@ public class MdmMatchLinkSvcTest {
|
||||||
Patient originalJaneGolden = getGoldenResourceFromTargetResource(jane);
|
Patient originalJaneGolden = getGoldenResourceFromTargetResource(jane);
|
||||||
|
|
||||||
MdmTransactionContext mdmCtx = buildUpdateLinkMdmTransactionContext();
|
MdmTransactionContext mdmCtx = buildUpdateLinkMdmTransactionContext();
|
||||||
myMdmLinkUpdaterSvc.updateLink(originalPaulGolden, paul, NO_MATCH, mdmCtx);
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
|
params.setGoldenResource(originalPaulGolden);
|
||||||
|
params.setSourceResource(paul);
|
||||||
|
params.setMatchResult(NO_MATCH);
|
||||||
|
params.setRequestDetails(new SystemRequestDetails());
|
||||||
|
params.setMdmContext(mdmCtx);
|
||||||
|
myMdmLinkUpdaterSvc.updateLink(params);
|
||||||
|
|
||||||
clearExternalEIDs(paul);
|
clearExternalEIDs(paul);
|
||||||
addExternalEID(paul, EID_2);
|
addExternalEID(paul, EID_2);
|
||||||
|
|
|
@ -4,8 +4,8 @@ import ca.uhn.fhir.jpa.entity.MdmLink;
|
||||||
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
|
||||||
import ca.uhn.fhir.jpa.model.entity.EnversRevision;
|
import ca.uhn.fhir.jpa.model.entity.EnversRevision;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmLink;
|
import ca.uhn.fhir.mdm.api.IMdmLink;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
import ca.uhn.fhir.mdm.api.MdmLinkWithRevision;
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
|
|
|
@ -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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*/
|
*/
|
||||||
package ca.uhn.fhir.mdm.api;
|
package ca.uhn.fhir.mdm.api;
|
||||||
|
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmMergeGoldenResourcesParams;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
|
||||||
public interface IGoldenResourceMergerSvc {
|
public interface IGoldenResourceMergerSvc {
|
||||||
|
@ -32,9 +32,5 @@ public interface IGoldenResourceMergerSvc {
|
||||||
* @param theToGoldenResource the golden resource we are merging to
|
* @param theToGoldenResource the golden resource we are merging to
|
||||||
* @return updated theToGoldenResource with the merged fields and links.
|
* @return updated theToGoldenResource with the merged fields and links.
|
||||||
*/
|
*/
|
||||||
IAnyResource mergeGoldenResources(
|
IAnyResource mergeGoldenResources(MdmMergeGoldenResourcesParams theParams);
|
||||||
IAnyResource theFromGoldenResource,
|
|
||||||
IAnyResource theManuallyMergedResource,
|
|
||||||
IAnyResource theToGoldenResource,
|
|
||||||
MdmTransactionContext theMdmTransactionContext);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,12 @@
|
||||||
package ca.uhn.fhir.mdm.api;
|
package ca.uhn.fhir.mdm.api;
|
||||||
|
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmMergeGoldenResourcesParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmUnduplicateGoldenResourceParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
@ -82,29 +87,62 @@ public interface IMdmControllerSvc {
|
||||||
RequestDetails theRequestDetails,
|
RequestDetails theRequestDetails,
|
||||||
String theRequestResourceType);
|
String theRequestResourceType);
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "6.8.0")
|
||||||
void notDuplicateGoldenResource(
|
void notDuplicateGoldenResource(
|
||||||
String theGoldenResourceId,
|
String theGoldenResourceId,
|
||||||
String theTargetGoldenResourceId,
|
String theTargetGoldenResourceId,
|
||||||
MdmTransactionContext theMdmTransactionContext);
|
MdmTransactionContext theMdmTransactionContext);
|
||||||
|
|
||||||
|
default void unduplicateGoldenResource(MdmUnduplicateGoldenResourceParams theParams) {
|
||||||
|
notDuplicateGoldenResource(
|
||||||
|
theParams.getGoldenResourceId(), theParams.getTargetGoldenResourceId(), theParams.getMdmContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "6.8.0")
|
||||||
IAnyResource mergeGoldenResources(
|
IAnyResource mergeGoldenResources(
|
||||||
String theFromGoldenResourceId,
|
String theFromGoldenResourceId,
|
||||||
String theToGoldenResourceId,
|
String theToGoldenResourceId,
|
||||||
IAnyResource theManuallyMergedGoldenResource,
|
IAnyResource theManuallyMergedGoldenResource,
|
||||||
MdmTransactionContext theMdmTransactionContext);
|
MdmTransactionContext theMdmTransactionContext);
|
||||||
|
|
||||||
|
default IAnyResource mergeGoldenResources(MdmMergeGoldenResourcesParams theParams) {
|
||||||
|
return mergeGoldenResources(
|
||||||
|
theParams.getFromGoldenResourceId(),
|
||||||
|
theParams.getToGoldenResourceId(),
|
||||||
|
theParams.getManuallyMergedResource(),
|
||||||
|
theParams.getMdmTransactionContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "6.8.0")
|
||||||
IAnyResource updateLink(
|
IAnyResource updateLink(
|
||||||
String theGoldenResourceId,
|
String theGoldenResourceId,
|
||||||
String theSourceResourceId,
|
String theSourceResourceId,
|
||||||
String theMatchResult,
|
String theMatchResult,
|
||||||
MdmTransactionContext theMdmTransactionContext);
|
MdmTransactionContext theMdmTransactionContext);
|
||||||
|
|
||||||
|
default IAnyResource updateLink(MdmCreateOrUpdateParams theParams) {
|
||||||
|
String matchResult = theParams.getMatchResult() == null
|
||||||
|
? null
|
||||||
|
: theParams.getMatchResult().name();
|
||||||
|
return updateLink(
|
||||||
|
theParams.getGoldenResourceId(), theParams.getResourceId(), matchResult, theParams.getMdmContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true, since = "6.8.0")
|
||||||
IAnyResource createLink(
|
IAnyResource createLink(
|
||||||
String theGoldenResourceId,
|
String theGoldenResourceId,
|
||||||
String theSourceResourceId,
|
String theSourceResourceId,
|
||||||
@Nullable String theMatchResult,
|
@Nullable String theMatchResult,
|
||||||
MdmTransactionContext theMdmTransactionContext);
|
MdmTransactionContext theMdmTransactionContext);
|
||||||
|
|
||||||
|
default IAnyResource createLink(MdmCreateOrUpdateParams theParams) {
|
||||||
|
String matchResult = theParams.getMatchResult() == null
|
||||||
|
? null
|
||||||
|
: theParams.getMatchResult().name();
|
||||||
|
return createLink(
|
||||||
|
theParams.getGoldenResourceId(), theParams.getResourceId(), matchResult, theParams.getMdmContext());
|
||||||
|
}
|
||||||
|
|
||||||
IBaseParameters submitMdmClearJob(
|
IBaseParameters submitMdmClearJob(
|
||||||
List<String> theResourceNames,
|
List<String> theResourceNames,
|
||||||
IPrimitiveType<BigDecimal> theBatchSize,
|
IPrimitiveType<BigDecimal> theBatchSize,
|
||||||
|
|
|
@ -19,13 +19,9 @@
|
||||||
*/
|
*/
|
||||||
package ca.uhn.fhir.mdm.api;
|
package ca.uhn.fhir.mdm.api;
|
||||||
|
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
|
||||||
public interface IMdmLinkCreateSvc {
|
public interface IMdmLinkCreateSvc {
|
||||||
IAnyResource createLink(
|
IAnyResource createLink(MdmCreateOrUpdateParams theParams);
|
||||||
IAnyResource theGoldenResource,
|
|
||||||
IAnyResource theSourceResource,
|
|
||||||
MdmMatchResultEnum theMatchResult,
|
|
||||||
MdmTransactionContext theMdmContext);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ package ca.uhn.fhir.mdm.api;
|
||||||
|
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,12 @@
|
||||||
*/
|
*/
|
||||||
package ca.uhn.fhir.mdm.api;
|
package ca.uhn.fhir.mdm.api;
|
||||||
|
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmUnduplicateGoldenResourceParams;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
|
||||||
public interface IMdmLinkUpdaterSvc {
|
public interface IMdmLinkUpdaterSvc {
|
||||||
IAnyResource updateLink(
|
IAnyResource updateLink(MdmCreateOrUpdateParams theParams);
|
||||||
IAnyResource theGoldenResource,
|
|
||||||
IAnyResource theSourceResource,
|
|
||||||
MdmMatchResultEnum theMatchResult,
|
|
||||||
MdmTransactionContext theMdmContext);
|
|
||||||
|
|
||||||
void notDuplicateGoldenResource(
|
void unduplicateGoldenResource(MdmUnduplicateGoldenResourceParams theParams);
|
||||||
IAnyResource theGoldenResource, IAnyResource theTargetGoldenResource, MdmTransactionContext theMdmContext);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ public interface IMdmSubmitSvc {
|
||||||
* @param theCriteria The FHIR search critieria for filtering the resources to be submitted for MDM processing.
|
* @param theCriteria The FHIR search critieria for filtering the resources to be submitted for MDM processing.
|
||||||
* @return the number of resources submitted for MDM processing.
|
* @return the number of resources submitted for MDM processing.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "6.8.0")
|
||||||
long submitPractitionerTypeToMdm(String theCriteria, RequestDetails theRequestDetails);
|
long submitPractitionerTypeToMdm(String theCriteria, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,6 +64,7 @@ public interface IMdmSubmitSvc {
|
||||||
* @param theCriteria The FHIR search critieria for filtering the resources to be submitted for MDM processing.
|
* @param theCriteria The FHIR search critieria for filtering the resources to be submitted for MDM processing.
|
||||||
* @return the number of resources submitted for MDM processing.
|
* @return the number of resources submitted for MDM processing.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "6.8.0")
|
||||||
long submitPatientTypeToMdm(String theCriteria, RequestDetails theRequestDetails);
|
long submitPatientTypeToMdm(String theCriteria, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*/
|
*/
|
||||||
package ca.uhn.fhir.mdm.api.paging;
|
package ca.uhn.fhir.mdm.api.paging;
|
||||||
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package ca.uhn.fhir.mdm.model;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
|
||||||
|
public class MdmCreateOrUpdateParams {
|
||||||
|
/**
|
||||||
|
* The golden resource id
|
||||||
|
*/
|
||||||
|
private String myGoldenResourceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The golden resource to update for the link.
|
||||||
|
*/
|
||||||
|
private IAnyResource myGoldenResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The source id.
|
||||||
|
*/
|
||||||
|
private String myResourceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The source resource linked to the golden resource
|
||||||
|
*/
|
||||||
|
private IAnyResource mySourceResource;
|
||||||
|
/**
|
||||||
|
* Match result to update the link to.
|
||||||
|
*/
|
||||||
|
private MdmMatchResultEnum myMatchResult;
|
||||||
|
/**
|
||||||
|
* The context.
|
||||||
|
*/
|
||||||
|
private MdmTransactionContext myMdmContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request details.
|
||||||
|
*/
|
||||||
|
private RequestDetails myRequestDetails;
|
||||||
|
|
||||||
|
public String getGoldenResourceId() {
|
||||||
|
return myGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoldenResourceId(String theGoldenResourceId) {
|
||||||
|
myGoldenResourceId = theGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceId() {
|
||||||
|
return myResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourceId(String theResourceId) {
|
||||||
|
myResourceId = theResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnyResource getGoldenResource() {
|
||||||
|
return myGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoldenResource(IAnyResource theGoldenResource) {
|
||||||
|
myGoldenResource = theGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnyResource getSourceResource() {
|
||||||
|
return mySourceResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceResource(IAnyResource theSourceResource) {
|
||||||
|
mySourceResource = theSourceResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MdmMatchResultEnum getMatchResult() {
|
||||||
|
return myMatchResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatchResult(MdmMatchResultEnum theMatchResult) {
|
||||||
|
myMatchResult = theMatchResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MdmTransactionContext getMdmContext() {
|
||||||
|
return myMdmContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMdmContext(MdmTransactionContext theMdmContext) {
|
||||||
|
myMdmContext = theMdmContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestDetails getRequestDetails() {
|
||||||
|
return myRequestDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestDetails(RequestDetails theRequestDetails) {
|
||||||
|
myRequestDetails = theRequestDetails;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package ca.uhn.fhir.mdm.model;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
|
||||||
|
public class MdmMergeGoldenResourcesParams {
|
||||||
|
private String myFromGoldenResourceId;
|
||||||
|
private IAnyResource myFromGoldenResource;
|
||||||
|
private String myToGoldenResourceId;
|
||||||
|
|
||||||
|
private IAnyResource myManuallyMergedResource;
|
||||||
|
|
||||||
|
private IAnyResource myToGoldenResource;
|
||||||
|
|
||||||
|
private MdmTransactionContext myMdmTransactionContext;
|
||||||
|
|
||||||
|
private RequestDetails myRequestDetails;
|
||||||
|
|
||||||
|
public String getFromGoldenResourceId() {
|
||||||
|
return myFromGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromGoldenResourceId(String theTheFromGoldenResourceId) {
|
||||||
|
myFromGoldenResourceId = theTheFromGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToGoldenResourceId() {
|
||||||
|
return myToGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToGoldenResourceId(String theTheToGoldenResourceId) {
|
||||||
|
myToGoldenResourceId = theTheToGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnyResource getFromGoldenResource() {
|
||||||
|
return myFromGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromGoldenResource(IAnyResource theFromGoldenResource) {
|
||||||
|
myFromGoldenResource = theFromGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnyResource getManuallyMergedResource() {
|
||||||
|
return myManuallyMergedResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setManuallyMergedResource(IAnyResource theManuallyMergedResource) {
|
||||||
|
myManuallyMergedResource = theManuallyMergedResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnyResource getToGoldenResource() {
|
||||||
|
return myToGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToGoldenResource(IAnyResource theToGoldenResource) {
|
||||||
|
myToGoldenResource = theToGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MdmTransactionContext getMdmTransactionContext() {
|
||||||
|
return myMdmTransactionContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMdmTransactionContext(MdmTransactionContext theMdmTransactionContext) {
|
||||||
|
myMdmTransactionContext = theMdmTransactionContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestDetails getRequestDetails() {
|
||||||
|
return myRequestDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestDetails(RequestDetails theRequestDetails) {
|
||||||
|
myRequestDetails = theRequestDetails;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package ca.uhn.fhir.mdm.model;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
|
||||||
|
public class MdmUnduplicateGoldenResourceParams {
|
||||||
|
|
||||||
|
private String myGoldenResourceId;
|
||||||
|
|
||||||
|
private IAnyResource myGoldenResource;
|
||||||
|
|
||||||
|
private String myTargetGoldenResourceId;
|
||||||
|
|
||||||
|
private IAnyResource myTargetGoldenResource;
|
||||||
|
|
||||||
|
private MdmTransactionContext myMdmContext;
|
||||||
|
|
||||||
|
private RequestDetails myRequestDetails;
|
||||||
|
|
||||||
|
public IAnyResource getGoldenResource() {
|
||||||
|
return myGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoldenResource(IAnyResource theGoldenResource) {
|
||||||
|
myGoldenResource = theGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnyResource getTargetGoldenResource() {
|
||||||
|
return myTargetGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetGoldenResource(IAnyResource theTargetGoldenResource) {
|
||||||
|
myTargetGoldenResource = theTargetGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MdmTransactionContext getMdmContext() {
|
||||||
|
return myMdmContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMdmContext(MdmTransactionContext theMdmContext) {
|
||||||
|
myMdmContext = theMdmContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestDetails getRequestDetails() {
|
||||||
|
return myRequestDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestDetails(RequestDetails theRequestDetails) {
|
||||||
|
myRequestDetails = theRequestDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGoldenResourceId() {
|
||||||
|
return myGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoldenResourceId(String theGoldenResourceId) {
|
||||||
|
myGoldenResourceId = theGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTargetGoldenResourceId() {
|
||||||
|
return myTargetGoldenResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetGoldenResourceId(String theTargetGoldenResourceId) {
|
||||||
|
myTargetGoldenResourceId = theTargetGoldenResourceId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MdmClearEvent implements IModelJson {
|
||||||
|
|
||||||
|
@JsonProperty("resourceTypes")
|
||||||
|
private List<String> myResourceTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if this submit was done asynchronously
|
||||||
|
* (ie, was submitted as a batch job).
|
||||||
|
* False if submitted directly to mdm.
|
||||||
|
*/
|
||||||
|
@JsonProperty("batchSize")
|
||||||
|
private Long myBatchSize;
|
||||||
|
|
||||||
|
public Long getBatchSize() {
|
||||||
|
return myBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatchSize(Long theBatchSize) {
|
||||||
|
myBatchSize = theBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getResourceTypes() {
|
||||||
|
if (myResourceTypes == null) {
|
||||||
|
myResourceTypes = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return myResourceTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourceTypes(List<String> theResourceTypes) {
|
||||||
|
myResourceTypes = theResourceTypes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
public class MdmEventResource implements IModelJson {
|
||||||
|
/**
|
||||||
|
* The id of the resource that's part of this event.
|
||||||
|
*/
|
||||||
|
@JsonProperty("id")
|
||||||
|
private String myId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resource type.
|
||||||
|
*/
|
||||||
|
@JsonProperty("resourceType")
|
||||||
|
private String myResourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if this is a golden resource; false otherwise.
|
||||||
|
*/
|
||||||
|
@JsonProperty("isGoldenResource")
|
||||||
|
private boolean myIsGoldenResource;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return myId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String theId) {
|
||||||
|
myId = theId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResourceType() {
|
||||||
|
return myResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResourceType(String theResourceType) {
|
||||||
|
myResourceType = theResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGoldenResource() {
|
||||||
|
return myIsGoldenResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsGoldenResource(boolean theGoldenResource) {
|
||||||
|
myIsGoldenResource = theGoldenResource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MdmHistoryEvent implements IModelJson {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of golden resource ids queried.
|
||||||
|
* Can be empty.
|
||||||
|
*/
|
||||||
|
@JsonProperty("goldenResourceIds")
|
||||||
|
private List<String> myGoldenResourceIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of source ids queried.
|
||||||
|
* Can be empty.
|
||||||
|
*/
|
||||||
|
@JsonProperty("sourceIds")
|
||||||
|
private List<String> mySourceIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The associated link revisions returned from the search.
|
||||||
|
*/
|
||||||
|
@JsonProperty("mdmLinkRevisions")
|
||||||
|
private List<MdmLinkWithRevisionJson> myMdmLinkRevisions;
|
||||||
|
|
||||||
|
public List<String> getGoldenResourceIds() {
|
||||||
|
if (myGoldenResourceIds == null) {
|
||||||
|
myGoldenResourceIds = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return myGoldenResourceIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGoldenResourceIds(List<String> theGoldenResourceIds) {
|
||||||
|
myGoldenResourceIds = theGoldenResourceIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSourceIds() {
|
||||||
|
if (mySourceIds == null) {
|
||||||
|
mySourceIds = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return mySourceIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceIds(List<String> theSourceIds) {
|
||||||
|
mySourceIds = theSourceIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MdmLinkWithRevisionJson> getMdmLinkRevisions() {
|
||||||
|
if (myMdmLinkRevisions == null) {
|
||||||
|
myMdmLinkRevisions = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return myMdmLinkRevisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMdmLinkRevisions(List<MdmLinkWithRevisionJson> theMdmLinkRevisions) {
|
||||||
|
myMdmLinkRevisions = theMdmLinkRevisions;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package ca.uhn.fhir.mdm.api;
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
|
|
@ -17,8 +17,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package ca.uhn.fhir.mdm.api;
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
|
||||||
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.model.api.IModelJson;
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package ca.uhn.fhir.mdm.api;
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* #%L
|
* #%L
|
|
@ -0,0 +1,26 @@
|
||||||
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
|
||||||
|
public class MdmMergeEvent implements IModelJson {
|
||||||
|
|
||||||
|
private MdmEventResource myFromResource;
|
||||||
|
|
||||||
|
private MdmEventResource myToResource;
|
||||||
|
|
||||||
|
public MdmEventResource getFromResource() {
|
||||||
|
return myFromResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromResource(MdmEventResource theFromResource) {
|
||||||
|
myFromResource = theFromResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MdmEventResource getToResource() {
|
||||||
|
return myToResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToResource(MdmEventResource theToResource) {
|
||||||
|
myToResource = theToResource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package ca.uhn.fhir.mdm.model.mdmevents;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.IModelJson;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MdmSubmitEvent implements IModelJson {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batch size; only applicable if this is a batch job
|
||||||
|
*/
|
||||||
|
@JsonProperty("batchSize")
|
||||||
|
private Long myBatchSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The search/resource urls used in this job
|
||||||
|
*/
|
||||||
|
@JsonProperty("urls")
|
||||||
|
private List<String> myUrls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if this submit was done asynchronously
|
||||||
|
* (ie, was submitted as a batch job).
|
||||||
|
* False if submitted directly to mdm.
|
||||||
|
*/
|
||||||
|
@JsonProperty("batch_job")
|
||||||
|
private boolean myIsBatchJob;
|
||||||
|
|
||||||
|
public Long getBatchSize() {
|
||||||
|
return myBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatchSize(Long theBatchSize) {
|
||||||
|
myBatchSize = theBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getUrls() {
|
||||||
|
if (myUrls == null) {
|
||||||
|
myUrls = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return myUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrls(List<String> theUrls) {
|
||||||
|
myUrls = theUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MdmSubmitEvent addUrl(String theUrl) {
|
||||||
|
getUrls().add(theUrl);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBatchJob() {
|
||||||
|
return myIsBatchJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatchJob(boolean theBatchJob) {
|
||||||
|
myIsBatchJob = theBatchJob;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,13 +21,13 @@ package ca.uhn.fhir.mdm.provider;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageLinkBuilder;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageLinkBuilder;
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageLinkTuple;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageLinkTuple;
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
import ca.uhn.fhir.rest.server.TransactionLogMessages;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
|
|
@ -21,11 +21,16 @@ package ca.uhn.fhir.mdm.provider;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmHistorySearchParameters;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkWithRevisionJson;
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmHistoryEvent;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkWithRevisionJson;
|
||||||
import ca.uhn.fhir.rest.annotation.Operation;
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import ca.uhn.fhir.util.ParametersUtil;
|
import ca.uhn.fhir.util.ParametersUtil;
|
||||||
|
@ -34,7 +39,9 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class MdmLinkHistoryProviderDstu3Plus extends BaseMdmProvider {
|
public class MdmLinkHistoryProviderDstu3Plus extends BaseMdmProvider {
|
||||||
|
@ -42,9 +49,15 @@ public class MdmLinkHistoryProviderDstu3Plus extends BaseMdmProvider {
|
||||||
|
|
||||||
private final IMdmControllerSvc myMdmControllerSvc;
|
private final IMdmControllerSvc myMdmControllerSvc;
|
||||||
|
|
||||||
public MdmLinkHistoryProviderDstu3Plus(FhirContext theFhirContext, IMdmControllerSvc theMdmControllerSvc) {
|
private final IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
|
public MdmLinkHistoryProviderDstu3Plus(
|
||||||
|
FhirContext theFhirContext,
|
||||||
|
IMdmControllerSvc theMdmControllerSvc,
|
||||||
|
IInterceptorBroadcaster theIInterceptorBroadcaster) {
|
||||||
super(theFhirContext);
|
super(theFhirContext);
|
||||||
myMdmControllerSvc = theMdmControllerSvc;
|
myMdmControllerSvc = theMdmControllerSvc;
|
||||||
|
myInterceptorBroadcaster = theIInterceptorBroadcaster;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(name = ProviderConstants.MDM_LINK_HISTORY, idempotent = true)
|
@Operation(name = ProviderConstants.MDM_LINK_HISTORY, idempotent = true)
|
||||||
|
@ -79,6 +92,27 @@ public class MdmLinkHistoryProviderDstu3Plus extends BaseMdmProvider {
|
||||||
|
|
||||||
parametersFromMdmLinkRevisions(retVal, mdmLinkRevisionsFromSvc);
|
parametersFromMdmLinkRevisions(retVal, mdmLinkRevisionsFromSvc);
|
||||||
|
|
||||||
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_POST_LINK_HISTORY)) {
|
||||||
|
// MDM_POST_LINK_HISTORY hook
|
||||||
|
MdmHistoryEvent historyEvent = new MdmHistoryEvent();
|
||||||
|
historyEvent.setMdmLinkRevisions(mdmLinkRevisionsFromSvc);
|
||||||
|
if (isNotEmpty(theResourceIds)) {
|
||||||
|
historyEvent.setSourceIds(theResourceIds.stream()
|
||||||
|
.map(IPrimitiveType::getValueAsString)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
if (isNotEmpty(theMdmGoldenResourceIds)) {
|
||||||
|
historyEvent.setGoldenResourceIds(theMdmGoldenResourceIds.stream()
|
||||||
|
.map(IPrimitiveType::getValueAsString)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
HookParams params = new HookParams();
|
||||||
|
params.add(RequestDetails.class, theRequestDetails);
|
||||||
|
params.add(MdmHistoryEvent.class, historyEvent);
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_POST_LINK_HISTORY, params);
|
||||||
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,21 @@ package ca.uhn.fhir.mdm.provider;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSubmitSvc;
|
import ca.uhn.fhir.mdm.api.IMdmSubmitSvc;
|
||||||
import ca.uhn.fhir.mdm.api.MdmConstants;
|
import ca.uhn.fhir.mdm.api.MdmConstants;
|
||||||
import ca.uhn.fhir.mdm.api.MdmLinkJson;
|
|
||||||
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
import ca.uhn.fhir.mdm.api.MdmQuerySearchParameters;
|
||||||
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
import ca.uhn.fhir.mdm.api.paging.MdmPageRequest;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmCreateOrUpdateParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmMergeGoldenResourcesParams;
|
||||||
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
import ca.uhn.fhir.mdm.model.MdmTransactionContext;
|
||||||
|
import ca.uhn.fhir.mdm.model.MdmUnduplicateGoldenResourceParams;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmLinkJson;
|
||||||
|
import ca.uhn.fhir.mdm.model.mdmevents.MdmSubmitEvent;
|
||||||
import ca.uhn.fhir.model.api.annotation.Description;
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
import ca.uhn.fhir.rest.annotation.Operation;
|
import ca.uhn.fhir.rest.annotation.Operation;
|
||||||
|
@ -57,16 +64,23 @@ import java.util.stream.Collectors;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import static ca.uhn.fhir.rest.api.Constants.PARAM_OFFSET;
|
import static ca.uhn.fhir.rest.api.Constants.PARAM_OFFSET;
|
||||||
|
import static org.apache.commons.lang3.ObjectUtils.isNotEmpty;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
private static final Logger ourLog = getLogger(MdmProviderDstu3Plus.class);
|
private static final Logger ourLog = getLogger(MdmProviderDstu3Plus.class);
|
||||||
|
|
||||||
|
private static final String PATIENT_RESOURCE = "Patient";
|
||||||
|
private static final String PRACTITIONER_RESOURCE = "Practitioner";
|
||||||
|
|
||||||
private final IMdmControllerSvc myMdmControllerSvc;
|
private final IMdmControllerSvc myMdmControllerSvc;
|
||||||
private final IMdmSubmitSvc myMdmSubmitSvc;
|
private final IMdmSubmitSvc myMdmSubmitSvc;
|
||||||
private final IMdmSettings myMdmSettings;
|
private final IMdmSettings myMdmSettings;
|
||||||
private final MdmControllerHelper myMdmControllerHelper;
|
private final MdmControllerHelper myMdmControllerHelper;
|
||||||
|
|
||||||
|
private final IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
public static final int DEFAULT_PAGE_SIZE = 20;
|
public static final int DEFAULT_PAGE_SIZE = 20;
|
||||||
public static final int MAX_PAGE_SIZE = 100;
|
public static final int MAX_PAGE_SIZE = 100;
|
||||||
|
|
||||||
|
@ -81,14 +95,22 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
IMdmControllerSvc theMdmControllerSvc,
|
IMdmControllerSvc theMdmControllerSvc,
|
||||||
MdmControllerHelper theMdmHelper,
|
MdmControllerHelper theMdmHelper,
|
||||||
IMdmSubmitSvc theMdmSubmitSvc,
|
IMdmSubmitSvc theMdmSubmitSvc,
|
||||||
|
IInterceptorBroadcaster theIInterceptorBroadcaster,
|
||||||
IMdmSettings theIMdmSettings) {
|
IMdmSettings theIMdmSettings) {
|
||||||
super(theFhirContext);
|
super(theFhirContext);
|
||||||
myMdmControllerSvc = theMdmControllerSvc;
|
myMdmControllerSvc = theMdmControllerSvc;
|
||||||
myMdmControllerHelper = theMdmHelper;
|
myMdmControllerHelper = theMdmHelper;
|
||||||
myMdmSubmitSvc = theMdmSubmitSvc;
|
myMdmSubmitSvc = theMdmSubmitSvc;
|
||||||
|
myInterceptorBroadcaster = theIInterceptorBroadcaster;
|
||||||
myMdmSettings = theIMdmSettings;
|
myMdmSettings = theIMdmSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for matches for the provided patient resource
|
||||||
|
* @param thePatient - the patient resource
|
||||||
|
* @param theRequestDetails - the request details
|
||||||
|
* @return - any matches to the provided patient resource
|
||||||
|
*/
|
||||||
@Operation(name = ProviderConstants.EMPI_MATCH, typeName = "Patient")
|
@Operation(name = ProviderConstants.EMPI_MATCH, typeName = "Patient")
|
||||||
public IBaseBundle match(
|
public IBaseBundle match(
|
||||||
@OperationParam(name = ProviderConstants.MDM_MATCH_RESOURCE, min = 1, max = 1, typeName = "Patient")
|
@OperationParam(name = ProviderConstants.MDM_MATCH_RESOURCE, min = 1, max = 1, typeName = "Patient")
|
||||||
|
@ -100,6 +122,14 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
return myMdmControllerHelper.getMatchesAndPossibleMatchesForResource(thePatient, "Patient", theRequestDetails);
|
return myMdmControllerHelper.getMatchesAndPossibleMatchesForResource(thePatient, "Patient", theRequestDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for matches for hte provided resource.
|
||||||
|
*
|
||||||
|
* @param theResource - the resource to match on
|
||||||
|
* @param theResourceType - the resource type
|
||||||
|
* @param theRequestDetails - the request details
|
||||||
|
* @return - any matches to the provided resource
|
||||||
|
*/
|
||||||
@Operation(name = ProviderConstants.MDM_MATCH)
|
@Operation(name = ProviderConstants.MDM_MATCH)
|
||||||
public IBaseBundle serverMatch(
|
public IBaseBundle serverMatch(
|
||||||
@OperationParam(name = ProviderConstants.MDM_MATCH_RESOURCE, min = 1, max = 1) IAnyResource theResource,
|
@OperationParam(name = ProviderConstants.MDM_MATCH_RESOURCE, min = 1, max = 1) IAnyResource theResource,
|
||||||
|
@ -138,11 +168,15 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
theRequestDetails,
|
theRequestDetails,
|
||||||
operationType,
|
operationType,
|
||||||
getResourceType(ProviderConstants.MDM_MERGE_GR_FROM_GOLDEN_RESOURCE_ID, theFromGoldenResourceId));
|
getResourceType(ProviderConstants.MDM_MERGE_GR_FROM_GOLDEN_RESOURCE_ID, theFromGoldenResourceId));
|
||||||
return myMdmControllerSvc.mergeGoldenResources(
|
|
||||||
theFromGoldenResourceId.getValueAsString(),
|
MdmMergeGoldenResourcesParams params = new MdmMergeGoldenResourcesParams();
|
||||||
theToGoldenResourceId.getValueAsString(),
|
params.setFromGoldenResourceId(theFromGoldenResourceId.getValueAsString());
|
||||||
theMergedResource,
|
params.setToGoldenResourceId(theToGoldenResourceId.getValueAsString());
|
||||||
txContext);
|
params.setManuallyMergedResource(theMergedResource);
|
||||||
|
params.setMdmTransactionContext(txContext);
|
||||||
|
params.setRequestDetails(theRequestDetails);
|
||||||
|
|
||||||
|
return myMdmControllerSvc.mergeGoldenResources(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(name = ProviderConstants.MDM_UPDATE_LINK)
|
@Operation(name = ProviderConstants.MDM_UPDATE_LINK)
|
||||||
|
@ -155,14 +189,18 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
IPrimitiveType<String> theMatchResult,
|
IPrimitiveType<String> theMatchResult,
|
||||||
ServletRequestDetails theRequestDetails) {
|
ServletRequestDetails theRequestDetails) {
|
||||||
validateUpdateLinkParameters(theGoldenResourceId, theResourceId, theMatchResult);
|
validateUpdateLinkParameters(theGoldenResourceId, theResourceId, theMatchResult);
|
||||||
return myMdmControllerSvc.updateLink(
|
|
||||||
theGoldenResourceId.getValueAsString(),
|
MdmCreateOrUpdateParams updateLinkParams = new MdmCreateOrUpdateParams();
|
||||||
theResourceId.getValue(),
|
updateLinkParams.setGoldenResourceId(theGoldenResourceId.getValueAsString());
|
||||||
theMatchResult.getValue(),
|
updateLinkParams.setResourceId(theResourceId.getValue());
|
||||||
createMdmContext(
|
updateLinkParams.setMatchResult(MdmControllerUtil.extractMatchResultOrNull(theMatchResult.getValue()));
|
||||||
theRequestDetails,
|
updateLinkParams.setMdmContext(createMdmContext(
|
||||||
MdmTransactionContext.OperationType.UPDATE_LINK,
|
theRequestDetails,
|
||||||
getResourceType(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId)));
|
MdmTransactionContext.OperationType.UPDATE_LINK,
|
||||||
|
getResourceType(ProviderConstants.MDM_UPDATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId)));
|
||||||
|
updateLinkParams.setRequestDetails(theRequestDetails);
|
||||||
|
|
||||||
|
return myMdmControllerSvc.updateLink(updateLinkParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(name = ProviderConstants.MDM_CREATE_LINK)
|
@Operation(name = ProviderConstants.MDM_CREATE_LINK)
|
||||||
|
@ -175,14 +213,18 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
IPrimitiveType<String> theMatchResult,
|
IPrimitiveType<String> theMatchResult,
|
||||||
ServletRequestDetails theRequestDetails) {
|
ServletRequestDetails theRequestDetails) {
|
||||||
validateCreateLinkParameters(theGoldenResourceId, theResourceId, theMatchResult);
|
validateCreateLinkParameters(theGoldenResourceId, theResourceId, theMatchResult);
|
||||||
return myMdmControllerSvc.createLink(
|
|
||||||
theGoldenResourceId.getValueAsString(),
|
MdmCreateOrUpdateParams params = new MdmCreateOrUpdateParams();
|
||||||
theResourceId.getValue(),
|
params.setGoldenResourceId(theGoldenResourceId.getValueAsString());
|
||||||
extractStringOrNull(theMatchResult),
|
params.setResourceId(theResourceId.getValue());
|
||||||
createMdmContext(
|
params.setMatchResult(MdmControllerUtil.extractMatchResultOrNull(extractStringOrNull(theMatchResult)));
|
||||||
theRequestDetails,
|
params.setRequestDetails(theRequestDetails);
|
||||||
MdmTransactionContext.OperationType.CREATE_LINK,
|
params.setMdmContext(createMdmContext(
|
||||||
getResourceType(ProviderConstants.MDM_CREATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId)));
|
theRequestDetails,
|
||||||
|
MdmTransactionContext.OperationType.CREATE_LINK,
|
||||||
|
getResourceType(ProviderConstants.MDM_CREATE_LINK_GOLDEN_RESOURCE_ID, theGoldenResourceId)));
|
||||||
|
|
||||||
|
return myMdmControllerSvc.createLink(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
|
@ -203,7 +245,7 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
|
|
||||||
List<String> resourceNames = new ArrayList<>();
|
List<String> resourceNames = new ArrayList<>();
|
||||||
|
|
||||||
if (theResourceNames != null) {
|
if (isNotEmpty(theResourceNames)) {
|
||||||
resourceNames.addAll(
|
resourceNames.addAll(
|
||||||
theResourceNames.stream().map(IPrimitiveType::getValue).collect(Collectors.toList()));
|
theResourceNames.stream().map(IPrimitiveType::getValue).collect(Collectors.toList()));
|
||||||
validateResourceNames(resourceNames);
|
validateResourceNames(resourceNames);
|
||||||
|
@ -316,15 +358,18 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
@OperationParam(name = ProviderConstants.MDM_QUERY_LINKS_RESOURCE_ID, min = 1, max = 1, typeName = "string")
|
@OperationParam(name = ProviderConstants.MDM_QUERY_LINKS_RESOURCE_ID, min = 1, max = 1, typeName = "string")
|
||||||
IPrimitiveType<String> theResourceId,
|
IPrimitiveType<String> theResourceId,
|
||||||
ServletRequestDetails theRequestDetails) {
|
ServletRequestDetails theRequestDetails) {
|
||||||
|
|
||||||
validateNotDuplicateParameters(theGoldenResourceId, theResourceId);
|
validateNotDuplicateParameters(theGoldenResourceId, theResourceId);
|
||||||
myMdmControllerSvc.notDuplicateGoldenResource(
|
|
||||||
theGoldenResourceId.getValue(),
|
MdmUnduplicateGoldenResourceParams params = new MdmUnduplicateGoldenResourceParams();
|
||||||
theResourceId.getValue(),
|
params.setRequestDetails(theRequestDetails);
|
||||||
createMdmContext(
|
params.setGoldenResourceId(theGoldenResourceId.getValueAsString());
|
||||||
theRequestDetails,
|
params.setTargetGoldenResourceId(theResourceId.getValueAsString());
|
||||||
MdmTransactionContext.OperationType.NOT_DUPLICATE,
|
params.setMdmContext(createMdmContext(
|
||||||
getResourceType(ProviderConstants.MDM_QUERY_LINKS_GOLDEN_RESOURCE_ID, theGoldenResourceId)));
|
theRequestDetails,
|
||||||
|
MdmTransactionContext.OperationType.NOT_DUPLICATE,
|
||||||
|
getResourceType(ProviderConstants.MDM_QUERY_LINKS_GOLDEN_RESOURCE_ID, theGoldenResourceId)));
|
||||||
|
|
||||||
|
myMdmControllerSvc.unduplicateGoldenResource(params);
|
||||||
|
|
||||||
IBaseParameters retval = ParametersUtil.newInstance(myFhirContext);
|
IBaseParameters retval = ParametersUtil.newInstance(myFhirContext);
|
||||||
ParametersUtil.addParameterToParametersBoolean(myFhirContext, retval, "success", true);
|
ParametersUtil.addParameterToParametersBoolean(myFhirContext, retval, "success", true);
|
||||||
|
@ -348,24 +393,22 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
String criteria = convertStringTypeToString(theCriteria);
|
String criteria = convertStringTypeToString(theCriteria);
|
||||||
String resourceType = convertStringTypeToString(theResourceType);
|
String resourceType = convertStringTypeToString(theResourceType);
|
||||||
long submittedCount;
|
long submittedCount;
|
||||||
|
IBaseParameters retval;
|
||||||
if (theRequestDetails.isPreferRespondAsync()) {
|
if (theRequestDetails.isPreferRespondAsync()) {
|
||||||
List<String> urls = buildUrlsForJob(criteria, resourceType);
|
List<String> urls = buildUrlsForJob(criteria, resourceType);
|
||||||
return myMdmControllerSvc.submitMdmSubmitJob(urls, theBatchSize, theRequestDetails);
|
retval = myMdmControllerSvc.submitMdmSubmitJob(urls, theBatchSize, theRequestDetails);
|
||||||
} else {
|
} else {
|
||||||
if (StringUtils.isNotBlank(resourceType)) {
|
submittedCount = synchronousMdmSubmit(resourceType, null, criteria, theRequestDetails);
|
||||||
submittedCount =
|
retval = buildMdmOutParametersWithCount(submittedCount);
|
||||||
myMdmSubmitSvc.submitSourceResourceTypeToMdm(resourceType, criteria, theRequestDetails);
|
|
||||||
} else {
|
|
||||||
submittedCount = myMdmSubmitSvc.submitAllSourceTypesToMdm(criteria, theRequestDetails);
|
|
||||||
}
|
|
||||||
return buildMdmOutParametersWithCount(submittedCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private List<String> buildUrlsForJob(String criteria, String resourceType) {
|
private List<String> buildUrlsForJob(String criteria, String resourceType) {
|
||||||
List<String> urls = new ArrayList<>();
|
List<String> urls = new ArrayList<>();
|
||||||
if (StringUtils.isNotBlank(resourceType)) {
|
if (isNotBlank(resourceType)) {
|
||||||
String theUrl = resourceType + "?" + criteria;
|
String theUrl = resourceType + "?" + criteria;
|
||||||
urls.add(theUrl);
|
urls.add(theUrl);
|
||||||
} else {
|
} else {
|
||||||
|
@ -388,7 +431,8 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
@OperationParam(name = ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, typeName = "integer")
|
@OperationParam(name = ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, typeName = "integer")
|
||||||
})
|
})
|
||||||
public IBaseParameters mdmBatchPatientInstance(@IdParam IIdType theIdParam, RequestDetails theRequest) {
|
public IBaseParameters mdmBatchPatientInstance(@IdParam IIdType theIdParam, RequestDetails theRequest) {
|
||||||
long submittedCount = myMdmSubmitSvc.submitSourceResourceToMdm(theIdParam, theRequest);
|
|
||||||
|
long submittedCount = synchronousMdmSubmit(null, theIdParam, null, theRequest);
|
||||||
return buildMdmOutParametersWithCount(submittedCount);
|
return buildMdmOutParametersWithCount(submittedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,11 +450,11 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
IPrimitiveType<BigDecimal> theBatchSize,
|
IPrimitiveType<BigDecimal> theBatchSize,
|
||||||
ServletRequestDetails theRequest) {
|
ServletRequestDetails theRequest) {
|
||||||
if (theRequest.isPreferRespondAsync()) {
|
if (theRequest.isPreferRespondAsync()) {
|
||||||
String theUrl = "Patient?";
|
String theUrl = PATIENT_RESOURCE + "?";
|
||||||
return myMdmControllerSvc.submitMdmSubmitJob(Collections.singletonList(theUrl), theBatchSize, theRequest);
|
return myMdmControllerSvc.submitMdmSubmitJob(Collections.singletonList(theUrl), theBatchSize, theRequest);
|
||||||
} else {
|
} else {
|
||||||
String criteria = convertStringTypeToString(theCriteria);
|
String criteria = convertStringTypeToString(theCriteria);
|
||||||
long submittedCount = myMdmSubmitSvc.submitPatientTypeToMdm(criteria, theRequest);
|
long submittedCount = synchronousMdmSubmit(PATIENT_RESOURCE, null, criteria, theRequest);
|
||||||
return buildMdmOutParametersWithCount(submittedCount);
|
return buildMdmOutParametersWithCount(submittedCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,7 +467,7 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
@OperationParam(name = ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, typeName = "integer")
|
@OperationParam(name = ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, typeName = "integer")
|
||||||
})
|
})
|
||||||
public IBaseParameters mdmBatchPractitionerInstance(@IdParam IIdType theIdParam, RequestDetails theRequest) {
|
public IBaseParameters mdmBatchPractitionerInstance(@IdParam IIdType theIdParam, RequestDetails theRequest) {
|
||||||
long submittedCount = myMdmSubmitSvc.submitSourceResourceToMdm(theIdParam, theRequest);
|
long submittedCount = synchronousMdmSubmit(null, theIdParam, null, theRequest);
|
||||||
return buildMdmOutParametersWithCount(submittedCount);
|
return buildMdmOutParametersWithCount(submittedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,11 +485,11 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
IPrimitiveType<BigDecimal> theBatchSize,
|
IPrimitiveType<BigDecimal> theBatchSize,
|
||||||
ServletRequestDetails theRequest) {
|
ServletRequestDetails theRequest) {
|
||||||
if (theRequest.isPreferRespondAsync()) {
|
if (theRequest.isPreferRespondAsync()) {
|
||||||
String theUrl = "Practitioner?";
|
String theUrl = PRACTITIONER_RESOURCE + "?";
|
||||||
return myMdmControllerSvc.submitMdmSubmitJob(Collections.singletonList(theUrl), theBatchSize, theRequest);
|
return myMdmControllerSvc.submitMdmSubmitJob(Collections.singletonList(theUrl), theBatchSize, theRequest);
|
||||||
} else {
|
} else {
|
||||||
String criteria = convertStringTypeToString(theCriteria);
|
String criteria = convertStringTypeToString(theCriteria);
|
||||||
long submittedCount = myMdmSubmitSvc.submitPractitionerTypeToMdm(criteria, theRequest);
|
long submittedCount = synchronousMdmSubmit(PRACTITIONER_RESOURCE, null, criteria, theRequest);
|
||||||
return buildMdmOutParametersWithCount(submittedCount);
|
return buildMdmOutParametersWithCount(submittedCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,4 +526,58 @@ public class MdmProviderDstu3Plus extends BaseMdmProvider {
|
||||||
IIdType idType = MdmControllerUtil.getGoldenIdDtOrThrowException(theParamName, theResourceId);
|
IIdType idType = MdmControllerUtil.getGoldenIdDtOrThrowException(theParamName, theResourceId);
|
||||||
return idType.getResourceType();
|
return idType.getResourceType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long synchronousMdmSubmit(
|
||||||
|
String theResourceType, IIdType theIdType, String theCriteria, RequestDetails theRequestDetails) {
|
||||||
|
long submittedCount = -1;
|
||||||
|
List<String> urls = new ArrayList<>();
|
||||||
|
if (theIdType != null) {
|
||||||
|
submittedCount = mdmSubmitWithId(theIdType, theRequestDetails, urls);
|
||||||
|
} else if (isNotBlank(theResourceType)) {
|
||||||
|
submittedCount = submitResourceTypeWithCriteria(theResourceType, theCriteria, theRequestDetails, urls);
|
||||||
|
} else {
|
||||||
|
submittedCount = submitAll(theCriteria, theRequestDetails, urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_SUBMIT)) {
|
||||||
|
// MDM_SUBMIT synchronous submit
|
||||||
|
MdmSubmitEvent submitEvent = new MdmSubmitEvent();
|
||||||
|
submitEvent.setBatchJob(false);
|
||||||
|
submitEvent.setUrls(urls);
|
||||||
|
|
||||||
|
HookParams hookParams = new HookParams();
|
||||||
|
hookParams.add(RequestDetails.class, theRequestDetails);
|
||||||
|
hookParams.add(MdmSubmitEvent.class, submitEvent);
|
||||||
|
myInterceptorBroadcaster.callHooks(Pointcut.MDM_SUBMIT, hookParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
return submittedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long mdmSubmitWithId(IIdType theIdType, RequestDetails theRequestDetails, List<String> theUrls) {
|
||||||
|
theUrls.add(theIdType.getValue());
|
||||||
|
return myMdmSubmitSvc.submitSourceResourceToMdm(theIdType, theRequestDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long submitResourceTypeWithCriteria(
|
||||||
|
String theResourceType, String theCriteria, RequestDetails theRequestDetails, List<String> theUrls) {
|
||||||
|
String url = theResourceType;
|
||||||
|
if (isNotEmpty(theCriteria)) {
|
||||||
|
url += "?" + theCriteria;
|
||||||
|
}
|
||||||
|
theUrls.add(url);
|
||||||
|
|
||||||
|
return myMdmSubmitSvc.submitSourceResourceTypeToMdm(theResourceType, theCriteria, theRequestDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long submitAll(String theCriteria, RequestDetails theRequestDetails, List<String> theUrls) {
|
||||||
|
// submitAllSourceTypes only runs through
|
||||||
|
// valid MDM source types
|
||||||
|
List<String> resourceTypes = myMdmSettings.getMdmRules().getMdmTypes();
|
||||||
|
for (String resourceType : resourceTypes) {
|
||||||
|
String url = resourceType + (isNotEmpty(theCriteria) ? "?" + theCriteria : "");
|
||||||
|
theUrls.add(url);
|
||||||
|
}
|
||||||
|
return myMdmSubmitSvc.submitAllSourceTypesToMdm(theCriteria, theRequestDetails);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.mdm.provider;
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.i18n.Msg;
|
import ca.uhn.fhir.i18n.Msg;
|
||||||
|
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
import ca.uhn.fhir.mdm.api.IMdmControllerSvc;
|
||||||
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
import ca.uhn.fhir.mdm.api.IMdmSettings;
|
||||||
|
@ -55,19 +56,28 @@ public class MdmProviderLoader {
|
||||||
@Autowired
|
@Autowired
|
||||||
private JpaStorageSettings myStorageSettings;
|
private JpaStorageSettings myStorageSettings;
|
||||||
|
|
||||||
private MdmProviderDstu3Plus myMdmProvider;
|
@Autowired
|
||||||
|
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
|
private BaseMdmProvider myMdmProvider;
|
||||||
private MdmLinkHistoryProviderDstu3Plus myMdmHistoryProvider;
|
private MdmLinkHistoryProviderDstu3Plus myMdmHistoryProvider;
|
||||||
|
|
||||||
public void loadProvider() {
|
public void loadProvider() {
|
||||||
switch (myFhirContext.getVersion().getVersion()) {
|
switch (myFhirContext.getVersion().getVersion()) {
|
||||||
case DSTU3:
|
case DSTU3:
|
||||||
case R4:
|
case R4:
|
||||||
myMdmProvider = new MdmProviderDstu3Plus(
|
myResourceProviderFactory.addSupplier(() -> new MdmProviderDstu3Plus(
|
||||||
myFhirContext, myMdmControllerSvc, myMdmControllerHelper, myMdmSubmitSvc, myMdmSettings);
|
myFhirContext,
|
||||||
myResourceProviderFactory.addSupplier(() -> myMdmProvider);
|
myMdmControllerSvc,
|
||||||
|
myMdmControllerHelper,
|
||||||
|
myMdmSubmitSvc,
|
||||||
|
myInterceptorBroadcaster,
|
||||||
|
myMdmSettings));
|
||||||
if (myStorageSettings.isNonResourceDbHistoryEnabled()) {
|
if (myStorageSettings.isNonResourceDbHistoryEnabled()) {
|
||||||
myMdmHistoryProvider = new MdmLinkHistoryProviderDstu3Plus(myFhirContext, myMdmControllerSvc);
|
myResourceProviderFactory.addSupplier(() -> {
|
||||||
myResourceProviderFactory.addSupplier(() -> myMdmHistoryProvider);
|
return new MdmLinkHistoryProviderDstu3Plus(
|
||||||
|
myFhirContext, myMdmControllerSvc, myInterceptorBroadcaster);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-caching-api</artifactId>
|
<artifactId>hapi-fhir-caching-api</artifactId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
<artifactId>hapi-fhir-serviceloaders</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot</artifactId>
|
<artifactId>hapi-fhir-spring-boot</artifactId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-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>6.9.1-SNAPSHOT</version>
|
<version>6.9.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue