diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java
index c79ce66547a..30d9439b417 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java
+++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/RunServerCommand.java
@@ -72,8 +72,6 @@ public class RunServerCommand extends BaseCommand {
options.addOption(null, OPTION_DISABLE_REFERENTIAL_INTEGRITY, false, "If this flag is set, the server will not enforce referential integrity");
addOptionalOption(options, "u", "url", "Url", "If this option is set, specifies the JDBC URL to use for the database connection");
- addOptionalOption(options, "d", "default-size", "PageSize", "If this option is set, specifies the default page size for number of query results");
- addOptionalOption(options, "m", "max-size", "MaxSize", "If this option is set, specifies the maximum result set size for queries");
Long defaultReuseSearchResults = DaoConfig.DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
String defaultReuseSearchResultsStr = defaultReuseSearchResults == null ? "off" : String.valueOf(defaultReuseSearchResults);
@@ -112,17 +110,6 @@ public class RunServerCommand extends BaseCommand {
ContextHolder.setDatabaseUrl(theCommandLine.getOptionValue("u"));
- String defaultPageSize = theCommandLine.getOptionValue("d");
- String maxPageSize = theCommandLine.getOptionValue("m");
- if (defaultPageSize != null) {
- ContextHolder.setDefaultPageSize(Integer.valueOf(defaultPageSize));
- if (maxPageSize != null) {
- ContextHolder.setMaxPageSize(Integer.valueOf(maxPageSize));
- } else {
- ContextHolder.setMaxPageSize(Integer.valueOf(defaultPageSize));
- }
- }
-
String reuseSearchResults = theCommandLine.getOptionValue(OPTION_REUSE_SEARCH_RESULTS_MILLIS);
if (reuseSearchResults != null) {
if (reuseSearchResults.equals("off")) {
diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml
index 2509802ef16..9988c9b8aba 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml
+++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml
@@ -136,10 +136,6 @@
-
- org.postgresql
- postgresql
-
diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java
index 5968d9ef739..7e3eb9fecf1 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java
+++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextHolder.java
@@ -33,8 +33,6 @@ public class ContextHolder {
private static String ourPath;
private static Long ourReuseSearchResultsMillis;
private static String ourDatabaseUrl;
- private static Integer myDefaultPageSize = 10;
- private static Integer myMaxPageSize = 50;
static {
ourReuseSearchResultsMillis = DaoConfig.DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
@@ -102,21 +100,4 @@ public class ContextHolder {
public static void setDatabaseUrl(String theDatabaseUrl) {
ourDatabaseUrl = theDatabaseUrl;
}
-
- public static void setDefaultPageSize(Integer theDefaultPageSize) {
- myDefaultPageSize = theDefaultPageSize;
- }
-
- public static Integer getDefaultPageSize() {
- return myDefaultPageSize;
- }
-
- public static void setMaxPageSize(Integer theMaxPageSize) {
- myMaxPageSize = theMaxPageSize;
- }
-
- public static Integer getMaxPageSize() {
- return myMaxPageSize;
- }
-
}
diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java
index 40b8e8f1e57..2211b0ee469 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java
+++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java
@@ -160,7 +160,7 @@ public class JpaServerDemo extends RestfulServer {
/*
* This is a simple paging strategy that keeps the last 10 searches in memory
*/
- setPagingProvider(new FifoMemoryPagingProvider(10).setDefaultPageSize(ContextHolder.getDefaultPageSize()).setMaximumPageSize(ContextHolder.getMaxPageSize()));
+ setPagingProvider(new FifoMemoryPagingProvider(10));
// Register a CORS filter
CorsInterceptor corsInterceptor = new CorsInterceptor();
diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml
index af0cee2d749..ba1e3d61c74 100644
--- a/hapi-fhir-jpaserver-base/pom.xml
+++ b/hapi-fhir-jpaserver-base/pom.xml
@@ -640,6 +640,28 @@
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 2.22.2
+
+ true
+ 1
+ false
+ alphabetical
+
+ **/*IT.java
+
+
+
+
+
+ integration-test
+ verify
+
+
+
+
de.jpdigital
hibernate54-ddl-maven-plugin
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/dstu3/BaseDstu3Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/dstu3/BaseDstu3Config.java
index 9e0d0207beb..bd6b9dc0a84 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/dstu3/BaseDstu3Config.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/dstu3/BaseDstu3Config.java
@@ -8,9 +8,7 @@ import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
import ca.uhn.fhir.jpa.dao.dstu3.TransactionProcessorVersionAdapterDstu3;
-import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistDstu3Svc;
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
-import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorDstu3;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcDstu3;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu3;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java
index 11730fbf192..4034e720a63 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r4/BaseR4Config.java
@@ -7,8 +7,6 @@ import ca.uhn.fhir.jpa.config.BaseConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
-import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistSvc;
-import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistR4Svc;
import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4;
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java
index 88e73510b39..615272a4e9c 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/r5/BaseR5Config.java
@@ -7,10 +7,8 @@ import ca.uhn.fhir.jpa.config.BaseConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
-import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistR5Svc;
import ca.uhn.fhir.jpa.dao.r5.TransactionProcessorVersionAdapterR5;
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
-import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR5;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcR5;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR5;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
index 68add2eb3de..35d03ae2c2e 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
@@ -320,86 +320,30 @@ public class SearchBuilder implements ISearchBuilder {
}
/*
- * Fulltext search
- */
- /*
- if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT)) {
- if (myFulltextSearchSvc == null) {
- if (myParams.containsKey(Constants.PARAM_TEXT)) {
- throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
- } else if (myParams.containsKey(Constants.PARAM_CONTENT)) {
- throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
- }
- }
-
- List pids;
- if (myParams.getEverythingMode() != null) {
- pids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
- } else {
- pids = myFulltextSearchSvc.search(myResourceName, myParams);
- }
- if (pids.isEmpty()) {
- // Will never match
- pids = Collections.singletonList(new ResourcePersistentId(-1L));
- }
-
- myQueryRoot.addPredicate(myQueryRoot.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(pids)));
- } else if (myParams.isLastN()) {
- if (myIElasticsearchSvc == null) {
- if (myParams.isLastN()) {
- throw new InvalidRequestException("LastN operation is not enabled on this service, can not process this request");
- }
- }
-
- if (myParams.isLastN()) {
- Integer myMaxObservationsPerCode = null;
- String[] maxCountParams = theRequest.getParameters().get("max");
- if (maxCountParams != null && maxCountParams.length > 0) {
- myMaxObservationsPerCode = Integer.valueOf(maxCountParams[0]);
- } else {
- throw new InvalidRequestException("Max parameter is required for $lastn operation");
- }
- List lastnResourceIds = myIElasticsearchSvc.executeLastN(myParams, myMaxObservationsPerCode);
- for (String lastnResourceId : lastnResourceIds) {
- lastnPids.add(myIdHelperService.resolveResourcePersistentIds(myResourceName, lastnResourceId));
- }
- if (lastnPids.isEmpty()) {
- // Will never match
- pids = Collections.singletonList(new ResourcePersistentId(-1L));
- }
- myQueryRoot.addPredicate(myQueryRoot.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(pids)));
- }
- }
- */
- /*
- * lastn search
+ * Fulltext or lastn search
*/
if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT) || myParams.isLastN()) {
- List lastnPids = new ArrayList<>();
- List fullTextSearchPids = new ArrayList<>();
-
- if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT)) {
- if (myFulltextSearchSvc == null) {
- if (myParams.containsKey(Constants.PARAM_TEXT)) {
- throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
- } else if (myParams.containsKey(Constants.PARAM_CONTENT)) {
- throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
+ List pids = new ArrayList<>();
+ if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT)) {
+ if (myFulltextSearchSvc == null) {
+ if (myParams.containsKey(Constants.PARAM_TEXT)) {
+ throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
+ } else if (myParams.containsKey(Constants.PARAM_CONTENT)) {
+ throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
+ }
}
- }
- if (myParams.getEverythingMode() != null) {
- fullTextSearchPids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
- } else {
- fullTextSearchPids = myFulltextSearchSvc.search(myResourceName, myParams);
- }
- } else {
- if (myIElasticsearchSvc == null) {
- if (myParams.isLastN()) {
- throw new InvalidRequestException("LastN operation is not enabled on this service, can not process this request");
+ if (myParams.getEverythingMode() != null) {
+ pids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
+ } else {
+ pids = myFulltextSearchSvc.search(myResourceName, myParams);
+ }
+ } else if (myParams.isLastN()) {
+ if (myIElasticsearchSvc == null) {
+ if (myParams.isLastN()) {
+ throw new InvalidRequestException("LastN operation is not enabled on this service, can not process this request");
+ }
}
- }
-
- if (myParams.isLastN()) {
Integer myMaxObservationsPerCode = null;
String[] maxCountParams = theRequest.getParameters().get("max");
if (maxCountParams != null && maxCountParams.length > 0) {
@@ -409,31 +353,16 @@ public class SearchBuilder implements ISearchBuilder {
}
List lastnResourceIds = myIElasticsearchSvc.executeLastN(myParams, myMaxObservationsPerCode);
for (String lastnResourceId : lastnResourceIds) {
- lastnPids.add(myIdHelperService.resolveResourcePersistentIds(myResourceName, lastnResourceId));
+ pids.add(myIdHelperService.resolveResourcePersistentIds(myResourceName, lastnResourceId));
}
}
- }
-
- //
- List pids;
- if (fullTextSearchPids.isEmpty()) {
- pids = lastnPids;
- } else if (lastnPids.isEmpty()) {
- pids = fullTextSearchPids;
- } else {
- // Intersection of the fullTextSearchPids and lastnPids
- Set pidIntersection = fullTextSearchPids.stream()
- .distinct()
- .filter(lastnPids::contains)
- .collect(Collectors.toSet());
- pids = new ArrayList<>(pidIntersection);
- }
if (pids.isEmpty()) {
// Will never match
pids = Collections.singletonList(new ResourcePersistentId(-1L));
}
myQueryRoot.addPredicate(myQueryRoot.get("myId").as(Long.class).in(ResourcePersistentId.toLongList(pids)));
+
}
/*
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistDstu3Svc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistDstu3Svc.java
deleted file mode 100644
index 5834d1bb5d7..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistDstu3Svc.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package ca.uhn.fhir.jpa.dao.lastn;
-
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
-import ca.uhn.fhir.jpa.dao.lastn.entity.*;
-import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
-import org.hl7.fhir.dstu3.model.CodeableConcept;
-import org.hl7.fhir.dstu3.model.Coding;
-import org.hl7.fhir.dstu3.model.Observation;
-import org.hl7.fhir.dstu3.model.Reference;
-import org.hl7.fhir.r4.model.DateTimeType;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceContextType;
-import java.util.*;
-
-@Transactional(propagation = Propagation.REQUIRED)
-public class ObservationLastNIndexPersistDstu3Svc {
-
- @PersistenceContext(type = PersistenceContextType.TRANSACTION)
- protected EntityManager myEntityManager;
-
- @Autowired
- IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
-
- @Autowired
- IObservationIndexedCodeCodingSearchParamDao myObservationIndexedCodeCodingSearchParamDao;
-
- public void indexObservation(Observation theObservation) {
- // Only index for lastn if Observation has a subject and effective date/time
- if(theObservation.getSubject() == null || !theObservation.hasEffective()) {
- return;
- }
-
- // Determine most recent effective date/time
- Date effectiveDtm = null;
- if (theObservation.hasEffectiveDateTimeType()) {
- effectiveDtm = theObservation.getEffectiveDateTimeType().getValue();
- } else if (theObservation.hasEffectivePeriod()) {
- effectiveDtm = theObservation.getEffectivePeriod().getEnd();
- }
- if (effectiveDtm == null) {
- return;
- }
-
- // Determine if an index already exists for Observation:
- boolean observationIndexUpdate = false;
- ObservationIndexedSearchParamLastNEntity indexedObservation = null;
- if (theObservation.hasId()) {
- indexedObservation = myResourceIndexedObservationLastNDao.findForIdentifier(theObservation.getIdElement().getIdPart());
- }
- if (indexedObservation == null) {
- indexedObservation = new ObservationIndexedSearchParamLastNEntity();
- } else {
- observationIndexUpdate = true;
- }
- indexedObservation.setEffectiveDtm(effectiveDtm);
- Reference subjectReference = theObservation.getSubject();
- String subjectId = subjectReference.getReference();
- String resourcePID = theObservation.getIdElement().getIdPart();
- indexedObservation.setIdentifier(resourcePID);
- indexedObservation.setSubject(subjectId);
-
- // Build CodeableConcept entities for Observation.Category
- Set categoryConcepts = new HashSet<>();
- for(CodeableConcept categoryCodeableConcept : theObservation.getCategory()) {
- // Build Coding entities for each category CodeableConcept
- Set categoryCodingEntities = new HashSet<>();
- ObservationIndexedCategoryCodeableConceptEntity categoryCodeableConceptEntity = new ObservationIndexedCategoryCodeableConceptEntity(categoryCodeableConcept.getText());
- for(Coding categoryCoding : categoryCodeableConcept.getCoding()){
- categoryCodingEntities.add(new ObservationIndexedCategoryCodingEntity(categoryCoding.getSystem(), categoryCoding.getCode(), categoryCoding.getDisplay()));
- }
- categoryCodeableConceptEntity.setObservationIndexedCategoryCodingEntitySet(categoryCodingEntities);
- categoryConcepts.add(categoryCodeableConceptEntity);
- }
- indexedObservation.setCategoryCodeableConcepts(categoryConcepts);
-
- // Build CodeableConcept entity for Observation.Code.
- CodeableConcept codeCodeableConcept = theObservation.getCode();
- String observationCodeNormalizedId = null;
-
- // Determine if a Normalized ID was created previously for Observation Code
- boolean observationCodeUpdate = false;
- for (Coding codeCoding : codeCodeableConcept.getCoding()) {
- if (codeCoding.hasCode() && codeCoding.hasSystem()) {
- observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(codeCoding.getCode(), codeCoding.getSystem());
- } else {
- observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(codeCoding.getDisplay());
- }
- if(observationCodeNormalizedId != null) {
- observationCodeUpdate = true;
- break;
- }
- }
- // Generate a new a normalized ID if necessary
- if (observationCodeNormalizedId == null) {
- observationCodeNormalizedId = UUID.randomUUID().toString();
- }
-
- // Create/update normalized Observation Code index record
- ObservationIndexedCodeCodeableConceptEntity codeableConceptField = new ObservationIndexedCodeCodeableConceptEntity(codeCodeableConcept.getText(), observationCodeNormalizedId);
- for (Coding codeCoding : codeCodeableConcept.getCoding()) {
- codeableConceptField.addCoding(new ObservationIndexedCodeCodingEntity(codeCoding.getSystem(), codeCoding.getCode(), codeCoding.getDisplay(), observationCodeNormalizedId));
- }
- if (observationCodeUpdate) {
- myEntityManager.merge(codeableConceptField);
- } else {
- myEntityManager.persist(codeableConceptField);
- }
-
- indexedObservation.setObservationCode(codeableConceptField);
- indexedObservation.setCodeNormalizedId(observationCodeNormalizedId);
- if (observationIndexUpdate) {
- myEntityManager.merge(indexedObservation);
- } else {
- myEntityManager.persist(indexedObservation);
- }
-
- }
-
- public void deleteObservationIndex(IBasePersistedResource theEntity) {
- ObservationIndexedSearchParamLastNEntity deletedObservationLastNEntity = myResourceIndexedObservationLastNDao.findForIdentifier(theEntity.getIdDt().getIdPart());
- if (deletedObservationLastNEntity != null) {
- myEntityManager.remove(deletedObservationLastNEntity);
- }
- }
-
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR4Svc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR4Svc.java
deleted file mode 100644
index d1d1f45e439..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR4Svc.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package ca.uhn.fhir.jpa.dao.lastn;
-
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodeableConceptSearchParamDao;
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
-import ca.uhn.fhir.jpa.dao.lastn.entity.*;
-import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
-import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
-import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef;
-import org.hl7.fhir.r4.model.*;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceContextType;
-import java.util.*;
-
-@Transactional(propagation = Propagation.REQUIRED)
-public class ObservationLastNIndexPersistR4Svc {
-
- @PersistenceContext(type = PersistenceContextType.TRANSACTION)
- protected EntityManager myEntityManager;
-
- @Autowired
- IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
-
- @Autowired
- IObservationIndexedCodeCodingSearchParamDao myObservationIndexedCodeCodingSearchParamDao;
-
- public void indexObservation(Observation theObservation) {
- // Only index for lastn if Observation has a subject and effective date/time
- if(theObservation.getSubject() == null || !theObservation.hasEffective()) {
- return;
- }
-
- // Determine most recent effective date/time
- Date effectiveDtm = null;
- if (theObservation.hasEffectiveDateTimeType()) {
- effectiveDtm = theObservation.getEffectiveDateTimeType().getValue();
- } else if (theObservation.hasEffectiveInstantType()) {
- effectiveDtm = theObservation.getEffectiveInstantType().getValue();
- } else if (theObservation.hasEffectivePeriod()) {
- effectiveDtm = theObservation.getEffectivePeriod().getEnd();
- } else if (theObservation.hasEffectiveTiming()) {
- List events = theObservation.getEffectiveTiming().getEvent();
- for (DateTimeType event : events) {
- Date eventDtm = event.getValue();
- if (effectiveDtm == null || eventDtm.after(effectiveDtm)) {
- effectiveDtm = eventDtm;
- }
- }
- }
- if (effectiveDtm == null) {
- return;
- }
-
- // Determine if an index already exists for Observation:
- boolean observationIndexUpdate = false;
- ObservationIndexedSearchParamLastNEntity indexedObservation = null;
- if (theObservation.hasId()) {
- indexedObservation = myResourceIndexedObservationLastNDao.findForIdentifier(theObservation.getIdElement().getIdPart());
- }
- if (indexedObservation == null) {
- indexedObservation = new ObservationIndexedSearchParamLastNEntity();
- } else {
- observationIndexUpdate = true;
- }
-
- indexedObservation.setEffectiveDtm(effectiveDtm);
- Reference subjectReference = theObservation.getSubject();
- String subjectId = subjectReference.getReference();
- String resourcePID = theObservation.getIdElement().getIdPart();
- indexedObservation.setIdentifier(resourcePID);
- indexedObservation.setSubject(subjectId);
-
- // Build CodeableConcept entities for Observation.Category
- Set categoryConcepts = new HashSet<>();
- for(CodeableConcept categoryCodeableConcept : theObservation.getCategory()) {
- // Build Coding entities for each category CodeableConcept
- Set categoryCodingEntities = new HashSet<>();
- ObservationIndexedCategoryCodeableConceptEntity categoryCodeableConceptEntity = new ObservationIndexedCategoryCodeableConceptEntity(categoryCodeableConcept.getText());
- for(Coding categoryCoding : categoryCodeableConcept.getCoding()){
- categoryCodingEntities.add(new ObservationIndexedCategoryCodingEntity(categoryCoding.getSystem(), categoryCoding.getCode(), categoryCoding.getDisplay()));
- }
- categoryCodeableConceptEntity.setObservationIndexedCategoryCodingEntitySet(categoryCodingEntities);
- categoryConcepts.add(categoryCodeableConceptEntity);
- }
- indexedObservation.setCategoryCodeableConcepts(categoryConcepts);
-
- // Build CodeableConcept entity for Observation.Code.
- CodeableConcept codeCodeableConcept = theObservation.getCode();
- String observationCodeNormalizedId = null;
-
- // Determine if a Normalized ID was created previously for Observation Code
- boolean observationCodeUpdate = false;
- for (Coding codeCoding : codeCodeableConcept.getCoding()) {
- if (codeCoding.hasCode() && codeCoding.hasSystem()) {
- observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(codeCoding.getCode(), codeCoding.getSystem());
- } else {
- observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(codeCoding.getDisplay());
- }
- if(observationCodeNormalizedId != null) {
- observationCodeUpdate = true;
- break;
- }
- }
- // Generate a new a normalized ID if necessary
- if (observationCodeNormalizedId == null) {
- observationCodeNormalizedId = UUID.randomUUID().toString();
- }
-
- // Create/update normalized Observation Code index record
- ObservationIndexedCodeCodeableConceptEntity codeableConceptField = new ObservationIndexedCodeCodeableConceptEntity(codeCodeableConcept.getText(), observationCodeNormalizedId);
- for (Coding codeCoding : codeCodeableConcept.getCoding()) {
- codeableConceptField.addCoding(new ObservationIndexedCodeCodingEntity(codeCoding.getSystem(), codeCoding.getCode(), codeCoding.getDisplay(), observationCodeNormalizedId));
- }
- if (observationCodeUpdate) {
- myEntityManager.merge(codeableConceptField);
- } else {
- myEntityManager.persist(codeableConceptField);
- }
-
- indexedObservation.setObservationCode(codeableConceptField);
- indexedObservation.setCodeNormalizedId(observationCodeNormalizedId);
- if (observationIndexUpdate) {
- myEntityManager.merge(indexedObservation);
- } else {
- myEntityManager.persist(indexedObservation);
- }
-
- }
-
- public void deleteObservationIndex(IBasePersistedResource theEntity) {
- ObservationIndexedSearchParamLastNEntity deletedObservationLastNEntity = myResourceIndexedObservationLastNDao.findForIdentifier(theEntity.getIdDt().getIdPart());
- if(deletedObservationLastNEntity != null) {
- myEntityManager.remove(deletedObservationLastNEntity);
- }
- }
-
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR5Svc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR5Svc.java
deleted file mode 100644
index 176d35ce7d5..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR5Svc.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package ca.uhn.fhir.jpa.dao.lastn;
-
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
-import ca.uhn.fhir.jpa.dao.lastn.entity.*;
-import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
-import org.hl7.fhir.r5.model.DateTimeType;
-import org.hl7.fhir.r5.model.CodeableConcept;
-import org.hl7.fhir.r5.model.Coding;
-import org.hl7.fhir.r5.model.Observation;
-import org.hl7.fhir.r5.model.Reference;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceContextType;
-import java.util.*;
-
-@Transactional(propagation = Propagation.REQUIRED)
-public class ObservationLastNIndexPersistR5Svc {
-
- @PersistenceContext(type = PersistenceContextType.TRANSACTION)
- protected EntityManager myEntityManager;
-
- @Autowired
- IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
-
- @Autowired
- IObservationIndexedCodeCodingSearchParamDao myObservationIndexedCodeCodingSearchParamDao;
-
- public void indexObservation(Observation theObservation) {
- // Only index for lastn if Observation has a subject and effective date/time
- if(theObservation.getSubject() == null || !theObservation.hasEffective()) {
- return;
- }
-
- // Determine most recent effective date/time
- Date effectiveDtm = null;
- if (theObservation.hasEffectiveDateTimeType()) {
- effectiveDtm = theObservation.getEffectiveDateTimeType().getValue();
- } else if (theObservation.hasEffectiveInstantType()) {
- effectiveDtm = theObservation.getEffectiveInstantType().getValue();
- } else if (theObservation.hasEffectivePeriod()) {
- effectiveDtm = theObservation.getEffectivePeriod().getEnd();
- } else if (theObservation.hasEffectiveTiming()) {
- List events = theObservation.getEffectiveTiming().getEvent();
- for (DateTimeType event : events) {
- Date eventDtm = event.getValue();
- if (effectiveDtm == null || eventDtm.after(effectiveDtm)) {
- effectiveDtm = eventDtm;
- }
- }
- }
- if (effectiveDtm == null) {
- return;
- }
-
- // Determine if an index already exists for Observation:
- boolean observationIndexUpdate = false;
- ObservationIndexedSearchParamLastNEntity indexedObservation = null;
- if (theObservation.hasId()) {
- indexedObservation = myResourceIndexedObservationLastNDao.findForIdentifier(theObservation.getIdElement().getIdPart());
- }
- if (indexedObservation == null) {
- indexedObservation = new ObservationIndexedSearchParamLastNEntity();
- } else {
- observationIndexUpdate = true;
- }
- indexedObservation.setEffectiveDtm(effectiveDtm);
- Reference subjectReference = theObservation.getSubject();
- String subjectId = subjectReference.getReference();
- String resourcePID = theObservation.getIdElement().getIdPart();
- indexedObservation.setIdentifier(resourcePID);
- indexedObservation.setSubject(subjectId);
-
- // Build CodeableConcept entities for Observation.Category
- Set categoryConcepts = new HashSet<>();
- for(CodeableConcept categoryCodeableConcept : theObservation.getCategory()) {
- // Build Coding entities for each category CodeableConcept
- Set categoryCodingEntities = new HashSet<>();
- ObservationIndexedCategoryCodeableConceptEntity categoryCodeableConceptEntity = new ObservationIndexedCategoryCodeableConceptEntity(categoryCodeableConcept.getText());
- for(Coding categoryCoding : categoryCodeableConcept.getCoding()){
- categoryCodingEntities.add(new ObservationIndexedCategoryCodingEntity(categoryCoding.getSystem(), categoryCoding.getCode(), categoryCoding.getDisplay()));
- }
- categoryCodeableConceptEntity.setObservationIndexedCategoryCodingEntitySet(categoryCodingEntities);
- categoryConcepts.add(categoryCodeableConceptEntity);
- }
- indexedObservation.setCategoryCodeableConcepts(categoryConcepts);
-
- // Build CodeableConcept entity for Observation.Code.
- CodeableConcept codeCodeableConcept = theObservation.getCode();
- String observationCodeNormalizedId = null;
-
- // Determine if a Normalized ID was created previously for Observation Code
- boolean observationCodeUpdate = false;
- for (Coding codeCoding : codeCodeableConcept.getCoding()) {
- if (codeCoding.hasCode() && codeCoding.hasSystem()) {
- observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(codeCoding.getCode(), codeCoding.getSystem());
- } else {
- observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(codeCoding.getDisplay());
- }
- if(observationCodeNormalizedId != null) {
- observationCodeUpdate = true;
- break;
- }
- }
- // Generate a new a normalized ID if necessary
- if (observationCodeNormalizedId == null) {
- observationCodeNormalizedId = UUID.randomUUID().toString();
- }
-
- // Create/update normalized Observation Code index record
- ObservationIndexedCodeCodeableConceptEntity codeableConceptField = new ObservationIndexedCodeCodeableConceptEntity(codeCodeableConcept.getText(), observationCodeNormalizedId);
- for (Coding codeCoding : codeCodeableConcept.getCoding()) {
- codeableConceptField.addCoding(new ObservationIndexedCodeCodingEntity(codeCoding.getSystem(), codeCoding.getCode(), codeCoding.getDisplay(), observationCodeNormalizedId));
- }
- if (observationCodeUpdate) {
- myEntityManager.merge(codeableConceptField);
- } else {
- myEntityManager.persist(codeableConceptField);
- }
-
- indexedObservation.setObservationCode(codeableConceptField);
- indexedObservation.setCodeNormalizedId(observationCodeNormalizedId);
- if (observationIndexUpdate) {
- myEntityManager.merge(indexedObservation);
- } else {
- myEntityManager.persist(indexedObservation);
- }
-
- }
-
- public void deleteObservationIndex(IBasePersistedResource theEntity) {
- ObservationIndexedSearchParamLastNEntity deletedObservationLastNEntity = myResourceIndexedObservationLastNDao.findForIdentifier(theEntity.getIdDt().getIdPart());
- if(deletedObservationLastNEntity != null) {
- myEntityManager.remove(deletedObservationLastNEntity);
- }
- }
-
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistSvc.java
index a906f852002..105fc81efda 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistSvc.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistSvc.java
@@ -53,8 +53,12 @@ public class ObservationLastNIndexPersistSvc {
effectiveDtm = mySearchParameterExtractor.extractDateFromResource(effectiveDateElement.get(0), "Observation.effective");
}
- // Only index for lastn if Observation has a subject and effective date/time
- if (subjectId == null || effectiveDtm == null) {
+ // Build CodeableConcept entity for Observation.Code.
+ List observationCodeCodeableConcepts = mySearchParameterExtractor.extractValues("Observation.code", theResource);
+
+
+ // Only index for lastn if Observation has a subject, effective date/time and code
+ if (subjectId == null || effectiveDtm == null || observationCodeCodeableConcepts.size() == 0) {
return;
}
@@ -76,17 +80,6 @@ public class ObservationLastNIndexPersistSvc {
indexedObservation.setIdentifier(resourcePID);
indexedObservation.setSubject(subjectId);
- // Build CodeableConcept entities for Observation.Category
- List observationCategoryCodeableConcepts = mySearchParameterExtractor.extractValues("Observation.category", theResource);
- Set categoryCodeableConceptEntities = new HashSet<>();
- for (IBase categoryCodeableConcept : observationCategoryCodeableConcepts) {
- // Build CodeableConcept entities for each category CodeableConcept
- categoryCodeableConceptEntities.add(getCategoryCodeableConceptEntities(categoryCodeableConcept));
- }
- indexedObservation.setCategoryCodeableConcepts(categoryCodeableConceptEntities);
-
- // Build CodeableConcept entity for Observation.Code.
- List observationCodeCodeableConcepts = mySearchParameterExtractor.extractValues("Observation.code", theResource);
// Determine if a Normalized ID was created previously for Observation Code
boolean observationCodeUpdate = false;
@@ -102,6 +95,15 @@ public class ObservationLastNIndexPersistSvc {
// Create/update normalized Observation Code index record
ObservationIndexedCodeCodeableConceptEntity codeableConceptField = getCodeCodeableConcept(observationCodeCodeableConcepts.get(0), observationCodeNormalizedId);
+ // Build CodeableConcept entities for Observation.Category
+ List observationCategoryCodeableConcepts = mySearchParameterExtractor.extractValues("Observation.category", theResource);
+ Set categoryCodeableConceptEntities = new HashSet<>();
+ for (IBase categoryCodeableConcept : observationCategoryCodeableConcepts) {
+ // Build CodeableConcept entities for each category CodeableConcept
+ categoryCodeableConceptEntities.add(getCategoryCodeableConceptEntities(categoryCodeableConcept));
+ }
+ indexedObservation.setCategoryCodeableConcepts(categoryCodeableConceptEntities);
+
if (observationCodeUpdate) {
myEntityManager.merge(codeableConceptField);
} else {
@@ -152,16 +154,18 @@ public class ObservationLastNIndexPersistSvc {
ResourceIndexedSearchParamToken param = mySearchParameterExtractor.createSearchParamForCoding("Observation",
new RuntimeSearchParam(null, null, "code", null, null, null, null, null, null, null),
nextCoding);
- String system = param.getSystem();
- String code = param.getValue();
- String text = mySearchParameterExtractor.getDisplayTextForCoding(nextCoding);
- if (code != null && system != null) {
- codeCodeableConceptId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(code, system);
- } else {
- codeCodeableConceptId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(text);
- }
- if (codeCodeableConceptId != null) {
- break;
+ if (param != null) {
+ String system = param.getSystem();
+ String code = param.getValue();
+ String text = mySearchParameterExtractor.getDisplayTextForCoding(nextCoding);
+ if (code != null && system != null) {
+ codeCodeableConceptId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(code, system);
+ } else {
+ codeCodeableConceptId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(text);
+ }
+ if (codeCodeableConceptId != null) {
+ break;
+ }
}
}
@@ -172,20 +176,28 @@ public class ObservationLastNIndexPersistSvc {
ResourceIndexedSearchParamToken param = mySearchParameterExtractor.createSearchParamForCoding("Observation",
new RuntimeSearchParam(null, null, "category", null, null, null, null, null, null, null),
theValue);
- String system = param.getSystem();
- String code = param.getValue();
- String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
- return new ObservationIndexedCategoryCodingEntity(system, code, text);
+ ObservationIndexedCategoryCodingEntity observationIndexedCategoryCodingEntity = null;
+ if (param != null) {
+ String system = param.getSystem();
+ String code = param.getValue();
+ String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
+ observationIndexedCategoryCodingEntity = new ObservationIndexedCategoryCodingEntity(system, code, text);
+ }
+ return observationIndexedCategoryCodingEntity;
}
private ObservationIndexedCodeCodingEntity getCodeCoding(IBase theValue, String observationCodeNormalizedId) {
ResourceIndexedSearchParamToken param = mySearchParameterExtractor.createSearchParamForCoding("Observation",
new RuntimeSearchParam(null, null, "code", null, null, null, null, null, null, null),
theValue);
- String system = param.getSystem();
- String code = param.getValue();
- String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
- return new ObservationIndexedCodeCodingEntity(system, code, text, observationCodeNormalizedId);
+ ObservationIndexedCodeCodingEntity observationIndexedCodeCodingEntity = null;
+ if (param != null) {
+ String system = param.getSystem();
+ String code = param.getValue();
+ String text = mySearchParameterExtractor.getDisplayTextForCoding(theValue);
+ observationIndexedCodeCodingEntity = new ObservationIndexedCodeCodingEntity(system, code, text, observationCodeNormalizedId);
+ }
+ return observationIndexedCodeCodingEntity;
}
public void deleteObservationIndex(IBasePersistedResource theEntity) {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/entity/ObservationIndexedCodeCodeableConceptEntity.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/entity/ObservationIndexedCodeCodeableConceptEntity.java
index bf1d994d31d..2757173505d 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/entity/ObservationIndexedCodeCodeableConceptEntity.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/entity/ObservationIndexedCodeCodeableConceptEntity.java
@@ -22,6 +22,7 @@ public class ObservationIndexedCodeCodeableConceptEntity {
@Column(name = "CODEABLE_CONCEPT_TEXT", nullable = true)
private String myCodeableConceptText;
+ // TODO: Make coding a Collection. Need to first figure out how to maintain this over time.
@IndexedEmbedded(depth=2, prefix = "coding")
// @OneToMany(mappedBy = "myCodeableConceptId", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@JoinColumn(name = "CODEABLE_CONCEPT_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_CONCEPT_CODE"))
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoObservationR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoObservationR4.java
index 14828dd2727..55f47758b3f 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoObservationR4.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoObservationR4.java
@@ -21,14 +21,10 @@ package ca.uhn.fhir.jpa.dao.r4;
*/
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDaoObservation;
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
-import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistSvc;
-import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistR4Svc;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
-import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProviderObservationDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProviderObservationDstu2.java
deleted file mode 100644
index 9a61f635368..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProviderObservationDstu2.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package ca.uhn.fhir.jpa.provider;
-
-import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
-import ca.uhn.fhir.jpa.model.util.JpaConstants;
-import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
-import ca.uhn.fhir.model.api.Include;
-import ca.uhn.fhir.model.api.annotation.Description;
-import ca.uhn.fhir.model.dstu2.resource.Observation;
-import ca.uhn.fhir.model.valueset.BundleTypeEnum;
-import ca.uhn.fhir.rest.annotation.*;
-import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
-import ca.uhn.fhir.rest.api.SortOrderEnum;
-import ca.uhn.fhir.rest.api.SortSpec;
-import ca.uhn.fhir.rest.api.SummaryEnum;
-import ca.uhn.fhir.rest.api.server.IBundleProvider;
-import ca.uhn.fhir.rest.param.*;
-
-import java.util.Set;
-
-/*
- * #%L
- * HAPI FHIR JPA Server
- * %%
- * Copyright (C) 2014 - 2020 University Health Network
- * %%
- * 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 class BaseJpaResourceProviderObservationDstu2 extends JpaResourceProviderDstu2 {
-
- /**
- * Observation/$lastn
- */
- @Operation(name = JpaConstants.OPERATION_LASTN, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
- public IBundleProvider observationLastN(
-
- javax.servlet.http.HttpServletRequest theServletRequest,
- javax.servlet.http.HttpServletResponse theServletResponse,
-
- ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
-
- @Description(shortDefinition="Search the contents of the resource's data using a filter")
- @OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_FILTER)
- StringAndListParam theFtFilter,
-
- @Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
- @OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT)
- StringAndListParam theFtContent,
-
- @Description(shortDefinition="Search the contents of the resource's narrative using a fulltext search")
- @OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_TEXT)
- StringAndListParam theFtText,
-
- @Description(shortDefinition="The classification of the type of observation")
- @OperationParam(name="category")
- TokenAndListParam theCategory,
-
- @Description(shortDefinition="The code of the observation type")
- @OperationParam(name="code")
- TokenAndListParam theCode,
-
- @Description(shortDefinition="Obtained date/time. If the obtained element is a period, a date that falls in the period")
- @OperationParam(name="date")
- DateRangeParam theDate,
-
- @Description(shortDefinition="The subject that the observation is about (if patient)")
- @OperationParam(name="patient")
- ReferenceAndListParam thePatient,
-
- @Description(shortDefinition="The subject that the observation is about")
- @OperationParam(name="subject" )
- ReferenceAndListParam theSubject,
-
- @IncludeParam(reverse=true)
- Set theRevIncludes,
- @Description(shortDefinition="Only return resources which were last updated as specified by the given range")
- @OperationParam(name="_lastUpdated")
- DateRangeParam theLastUpdated,
-
- @IncludeParam(allow= {
- "Observation:based-on",
- "Observation:derived-from",
- "Observation:device",
- "Observation:encounter",
- "Observation:focus",
- "Observation:has-member",
- "Observation:part-of",
- "Observation:patient",
- "Observation:performer",
- "Observation:specimen",
- "Observation:subject",
- "*"
- })
- Set theIncludes,
-
- @Sort
- SortSpec theSort,
-
- @ca.uhn.fhir.rest.annotation.Count
- Integer theCount,
-
- SummaryEnum theSummaryMode,
-
- SearchTotalModeEnum theSearchTotalMode
-
- ) {
- startRequest(theServletRequest);
- try {
- SearchParameterMap paramMap = new SearchParameterMap();
- paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_FILTER, theFtFilter);
- paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT, theFtContent);
- paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_TEXT, theFtText);
- paramMap.add("category", theCategory);
- paramMap.add("code", theCode);
- paramMap.add("date", theDate);
- paramMap.add("patient", thePatient);
- paramMap.add("subject", theSubject);
- paramMap.setRevIncludes(theRevIncludes);
- paramMap.setLastUpdated(theLastUpdated);
- paramMap.setIncludes(theIncludes);
- paramMap.setLastN(true);
- if (theSort == null) {
- SortSpec effectiveDtm = new SortSpec("date").setOrder(SortOrderEnum.DESC);
- SortSpec observationCode = new SortSpec("code").setOrder(SortOrderEnum.ASC).setChain(effectiveDtm);
- if (thePatient != null && theSubject == null) {
- theSort = new SortSpec("patient").setChain(observationCode);
- } else {
- theSort = new SortSpec("subject").setChain(observationCode);
- }
- }
- paramMap.setSort(theSort);
- paramMap.setCount(theCount);
- paramMap.setSummaryMode(theSummaryMode);
- paramMap.setSearchTotalMode(theSearchTotalMode);
-
- return ((IFhirResourceDaoObservation) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
- } finally {
- endRequest(theServletRequest);
- }
- }
-
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/json/IdJson.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/json/IdJson.java
deleted file mode 100644
index 1df4410f054..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/json/IdJson.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package ca.uhn.fhir.jpa.search.lastn.json;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
-public class IdJson {
-
- @JsonProperty(value = "_id", required = true)
- private String myId;
-
- public IdJson(String theId) {
- myId = theId;
- }
-
- public String getId() { return myId; }
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/json/IndexJson.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/json/IndexJson.java
deleted file mode 100644
index dc1880124b4..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/json/IndexJson.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package ca.uhn.fhir.jpa.search.lastn.json;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
-public class IndexJson {
-
- @JsonProperty(value = "index", required = true)
- private IdJson myIndex;
-
- public IndexJson(IdJson theIndex) {
- myIndex = theIndex;
- }
-
- public IdJson getId() { return myIndex; }
-
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/util/SimpleStopWatch.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/util/SimpleStopWatch.java
deleted file mode 100644
index 20381a5e2fe..00000000000
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/util/SimpleStopWatch.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package ca.uhn.fhir.jpa.search.lastn.util;
-
-public class SimpleStopWatch {
- private long myStarted = System.currentTimeMillis();
-
- public SimpleStopWatch() {
-
- }
-
- public long getElapsedTime() {
- return System.currentTimeMillis() - myStarted;
- }
-
- public void restart() {
- myStarted = System.currentTimeMillis();
- }
-
-}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNIT.java
similarity index 99%
rename from hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNTest.java
rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNIT.java
index c63a1a8932e..58f16a68383 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchLastNIT.java
@@ -28,7 +28,7 @@ import static org.mockito.Mockito.when;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestR4ConfigWithElasticsearchClient.class })
-public class FhirResourceDaoR4SearchLastNTest extends BaseJpaTest {
+public class FhirResourceDaoR4SearchLastNIT extends BaseJpaTest {
@Autowired
@Qualifier("myPatientDaoR4")
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java
similarity index 98%
rename from hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchTest.java
rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java
index 7c6bcca1295..85e53af4ad6 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java
@@ -60,10 +60,10 @@ import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4ConfigWithElasticSearch.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-public class FhirResourceDaoR4SearchWithElasticSearchTest extends BaseJpaTest {
+public class FhirResourceDaoR4SearchWithElasticSearchIT extends BaseJpaTest {
public static final String URL_MY_CODE_SYSTEM = "http://example.com/my_code_system";
public static final String URL_MY_VALUE_SET = "http://example.com/my_value_set";
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4SearchWithElasticSearchTest.class);
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4SearchWithElasticSearchIT.class);
@Autowired
protected DaoConfig myDaoConfig;
@Autowired
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4IT.java
similarity index 98%
rename from hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4Test.java
rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4IT.java
index 79f08459135..9a552c09a0d 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PersistObservationIndexedSearchParamLastNR4IT.java
@@ -40,7 +40,7 @@ import static org.junit.Assert.assertTrue;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4ConfigWithElasticsearchClient.class})
-public class PersistObservationIndexedSearchParamLastNR4Test {
+public class PersistObservationIndexedSearchParamLastNR4IT {
@Autowired
IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
@@ -48,9 +48,6 @@ public class PersistObservationIndexedSearchParamLastNR4Test {
@Autowired
IObservationIndexedCodeCodeableConceptSearchParamDao myCodeableConceptIndexedSearchParamNormalizedDao;
-// @Autowired
-// ObservationLastNIndexPersistR4Svc myObservationLastNIndexPersistR4Svc;
-
@Autowired
private ElasticsearchSvcImpl elasticsearchSvc;
@@ -68,9 +65,6 @@ public class PersistObservationIndexedSearchParamLastNR4Test {
myResourceIndexedObservationLastNDao.deleteAll();
myCodeableConceptIndexedSearchParamNormalizedDao.deleteAll();
-// testObservationPersist = new BaseObservationLastNIndexPersistSvc(myEntityManager, myResourceIndexedObservationLastNDao,
-// myObservationIndexedCodeCodingSearchParamDao, mySearchParamExtractor, myContext);
-
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcMultipleObservationsTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcMultipleObservationsIT.java
similarity index 99%
rename from hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcMultipleObservationsTest.java
rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcMultipleObservationsIT.java
index 2f495cdea88..7eb78281ec3 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcMultipleObservationsTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcMultipleObservationsIT.java
@@ -26,7 +26,7 @@ import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestElasticsearchConfig.class})
-public class LastNElasticsearchSvcMultipleObservationsTest {
+public class LastNElasticsearchSvcMultipleObservationsIT {
@Autowired
private ElasticsearchSvcImpl elasticsearchSvc;
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcSingleObservationTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcSingleObservationIT.java
similarity index 99%
rename from hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcSingleObservationTest.java
rename to hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcSingleObservationIT.java
index e2dc8f23bb8..b78e14821b3 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcSingleObservationTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/LastNElasticsearchSvcSingleObservationIT.java
@@ -27,7 +27,7 @@ import static org.junit.Assert.assertTrue;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestElasticsearchConfig.class})
-public class LastNElasticsearchSvcSingleObservationTest {
+public class LastNElasticsearchSvcSingleObservationIT {
@Autowired
ElasticsearchSvcImpl elasticsearchSvc;
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java
index 8a73cdf1349..78d54ead1eb 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java
@@ -636,7 +636,10 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
private void addToken_Coding(String theResourceType, Set theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
- theParams.add(createSearchParamForCoding(theResourceType, theSearchParam, theValue));
+ ResourceIndexedSearchParamToken resourceIndexedSearchParamToken = createSearchParamForCoding(theResourceType, theSearchParam, theValue);
+ if (resourceIndexedSearchParamToken != null) {
+ theParams.add(resourceIndexedSearchParamToken);
+ }
String text = getDisplayTextForCoding(theValue);
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, text);
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/src/main/java/ca/uhn/fhir/spring/boot/autoconfigure/FhirAutoConfiguration.java b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/src/main/java/ca/uhn/fhir/spring/boot/autoconfigure/FhirAutoConfiguration.java
index c84e17cad24..91566fc9527 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/src/main/java/ca/uhn/fhir/spring/boot/autoconfigure/FhirAutoConfiguration.java
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/src/main/java/ca/uhn/fhir/spring/boot/autoconfigure/FhirAutoConfiguration.java
@@ -164,7 +164,7 @@ public class FhirAutoConfiguration {
private ScheduledExecutorService myScheduledExecutorService;
@Configuration
- @EntityScan(basePackages = {"ca.uhn.fhir.jpa.entity", "ca.uhn.fhir.jpa.model.entity"})
+ @EntityScan(basePackages = {"ca.uhn.fhir.jpa.entity", "ca.uhn.fhir.jpa.model.entity", "ca.uhn.fhir.jpa.dao.lastn.entity"})
@Import({
SubscriptionChannelConfig.class,
SubscriptionProcessorConfig.class,
diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
index 665f598fd98..737dfb1fb04 100644
--- a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
+++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
@@ -24,7 +24,7 @@ import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
public class ${className}ResourceProvider extends
## We have specialized base classes for RPs that handle certain resource types. These
## RPs implement type specific operations
-#if ( $version != 'dstu' && (${className} == 'Encounter' || ${className} == 'Patient' || ${className} == 'ValueSet' || ${className} == 'QuestionnaireAnswers' || ${className} == 'CodeSystem' || ($version != 'dstu2' && ${className} == 'ConceptMap') || ${className} == 'MessageHeader' || ${className} == 'Composition' || ${className} == 'StructureDefinition' || ${className} == 'Observation' ))
+#if ( $version != 'dstu' && (${className} == 'Encounter' || ${className} == 'Patient' || ${className} == 'ValueSet' || ${className} == 'QuestionnaireAnswers' || ${className} == 'CodeSystem' || ($version != 'dstu2' && ${className} == 'ConceptMap') || ${className} == 'MessageHeader' || ${className} == 'Composition' || ${className} == 'StructureDefinition' || ($version != 'dstu2' && ${className} == 'Observation') ))
BaseJpaResourceProvider${className}${versionCapitalized}
#else
JpaResourceProvider${versionCapitalized}<${className}>