3693 Search by id is returning a deleted resource with a client-generated id (#3694)
- Added functionality to optionally filter out deleted resources when resolving forced ids to persistent ids - Bumps version Co-authored-by: nathaniel.doef <nathaniel.doef@smilecdr.com> Co-authored-by: Ken Stevens <ken@smilecdr.com>
This commit is contained in:
parent
3a28920ea7
commit
b68ccb373a
|
@ -4,7 +4,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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
<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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>HAPI FHIR BOM</name>
|
<name>HAPI FHIR BOM</name>
|
||||||
|
|
||||||
<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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom</relativePath>
|
<relativePath>../../hapi-deployable-pom</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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 3693
|
||||||
|
jira: SMILE-4185
|
||||||
|
title: "Previously, deleted resources with client generated ids were being included in the
|
||||||
|
bundle total when searching by _id. This has been corrected by adding functionality to optionally filter
|
||||||
|
out deleted resources when resolving forced ids to persistent ids."
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package ca.uhn.fhir.jpa.dao.data;
|
package ca.uhn.fhir.jpa.dao.data;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.custom.IForcedIdQueries;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -29,10 +30,10 @@ import java.util.Optional;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface IForcedIdDao extends JpaRepository<ForcedId, Long>, IHapiFhirJpaRepository, IForcedIdQueries {
|
||||||
|
|
||||||
public interface IForcedIdDao extends JpaRepository<ForcedId, Long>, IHapiFhirJpaRepository {
|
@Query("SELECT f FROM ForcedId f WHERE f.myResourcePid IN (:resource_pids)")
|
||||||
|
|
||||||
@Query("SELECT f FROM ForcedId f WHERE myResourcePid IN (:resource_pids)")
|
|
||||||
List<ForcedId> findAllByResourcePid(@Param("resource_pids") List<Long> theResourcePids);
|
List<ForcedId> findAllByResourcePid(@Param("resource_pids") List<Long> theResourcePids);
|
||||||
|
|
||||||
@Query("SELECT f FROM ForcedId f WHERE f.myResourcePid = :resource_pid")
|
@Query("SELECT f FROM ForcedId f WHERE f.myResourcePid = :resource_pid")
|
||||||
|
@ -41,54 +42,4 @@ public interface IForcedIdDao extends JpaRepository<ForcedId, Long>, IHapiFhirJp
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("DELETE FROM ForcedId t WHERE t.myId = :pid")
|
@Query("DELETE FROM ForcedId t WHERE t.myId = :pid")
|
||||||
void deleteByPid(@Param("pid") Long theId);
|
void deleteByPid(@Param("pid") Long theId);
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
|
||||||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
|
||||||
*/
|
|
||||||
@Query("" +
|
|
||||||
"SELECT " +
|
|
||||||
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
|
||||||
"FROM ForcedId f " +
|
|
||||||
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
|
||||||
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id )")
|
|
||||||
Collection<Object[]> findAndResolveByForcedIdWithNoType(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedIds);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
|
||||||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
|
||||||
*/
|
|
||||||
@Query("" +
|
|
||||||
"SELECT " +
|
|
||||||
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
|
||||||
"FROM ForcedId f " +
|
|
||||||
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
|
||||||
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id ) AND f.myPartitionIdValue IN :partition_id")
|
|
||||||
Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartition(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedIds, @Param("partition_id") Collection<Integer> thePartitionId);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
|
||||||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
|
||||||
*/
|
|
||||||
@Query("" +
|
|
||||||
"SELECT " +
|
|
||||||
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
|
||||||
"FROM ForcedId f " +
|
|
||||||
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
|
||||||
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id ) AND f.myPartitionIdValue IS NULL")
|
|
||||||
Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionNull(@Param("resource_type") String theResourceType, @Param("forced_id") Collection<String> theForcedIds);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
|
||||||
* is an object array, where the order matters (the array represents columns returned by the query). Be careful if you change this query in any way.
|
|
||||||
*/
|
|
||||||
@Query("" +
|
|
||||||
"SELECT " +
|
|
||||||
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
|
||||||
"FROM ForcedId f " +
|
|
||||||
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
|
||||||
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id ) AND (f.myPartitionIdValue IS NULL OR f.myPartitionIdValue IN :partition_id)")
|
|
||||||
Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(@Param("resource_type") String theNextResourceType, @Param("forced_id") Collection<String> theNextIds, @Param("forced_id") List<Integer> thePartitionIdsWithoutDefault);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.data.custom;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
// Don't change the name of this class. Spring Data requires the name to match.
|
||||||
|
// See https://stackoverflow.com/questions/11880924/how-to-add-custom-method-to-spring-data-jpa
|
||||||
|
public class IForcedIdDaoImpl implements IForcedIdQueries {
|
||||||
|
|
||||||
|
@PersistenceContext
|
||||||
|
private EntityManager myEntityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are not filtered.
|
||||||
|
*/
|
||||||
|
public Collection<Object[]> findAndResolveByForcedIdWithNoTypeIncludeDeleted(String theResourceType, Collection<String> theForcedIds) {
|
||||||
|
return findAndResolveByForcedIdWithNoType(theResourceType, theForcedIds, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered. Be careful if you change this query in any way.
|
||||||
|
*/
|
||||||
|
public Collection<Object[]> findAndResolveByForcedIdWithNoType(String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted) {
|
||||||
|
String query = "" +
|
||||||
|
"SELECT " +
|
||||||
|
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
||||||
|
"FROM ForcedId f " +
|
||||||
|
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
||||||
|
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id )";
|
||||||
|
|
||||||
|
if (theExcludeDeleted) {
|
||||||
|
query += " AND t.myDeleted IS NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
return myEntityManager.createQuery(query)
|
||||||
|
.setParameter("resource_type", theResourceType)
|
||||||
|
.setParameter("forced_id", theForcedIds)
|
||||||
|
.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered. Be careful if you change this query in any way.
|
||||||
|
*/
|
||||||
|
public Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartition(String theResourceType, Collection<String> theForcedIds, Collection<Integer> thePartitionId, boolean theExcludeDeleted) {
|
||||||
|
String query = "" +
|
||||||
|
"SELECT " +
|
||||||
|
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
||||||
|
"FROM ForcedId f " +
|
||||||
|
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
||||||
|
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id ) AND f.myPartitionIdValue IN ( :partition_id )";
|
||||||
|
|
||||||
|
|
||||||
|
if (theExcludeDeleted) {
|
||||||
|
query += " AND t.myDeleted IS NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
return myEntityManager.createQuery(query)
|
||||||
|
.setParameter("resource_type", theResourceType)
|
||||||
|
.setParameter("forced_id", theForcedIds)
|
||||||
|
.setParameter("partition_id", thePartitionId)
|
||||||
|
.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered. Be careful if you change this query in any way.
|
||||||
|
*/
|
||||||
|
public Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionNull(String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted) {
|
||||||
|
String query = "" +
|
||||||
|
"SELECT " +
|
||||||
|
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
||||||
|
"FROM ForcedId f " +
|
||||||
|
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
||||||
|
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id ) AND f.myPartitionIdValue IS NULL";
|
||||||
|
|
||||||
|
|
||||||
|
if (theExcludeDeleted) {
|
||||||
|
query += " AND t.myDeleted IS NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
return myEntityManager.createQuery(query)
|
||||||
|
.setParameter("resource_type", theResourceType)
|
||||||
|
.setParameter("forced_id", theForcedIds)
|
||||||
|
.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered. Be careful if you change this query in any way.
|
||||||
|
*/
|
||||||
|
public Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(String theResourceType, Collection<String> theForcedIds, List<Integer> thePartitionIdsWithoutDefault, boolean theExcludeDeleted) {
|
||||||
|
String query = "" +
|
||||||
|
"SELECT " +
|
||||||
|
" f.myResourceType, f.myResourcePid, f.myForcedId, t.myDeleted " +
|
||||||
|
"FROM ForcedId f " +
|
||||||
|
"JOIN ResourceTable t ON t.myId = f.myResourcePid " +
|
||||||
|
"WHERE f.myResourceType = :resource_type AND f.myForcedId IN ( :forced_id ) AND (f.myPartitionIdValue IS NULL OR f.myPartitionIdValue IN ( :partition_id ))";
|
||||||
|
|
||||||
|
if (theExcludeDeleted) {
|
||||||
|
query += " AND t.myDeleted IS NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
return myEntityManager.createQuery(query)
|
||||||
|
.setParameter("resource_type", theResourceType)
|
||||||
|
.setParameter("forced_id", theForcedIds)
|
||||||
|
.setParameter("partition_id", thePartitionIdsWithoutDefault)
|
||||||
|
.getResultList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.data.custom;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
|
||||||
|
* %%
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IForcedIdQueries {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources should not be filtered.
|
||||||
|
*/
|
||||||
|
Collection<Object[]> findAndResolveByForcedIdWithNoTypeIncludeDeleted(String theResourceType, Collection<String> theForcedIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered.
|
||||||
|
*/
|
||||||
|
Collection<Object[]> findAndResolveByForcedIdWithNoType(String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered.
|
||||||
|
*/
|
||||||
|
Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartition(String theResourceType, Collection<String> theForcedIds, Collection<Integer> thePartitionId, boolean theExcludeDeleted);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered.
|
||||||
|
*/
|
||||||
|
Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionNull(String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a Collection where each row is an element in the collection. Each element in the collection
|
||||||
|
* is an object array, where the order matters (the array represents columns returned by the query).
|
||||||
|
* Deleted resources are optionally filtered.
|
||||||
|
*/
|
||||||
|
Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(String theNextResourceType, Collection<String> theNextIds, List<Integer> thePartitionIdsWithoutDefault, boolean theExcludeDeleted);
|
||||||
|
|
||||||
|
}
|
|
@ -31,7 +31,6 @@ import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||||
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
||||||
import ca.uhn.fhir.jpa.model.cross.ResourceLookup;
|
import ca.uhn.fhir.jpa.model.cross.ResourceLookup;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
|
||||||
import ca.uhn.fhir.jpa.search.builder.SearchBuilder;
|
import ca.uhn.fhir.jpa.search.builder.SearchBuilder;
|
||||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||||
import ca.uhn.fhir.jpa.util.QueryChunker;
|
import ca.uhn.fhir.jpa.util.QueryChunker;
|
||||||
|
@ -128,12 +127,26 @@ public class IdHelperService implements IIdHelperService {
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException {
|
public IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException {
|
||||||
|
return resolveResourceIdentity(theRequestPartitionId, theResourceType, theResourceId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a forced ID, convert it to its Long value. Since you are allowed to use string IDs for resources, we need to
|
||||||
|
* convert those to the underlying Long values that are stored, for lookup and comparison purposes.
|
||||||
|
* Optionally filters out deleted resources.
|
||||||
|
*
|
||||||
|
* @throws ResourceNotFoundException If the ID can not be found
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId, boolean theExcludeDeleted) throws ResourceNotFoundException {
|
||||||
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
|
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
|
||||||
assert theRequestPartitionId != null;
|
assert theRequestPartitionId != null;
|
||||||
|
|
||||||
IdDt id = new IdDt(theResourceType, theResourceId);
|
IdDt id = new IdDt(theResourceType, theResourceId);
|
||||||
Map<String, List<IResourceLookup>> matches = translateForcedIdToPids(theRequestPartitionId,
|
Map<String, List<IResourceLookup>> matches = translateForcedIdToPids(theRequestPartitionId,
|
||||||
Collections.singletonList(id));
|
Collections.singletonList(id),
|
||||||
|
theExcludeDeleted);
|
||||||
|
|
||||||
// We only pass 1 input in so only 0..1 will come back
|
// We only pass 1 input in so only 0..1 will come back
|
||||||
if (matches.isEmpty() || !matches.containsKey(theResourceId)) {
|
if (matches.isEmpty() || !matches.containsKey(theResourceId)) {
|
||||||
|
@ -155,14 +168,27 @@ public class IdHelperService implements IIdHelperService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a mapping of Id -> ResourcePersistentId.
|
* Returns a mapping of Id -> ResourcePersistentId.
|
||||||
* If any resource is not found, it will throw ResourceNotFound exception
|
* If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned)
|
||||||
* (and no map will be returned)
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId,
|
public Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId,
|
||||||
String theResourceType,
|
String theResourceType,
|
||||||
List<String> theIds) {
|
List<String> theIds) {
|
||||||
|
return resolveResourcePersistentIds(theRequestPartitionId, theResourceType, theIds, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a mapping of Id -> ResourcePersistentId.
|
||||||
|
* If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned)
|
||||||
|
* Optionally filters out deleted resources.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId,
|
||||||
|
String theResourceType,
|
||||||
|
List<String> theIds,
|
||||||
|
boolean theExcludeDeleted) {
|
||||||
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
|
assert myDontCheckActiveTransactionForUnitTest || TransactionSynchronizationManager.isSynchronizationActive();
|
||||||
Validate.notNull(theIds, "theIds cannot be null");
|
Validate.notNull(theIds, "theIds cannot be null");
|
||||||
Validate.isTrue(!theIds.isEmpty(), "theIds must not be empty");
|
Validate.isTrue(!theIds.isEmpty(), "theIds must not be empty");
|
||||||
|
@ -179,7 +205,7 @@ public class IdHelperService implements IIdHelperService {
|
||||||
// is a forced id
|
// is a forced id
|
||||||
// we must resolve!
|
// we must resolve!
|
||||||
if (myDaoConfig.isDeleteEnabled()) {
|
if (myDaoConfig.isDeleteEnabled()) {
|
||||||
retVal = new ResourcePersistentId(resolveResourceIdentity(theRequestPartitionId, theResourceType, id).getResourceId());
|
retVal = new ResourcePersistentId(resolveResourceIdentity(theRequestPartitionId, theResourceType, id, theExcludeDeleted).getResourceId());
|
||||||
retVals.put(id, retVal);
|
retVals.put(id, retVal);
|
||||||
} else {
|
} else {
|
||||||
// fetch from cache... adding to cache if not available
|
// fetch from cache... adding to cache if not available
|
||||||
|
@ -209,11 +235,22 @@ public class IdHelperService implements IIdHelperService {
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId) {
|
public ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId) {
|
||||||
|
return resolveResourcePersistentIds(theRequestPartitionId, theResourceType, theId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a resource type and ID, determines the internal persistent ID for the resource.
|
||||||
|
* Optionally filters out deleted resources.
|
||||||
|
*
|
||||||
|
* @throws ResourceNotFoundException If the ID can not be found
|
||||||
|
*/
|
||||||
|
public ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId, boolean theExcludeDeleted){
|
||||||
Validate.notNull(theId, "theId must not be null");
|
Validate.notNull(theId, "theId must not be null");
|
||||||
|
|
||||||
Map<String, ResourcePersistentId> retVal = resolveResourcePersistentIds(theRequestPartitionId,
|
Map<String, ResourcePersistentId> retVal = resolveResourcePersistentIds(theRequestPartitionId,
|
||||||
theResourceType,
|
theResourceType,
|
||||||
Collections.singletonList(theId));
|
Collections.singletonList(theId),
|
||||||
|
theExcludeDeleted);
|
||||||
return retVal.get(theId); // should be only one
|
return retVal.get(theId); // should be only one
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +443,7 @@ public class IdHelperService implements IIdHelperService {
|
||||||
return typeToIds;
|
return typeToIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, List<IResourceLookup>> translateForcedIdToPids(@Nonnull RequestPartitionId theRequestPartitionId, Collection<IIdType> theId) {
|
private Map<String, List<IResourceLookup>> translateForcedIdToPids(@Nonnull RequestPartitionId theRequestPartitionId, Collection<IIdType> theId, boolean theExcludeDeleted) {
|
||||||
assert theRequestPartitionId != null;
|
assert theRequestPartitionId != null;
|
||||||
|
|
||||||
theId.forEach(id -> Validate.isTrue(id.hasIdPart()));
|
theId.forEach(id -> Validate.isTrue(id.hasIdPart()));
|
||||||
|
@ -455,14 +492,14 @@ public class IdHelperService implements IIdHelperService {
|
||||||
assert isNotBlank(nextResourceType);
|
assert isNotBlank(nextResourceType);
|
||||||
|
|
||||||
if (requestPartitionId.isAllPartitions()) {
|
if (requestPartitionId.isAllPartitions()) {
|
||||||
views = myForcedIdDao.findAndResolveByForcedIdWithNoType(nextResourceType, nextIds);
|
views = myForcedIdDao.findAndResolveByForcedIdWithNoType(nextResourceType, nextIds, theExcludeDeleted);
|
||||||
} else {
|
} else {
|
||||||
if (requestPartitionId.isDefaultPartition()) {
|
if (requestPartitionId.isDefaultPartition()) {
|
||||||
views = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionNull(nextResourceType, nextIds);
|
views = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionNull(nextResourceType, nextIds, theExcludeDeleted);
|
||||||
} else if (requestPartitionId.hasDefaultPartitionId()) {
|
} else if (requestPartitionId.hasDefaultPartitionId()) {
|
||||||
views = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(nextResourceType, nextIds, requestPartitionId.getPartitionIdsWithoutDefault());
|
views = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(nextResourceType, nextIds, requestPartitionId.getPartitionIdsWithoutDefault(), theExcludeDeleted);
|
||||||
} else {
|
} else {
|
||||||
views = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartition(nextResourceType, nextIds, requestPartitionId.getPartitionIds());
|
views = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartition(nextResourceType, nextIds, requestPartitionId.getPartitionIds(), theExcludeDeleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +508,7 @@ public class IdHelperService implements IIdHelperService {
|
||||||
Long resourcePid = (Long) next[1];
|
Long resourcePid = (Long) next[1];
|
||||||
String forcedId = (String) next[2];
|
String forcedId = (String) next[2];
|
||||||
Date deletedAt = (Date) next[3];
|
Date deletedAt = (Date) next[3];
|
||||||
|
|
||||||
ResourceLookup lookup = new ResourceLookup(resourceType, resourcePid, deletedAt);
|
ResourceLookup lookup = new ResourceLookup(resourceType, resourcePid, deletedAt);
|
||||||
if (!retVal.containsKey(forcedId)) {
|
if (!retVal.containsKey(forcedId)) {
|
||||||
retVal.put(forcedId, new ArrayList<>());
|
retVal.put(forcedId, new ArrayList<>());
|
||||||
|
|
|
@ -22,7 +22,6 @@ package ca.uhn.fhir.jpa.search.builder.predicate;
|
||||||
|
|
||||||
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.dao.index.IdHelperService;
|
|
||||||
import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
|
import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
|
||||||
import ca.uhn.fhir.jpa.search.builder.QueryStack;
|
import ca.uhn.fhir.jpa.search.builder.QueryStack;
|
||||||
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
|
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
|
||||||
|
@ -83,7 +82,8 @@ public class ResourceIdPredicateBuilder extends BasePredicateBuilder {
|
||||||
}
|
}
|
||||||
haveValue = true;
|
haveValue = true;
|
||||||
try {
|
try {
|
||||||
ResourcePersistentId pid = myIdHelperService.resolveResourcePersistentIds(theRequestPartitionId, theResourceName, valueAsId.getIdPart());
|
boolean excludeDeleted = true;
|
||||||
|
ResourcePersistentId pid = myIdHelperService.resolveResourcePersistentIds(theRequestPartitionId, theResourceName, valueAsId.getIdPart(), excludeDeleted);
|
||||||
orPids.add(pid);
|
orPids.add(pid);
|
||||||
} catch (ResourceNotFoundException e) {
|
} catch (ResourceNotFoundException e) {
|
||||||
// This is not an error in a search, it just results in no matches
|
// This is not an error in a search, it just results in no matches
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ package ca.uhn.fhir.jpa.dao.index;
|
||||||
|
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
||||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||||
|
import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
|
||||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
@ -18,12 +18,21 @@ import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class IdHelperServiceTest {
|
public class IdHelperServiceTest {
|
||||||
|
|
||||||
|
@ -88,10 +97,10 @@ public class IdHelperServiceTest {
|
||||||
};
|
};
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Mockito.when(myDaoConfig.isDeleteEnabled())
|
when(myDaoConfig.isDeleteEnabled())
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
Mockito.when(myForcedIdDao.findAndResolveByForcedIdWithNoType(Mockito.anyString(),
|
when(myForcedIdDao.findAndResolveByForcedIdWithNoType(Mockito.anyString(),
|
||||||
Mockito.anyList()))
|
Mockito.anyList(), Mockito.anyBoolean()))
|
||||||
.thenReturn(Collections.singletonList(redView))
|
.thenReturn(Collections.singletonList(redView))
|
||||||
.thenReturn(Collections.singletonList(blueView));
|
.thenReturn(Collections.singletonList(blueView));
|
||||||
|
|
||||||
|
@ -119,9 +128,9 @@ public class IdHelperServiceTest {
|
||||||
ResourcePersistentId blue = new ResourcePersistentId("Patient", new Long(456l));
|
ResourcePersistentId blue = new ResourcePersistentId("Patient", new Long(456l));
|
||||||
|
|
||||||
// we will pretend the lookup value is in the cache
|
// we will pretend the lookup value is in the cache
|
||||||
Mockito.when(myMemoryCacheService.getThenPutAfterCommit(Mockito.any(MemoryCacheService.CacheEnum.class),
|
when(myMemoryCacheService.getThenPutAfterCommit(any(MemoryCacheService.CacheEnum.class),
|
||||||
Mockito.anyString(),
|
Mockito.anyString(),
|
||||||
Mockito.any(Function.class)))
|
any(Function.class)))
|
||||||
.thenReturn(red)
|
.thenReturn(red)
|
||||||
.thenReturn(blue);
|
.thenReturn(blue);
|
||||||
|
|
||||||
|
@ -139,4 +148,58 @@ public class IdHelperServiceTest {
|
||||||
Assertions.assertEquals(red, map.get("RED"));
|
Assertions.assertEquals(red, map.get("RED"));
|
||||||
Assertions.assertEquals(blue, map.get("BLUE"));
|
Assertions.assertEquals(blue, map.get("BLUE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveResourceIdentity_defaultFunctionality(){
|
||||||
|
RequestPartitionId partitionId = RequestPartitionId.fromPartitionIdAndName(1, "partition");
|
||||||
|
String resourceType = "Patient";
|
||||||
|
String resourceForcedId = "AAA";
|
||||||
|
|
||||||
|
Object[] forcedIdView = new Object[4];
|
||||||
|
forcedIdView[0] = resourceType;
|
||||||
|
forcedIdView[1] = 1L;
|
||||||
|
forcedIdView[2] = resourceForcedId;
|
||||||
|
forcedIdView[3] = null;
|
||||||
|
|
||||||
|
Collection<Object[]> testForcedIdViews = new ArrayList<>();
|
||||||
|
testForcedIdViews.add(forcedIdView);
|
||||||
|
when(myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartition(any(), any(), any(), anyBoolean())).thenReturn(testForcedIdViews);
|
||||||
|
|
||||||
|
IResourceLookup result = myHelperService.resolveResourceIdentity(partitionId, resourceType, resourceForcedId);
|
||||||
|
assertEquals(forcedIdView[0], result.getResourceType());
|
||||||
|
assertEquals(forcedIdView[1], result.getResourceId());
|
||||||
|
assertEquals(forcedIdView[3], result.getDeleted());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveResourcePersistentIds_mapDefaultFunctionality(){
|
||||||
|
RequestPartitionId partitionId = RequestPartitionId.fromPartitionIdAndName(1, "partition");
|
||||||
|
String resourceType = "Patient";
|
||||||
|
List<String> ids = Arrays.asList("A", "B", "C");
|
||||||
|
|
||||||
|
ResourcePersistentId resourcePersistentId1 = new ResourcePersistentId("TEST1");
|
||||||
|
ResourcePersistentId resourcePersistentId2 = new ResourcePersistentId("TEST2");
|
||||||
|
ResourcePersistentId resourcePersistentId3 = new ResourcePersistentId("TEST3");
|
||||||
|
when(myMemoryCacheService.getThenPutAfterCommit(any(), any(), any()))
|
||||||
|
.thenReturn(resourcePersistentId1)
|
||||||
|
.thenReturn(resourcePersistentId2)
|
||||||
|
.thenReturn(resourcePersistentId3);
|
||||||
|
Map<String, ResourcePersistentId> result = myHelperService.resolveResourcePersistentIds(partitionId, resourceType, ids);
|
||||||
|
assertThat(result.keySet(), hasSize(3));
|
||||||
|
assertEquals("TEST1", result.get("A").getId());
|
||||||
|
assertEquals("TEST2", result.get("B").getId());
|
||||||
|
assertEquals("TEST3", result.get("C").getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveResourcePersistentIds_resourcePidDefaultFunctionality(){
|
||||||
|
RequestPartitionId partitionId = RequestPartitionId.fromPartitionIdAndName(1, "partition");
|
||||||
|
String resourceType = "Patient";
|
||||||
|
String id = "A";
|
||||||
|
|
||||||
|
ResourcePersistentId resourcePersistentId1 = new ResourcePersistentId(id);
|
||||||
|
when(myMemoryCacheService.getThenPutAfterCommit(any(), any(), any())).thenReturn(resourcePersistentId1);
|
||||||
|
ResourcePersistentId result = myHelperService.resolveResourcePersistentIds(partitionId, resourceType, id);
|
||||||
|
assertEquals(id, result.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -877,8 +877,8 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
|
||||||
assertEquals(1, StringUtils.countMatches(selectQuery.toLowerCase(), "t0.res_deleted_at is null"), selectQuery);
|
assertEquals(1, StringUtils.countMatches(selectQuery.toLowerCase(), "t0.res_deleted_at is null"), selectQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the resource - The searches should generate similar SQL now, but
|
// Delete the resource - There should only be one search performed because deleted resources will
|
||||||
// not actually return the result
|
// be filtered out in the query that resolves forced ids to persistent ids
|
||||||
myObservationDao.delete(new IdType("Observation/A"));
|
myObservationDao.delete(new IdType("Observation/A"));
|
||||||
myObservationDao.delete(new IdType("Observation/" + obs2id));
|
myObservationDao.delete(new IdType("Observation/" + obs2id));
|
||||||
|
|
||||||
|
@ -892,14 +892,10 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
|
||||||
assertEquals(0, outcome.getResources(0, 999).size());
|
assertEquals(0, outcome.getResources(0, 999).size());
|
||||||
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
myCaptureQueriesListener.logSelectQueriesForCurrentThread();
|
||||||
|
|
||||||
|
assertEquals(1, myCaptureQueriesListener.getSelectQueriesForCurrentThread().size());
|
||||||
String selectQuery = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, false);
|
String selectQuery = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(0).getSql(true, false);
|
||||||
assertEquals(1, StringUtils.countMatches(selectQuery.toLowerCase(), "forcedid0_.resource_type='observation'"), selectQuery);
|
assertEquals(1, StringUtils.countMatches(selectQuery.toLowerCase(), "forcedid0_.resource_type='observation'"), selectQuery);
|
||||||
assertEquals(1, StringUtils.countMatches(selectQuery.toLowerCase(), "forcedid0_.forced_id in ('a')"), selectQuery);
|
assertEquals(1, StringUtils.countMatches(selectQuery.toLowerCase(), "forcedid0_.forced_id in ('a')"), selectQuery);
|
||||||
|
|
||||||
selectQuery = myCaptureQueriesListener.getSelectQueriesForCurrentThread().get(1).getSql(true, false);
|
|
||||||
assertEquals(1, StringUtils.countMatches(selectQuery.toLowerCase(), "select t0.res_id from hfj_resource t0"), selectQuery);
|
|
||||||
assertEquals(0, StringUtils.countMatches(selectQuery.toLowerCase(), "t0.res_type = 'observation'"), selectQuery);
|
|
||||||
assertEquals(0, StringUtils.countMatches(selectQuery.toLowerCase(), "t0.res_deleted_at is null"), selectQuery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search by ID where at least one ID is a numeric ID
|
// Search by ID where at least one ID is a numeric ID
|
||||||
|
|
|
@ -36,6 +36,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
@ -151,6 +153,187 @@ public class MultitenantServerR4Test extends BaseMultitenantResourceProviderR4Te
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAndResolveByForcedIdWithNoType() {
|
||||||
|
// Create patients
|
||||||
|
String patientId = "AAA";
|
||||||
|
IIdType idA = createPatient(withId(patientId));
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeIncludeDeleted(
|
||||||
|
"Patient", Arrays.asList(patientId)
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoType(
|
||||||
|
"Patient", Arrays.asList(patientId), true
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete resource
|
||||||
|
deletePatient(JpaConstants.DEFAULT_PARTITION_NAME, idA);
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeIncludeDeleted(
|
||||||
|
"Patient", Arrays.asList(patientId)
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoType(
|
||||||
|
"Patient", Arrays.asList(patientId), true
|
||||||
|
);
|
||||||
|
assertThat(forcedIds, hasSize(0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAndResolveByForcedIdWithNoTypeInPartitionNull() {
|
||||||
|
// Create patients
|
||||||
|
String patientId = "AAA";
|
||||||
|
IIdType idA = createPatient(withId(patientId));
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionNull(
|
||||||
|
"Patient", Arrays.asList(patientId), false
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionNull(
|
||||||
|
"Patient", Arrays.asList(patientId), true
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete resource
|
||||||
|
deletePatient(JpaConstants.DEFAULT_PARTITION_NAME, idA);
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionNull(
|
||||||
|
"Patient", Arrays.asList(patientId), false
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionNull(
|
||||||
|
"Patient", Arrays.asList(patientId), true
|
||||||
|
);
|
||||||
|
assertEquals(0, forcedIds.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(){
|
||||||
|
// Create patients
|
||||||
|
String patientId = "AAA";
|
||||||
|
IIdType idA = createPatient(withTenant(TENANT_A), withId(patientId));
|
||||||
|
|
||||||
|
createPatient(withId("BBB"));
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID), false
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID), true
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
deletePatient(TENANT_A, idA);
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID), false
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID), true
|
||||||
|
);
|
||||||
|
assertEquals(0, forcedIds.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAndResolveByForcedIdWithNoTypeInPartition() throws IOException {
|
||||||
|
// Create patients
|
||||||
|
String patientId = "AAA";
|
||||||
|
IIdType idA = createPatient(withTenant(TENANT_A), withId(patientId));
|
||||||
|
|
||||||
|
createPatient(withTenant(TENANT_B), withId("BBB"));
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartition(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID, TENANT_B_ID), false
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartition(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID, TENANT_B_ID), true
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
deletePatient(TENANT_A, idA);
|
||||||
|
|
||||||
|
// Search and include deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartition(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID, TENANT_B_ID), false
|
||||||
|
);
|
||||||
|
assertContainsSingleForcedId(forcedIds, patientId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search and filter deleted
|
||||||
|
runInTransaction(() -> {
|
||||||
|
Collection<Object[]> forcedIds = myForcedIdDao.findAndResolveByForcedIdWithNoTypeInPartition(
|
||||||
|
"Patient", Arrays.asList(patientId), Arrays.asList(TENANT_A_ID, TENANT_B_ID), true
|
||||||
|
);
|
||||||
|
assertEquals(0, forcedIds.size());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertContainsSingleForcedId(Collection<Object[]> forcedIds, String patientId){
|
||||||
|
assertEquals(1, forcedIds.size());
|
||||||
|
assertEquals(patientId, forcedIds.stream().toList().get(0)[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deletePatient(String tenantId, IIdType patientId){
|
||||||
|
SystemRequestDetails requestDetails = new SystemRequestDetails();
|
||||||
|
requestDetails.setTenantId(tenantId);
|
||||||
|
myPatientDao.delete(patientId, requestDetails);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateAndRead_NonPartitionableResource_DefaultTenant() {
|
public void testCreateAndRead_NonPartitionableResource_DefaultTenant() {
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ import ca.uhn.fhir.util.StopWatch;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
@ -3986,6 +3987,74 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchByIdForDeletedResourceWithClientAssignedId() throws IOException {
|
||||||
|
// Create with client assigned ID
|
||||||
|
Patient p = new Patient();
|
||||||
|
String patientId = "AAA";
|
||||||
|
p.setId(patientId);
|
||||||
|
|
||||||
|
MethodOutcome outcome = myClient.update().resource(p).execute();
|
||||||
|
assertTrue(outcome.getCreated());
|
||||||
|
|
||||||
|
Patient createdPatient = (Patient) outcome.getResource();
|
||||||
|
|
||||||
|
// Search
|
||||||
|
Bundle search1 = (Bundle) myClient.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.RES_ID.exactly().identifier(patientId))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals(1, search1.getTotal());
|
||||||
|
assertEquals(patientId, search1.getEntry().get(0).getResource().getIdElement().getIdPart());
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
outcome = myClient.delete().resource(createdPatient).execute();
|
||||||
|
assertNull(outcome.getResource());
|
||||||
|
|
||||||
|
// Search
|
||||||
|
Bundle search2 = (Bundle) myClient.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.RES_ID.exactly().identifier(patientId))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertTrue(CollectionUtils.isEmpty(search2.getEntry()));
|
||||||
|
assertEquals(0, search2.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchByIdForDeletedResourceWithServerAssignedId() throws IOException {
|
||||||
|
// Create with server assigned ID
|
||||||
|
Patient p = new Patient();
|
||||||
|
MethodOutcome outcome = myClient.create().resource(p).execute();
|
||||||
|
assertTrue(outcome.getCreated());
|
||||||
|
|
||||||
|
Patient createdPatient = (Patient) outcome.getResource();
|
||||||
|
String patientId = createdPatient.getIdElement().getIdPart();
|
||||||
|
|
||||||
|
// Search
|
||||||
|
Bundle search1 = (Bundle) myClient.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.RES_ID.exactly().identifier(patientId))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals(1, search1.getTotal());
|
||||||
|
assertEquals(patientId, search1.getEntry().get(0).getResource().getIdElement().getIdPart());
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
outcome = myClient.delete().resource(createdPatient).execute();
|
||||||
|
assertNull(outcome.getResource());
|
||||||
|
|
||||||
|
// Search
|
||||||
|
Bundle search2 = (Bundle) myClient.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.RES_ID.exactly().identifier(patientId))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertTrue(CollectionUtils.isEmpty(search2.getEntry()));
|
||||||
|
assertEquals(0, search2.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchByIdentifier() {
|
public void testSearchByIdentifier() {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,15 @@ public interface IIdHelperService {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId);
|
ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a resource type and ID, determines the internal persistent ID for a resource.
|
||||||
|
* Optionally filters out deleted resources.
|
||||||
|
*
|
||||||
|
* @throws ResourceNotFoundException If the ID can not be found
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId, boolean theExcludeDeleted);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a mapping of Id -> ResourcePersistentId.
|
* Returns a mapping of Id -> ResourcePersistentId.
|
||||||
* If any resource is not found, it will throw ResourceNotFound exception
|
* If any resource is not found, it will throw ResourceNotFound exception
|
||||||
|
@ -68,6 +77,14 @@ public interface IIdHelperService {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, List<String> theIds);
|
Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, List<String> theIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a mapping of Id -> ResourcePersistentId.
|
||||||
|
* If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned)
|
||||||
|
* Optionally filters out deleted resources.
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, List<String> theIds, boolean theExcludeDeleted);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a persistent ID, returns the associated resource ID
|
* Given a persistent ID, returns the associated resource ID
|
||||||
*/
|
*/
|
||||||
|
@ -83,6 +100,16 @@ public interface IIdHelperService {
|
||||||
@Nonnull
|
@Nonnull
|
||||||
IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException;
|
IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a forced ID, convert it to it's Long value. Since you are allowed to use string IDs for resources, we need to
|
||||||
|
* convert those to the underlying Long values that are stored, for lookup and comparison purposes.
|
||||||
|
* Optionally filters out deleted resources.
|
||||||
|
*
|
||||||
|
* @throws ResourceNotFoundException If the ID can not be found
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId, boolean theExcludeDeleted) throws ResourceNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given resource ID should be stored in a forced ID. Under default config
|
* Returns true if the given resource ID should be stored in a forced ID. Under default config
|
||||||
* (meaning client ID strategy is {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ALPHANUMERIC})
|
* (meaning client ID strategy is {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ALPHANUMERIC})
|
||||||
|
|
|
@ -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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -58,37 +58,37 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-r5</artifactId>
|
<artifactId>hapi-fhir-structures-r5</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.velocity</groupId>
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
|
|
@ -4,7 +4,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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
4
pom.xml
4
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<name>HAPI-FHIR</name>
|
<name>HAPI-FHIR</name>
|
||||||
<description>An open-source implementation of the FHIR specification in Java.</description>
|
<description>An open-source implementation of the FHIR specification in Java.</description>
|
||||||
<url>https://hapifhir.io</url>
|
<url>https://hapifhir.io</url>
|
||||||
|
@ -2011,7 +2011,7 @@
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-checkstyle</artifactId>
|
<artifactId>hapi-fhir-checkstyle</artifactId>
|
||||||
<!-- Remember to bump this when you upgrade the version -->
|
<!-- Remember to bump this when you upgrade the version -->
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -6,7 +6,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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>6.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-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.1.0-PRE8-SNAPSHOT</version>
|
<version>6.1.0-PRE9-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue