implements IFhirResourceDaoConceptMap {
@Autowired
private ITermReadSvc myHapiTerminologySvc;
@@ -166,7 +171,7 @@ public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao implements IFhirResourceDaoValueSet {
private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoValueSetDstu3.class);
@@ -420,7 +423,7 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao
if (myDaoConfig.isPreExpandValueSets() && !retVal.isUnchangedInCurrentOperation()) {
if (retVal.getDeleted() == null) {
ValueSet valueSet = (ValueSet) theResource;
- myHapiTerminologySvc.storeTermValueSet(retVal, org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(valueSet));
+ myHapiTerminologySvc.storeTermValueSet(retVal, org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSet));
} else {
myHapiTerminologySvc.deleteValueSetAndChildren(retVal);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java
index 51aa90a45de..d0d904c3b3d 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/Search.java
@@ -13,7 +13,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.*;
-import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.*;
@@ -43,8 +42,8 @@ import static org.apache.commons.lang3.StringUtils.left;
@Table(name = "HFJ_SEARCH", uniqueConstraints = {
@UniqueConstraint(name = "IDX_SEARCH_UUID", columnNames = "SEARCH_UUID")
}, indexes = {
- @Index(name = "IDX_SEARCH_LASTRETURNED", columnList = "SEARCH_LAST_RETURNED"),
- @Index(name = "IDX_SEARCH_RESTYPE_HASHS", columnList = "RESOURCE_TYPE,SEARCH_QUERY_STRING_HASH,CREATED")
+ @Index(name = "IDX_SEARCH_RESTYPE_HASHS", columnList = "RESOURCE_TYPE,SEARCH_QUERY_STRING_HASH,CREATED"),
+ @Index(name = "IDX_SEARCH_CREATED", columnList = "CREATED")
})
public class Search implements ICachedSearchDetails, Serializable {
@@ -90,11 +89,6 @@ public class Search implements ICachedSearchDetails, Serializable {
private Long myResourceId;
@Column(name = "RESOURCE_TYPE", length = 200, nullable = true)
private String myResourceType;
- @NotNull
- @Temporal(TemporalType.TIMESTAMP)
- @Column(name = "SEARCH_LAST_RETURNED", nullable = false, updatable = false)
- @OptimisticLock(excluded = true)
- private Date mySearchLastReturned;
@Lob()
@Basic(fetch = FetchType.LAZY)
@Column(name = "SEARCH_QUERY_STRING", nullable = true, updatable = false, length = MAX_SEARCH_QUERY_STRING)
@@ -261,14 +255,6 @@ public class Search implements ICachedSearchDetails, Serializable {
myResourceType = theResourceType;
}
- public Date getSearchLastReturned() {
- return mySearchLastReturned;
- }
-
- public void setSearchLastReturned(Date theDate) {
- mySearchLastReturned = theDate;
- }
-
public String getSearchQueryString() {
return mySearchQueryString;
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSetConceptDesignation.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSetConceptDesignation.java
index ea6582e49cf..bca66a3792b 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSetConceptDesignation.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermValueSetConceptDesignation.java
@@ -33,9 +33,7 @@ import java.io.Serializable;
import static org.apache.commons.lang3.StringUtils.left;
import static org.apache.commons.lang3.StringUtils.length;
-@Table(name = "TRM_VALUESET_C_DESIGNATION", indexes = {
- @Index(name = "IDX_VALUESET_C_DSGNTN_VAL", columnList = "VAL")
-})
+@Table(name = "TRM_VALUESET_C_DESIGNATION")
@Entity()
public class TermValueSetConceptDesignation implements Serializable {
private static final long serialVersionUID = 1L;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/JpaPreResourceAccessDetails.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/JpaPreResourceAccessDetails.java
index 316614b34ec..77fa992ed6b 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/JpaPreResourceAccessDetails.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/JpaPreResourceAccessDetails.java
@@ -57,7 +57,6 @@ public class JpaPreResourceAccessDetails implements IPreResourceAccessDetails {
public IBaseResource getResource(int theIndex) {
if (myResources == null) {
myResources = new ArrayList<>(myResourcePids.size());
- // FIXME: JA don't call interceptors for this query
mySearchBuilderSupplier.call().loadResourcesByPid(myResourcePids, Collections.emptySet(), myResources, false, null);
}
return myResources.get(theIndex);
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/TerminologyUploaderProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/TerminologyUploaderProvider.java
index 5682960d637..90a27e56c48 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/TerminologyUploaderProvider.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/TerminologyUploaderProvider.java
@@ -39,7 +39,6 @@ import ca.uhn.fhir.util.ValidateUtil;
import com.google.common.base.Charsets;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
-import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.ICompositeType;
@@ -53,9 +52,15 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
-import static org.apache.commons.lang3.StringUtils.*;
+import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import static org.apache.commons.lang3.StringUtils.trim;
+import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
public class TerminologyUploaderProvider extends BaseJpaProvider {
@@ -226,9 +231,9 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
b.append(ConceptHandler.DISPLAY);
b.append("\n");
for (Map.Entry nextEntry : codes.entrySet()) {
- b.append(nextEntry.getKey());
+ b.append(csvEscape(nextEntry.getKey()));
b.append(",");
- b.append(defaultString(nextEntry.getValue()));
+ b.append(csvEscape(nextEntry.getValue()));
b.append("\n");
}
byte[] bytes = b.toString().getBytes(Charsets.UTF_8);
@@ -245,9 +250,9 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
b.append(HierarchyHandler.PARENT);
b.append("\n");
for (Map.Entry nextEntry : codeToParentCodes.entries()) {
- b.append(nextEntry.getKey());
+ b.append(csvEscape(nextEntry.getKey()));
b.append(",");
- b.append(defaultString(nextEntry.getValue()));
+ b.append(csvEscape(nextEntry.getValue()));
b.append("\n");
}
byte[] bytes = b.toString().getBytes(Charsets.UTF_8);
@@ -267,10 +272,10 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
CodeSystem nextCodeSystem;
switch (getContext().getVersion().getVersion()) {
case DSTU3:
- nextCodeSystem = VersionConvertor_30_40.convertCodeSystem((org.hl7.fhir.dstu3.model.CodeSystem) theCodeSystem);
+ nextCodeSystem = convertCodeSystem((org.hl7.fhir.dstu3.model.CodeSystem) theCodeSystem);
break;
case R5:
- nextCodeSystem = org.hl7.fhir.convertors.conv40_50.CodeSystem.convertCodeSystem((org.hl7.fhir.r5.model.CodeSystem) theCodeSystem);
+ nextCodeSystem = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem((org.hl7.fhir.r5.model.CodeSystem) theCodeSystem);
break;
default:
nextCodeSystem = (CodeSystem) theCodeSystem;
@@ -354,7 +359,6 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
return retVal;
}
-
private static class FileBackedFileDescriptor implements ITermLoaderSvc.FileDescriptor {
private final File myNextFile;
@@ -376,4 +380,13 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
}
}
}
+
+ private static String csvEscape(String theValue) {
+ return '"' +
+ theValue
+ .replace("\"", "\"\"")
+ .replace("\n", "\\n")
+ .replace("\r", "") +
+ '"';
+ }
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderConceptMapDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderConceptMapDstu3.java
index 7bcfee951a4..0f42082bbef 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderConceptMapDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderConceptMapDstu3.java
@@ -21,9 +21,9 @@ package ca.uhn.fhir.jpa.provider.dstu3;
*/
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
+import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.term.TranslationRequest;
import ca.uhn.fhir.jpa.term.TranslationResult;
-import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
@@ -31,11 +31,21 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
-import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.dstu3.model.BooleanType;
+import org.hl7.fhir.dstu3.model.CodeType;
+import org.hl7.fhir.dstu3.model.CodeableConcept;
+import org.hl7.fhir.dstu3.model.Coding;
+import org.hl7.fhir.dstu3.model.ConceptMap;
+import org.hl7.fhir.dstu3.model.IdType;
+import org.hl7.fhir.dstu3.model.Parameters;
+import org.hl7.fhir.dstu3.model.StringType;
+import org.hl7.fhir.dstu3.model.UriType;
import org.hl7.fhir.exceptions.FHIRException;
import javax.servlet.http.HttpServletRequest;
+import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
+
public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderDstu3 {
@Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = {
@OperationParam(name = "result", type = BooleanType.class, min = 1, max = 1),
@@ -129,7 +139,7 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
TranslationResult result = dao.translate(translationRequest, theRequestDetails);
// Convert from R4 to DSTU3
- return VersionConvertor_30_40.convertParameters(result.toParameters());
+ return convertParameters(result.toParameters());
} catch (FHIRException fe) {
throw new InternalErrorException(fe);
} finally {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaResourceProviderDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaResourceProviderDstu3.java
index e6376d2ddf1..42aec253031 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaResourceProviderDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaResourceProviderDstu3.java
@@ -21,17 +21,28 @@ package ca.uhn.fhir.jpa.provider.dstu3;
*/
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
-import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
-import ca.uhn.fhir.rest.annotation.*;
+import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
+import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
+import ca.uhn.fhir.rest.annotation.Create;
+import ca.uhn.fhir.rest.annotation.Delete;
+import ca.uhn.fhir.rest.annotation.IdParam;
+import ca.uhn.fhir.rest.annotation.Operation;
+import ca.uhn.fhir.rest.annotation.OperationParam;
+import ca.uhn.fhir.rest.annotation.ResourceParam;
+import ca.uhn.fhir.rest.annotation.Update;
+import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
-import org.hl7.fhir.convertors.VersionConvertor_30_40;
-import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.dstu3.model.BooleanType;
+import org.hl7.fhir.dstu3.model.IdType;
+import org.hl7.fhir.dstu3.model.IntegerType;
+import org.hl7.fhir.dstu3.model.Meta;
+import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
@@ -41,6 +52,7 @@ import javax.servlet.http.HttpServletRequest;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_ADD;
import static ca.uhn.fhir.jpa.model.util.JpaConstants.OPERATION_META_DELETE;
+import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
public class JpaResourceProviderDstu3 extends BaseJpaResourceProvider {
@@ -91,7 +103,7 @@ public class JpaResourceProviderDstu3 extends BaseJpaRes
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
try {
- return VersionConvertor_30_40.convertParameters(retVal);
+ return convertParameters(retVal);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -107,7 +119,7 @@ public class JpaResourceProviderDstu3 extends BaseJpaRes
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
try {
- return VersionConvertor_30_40.convertParameters(retVal);
+ return convertParameters(retVal);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java
index f345c6f7361..c1f1970a0c1 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaSystemProviderDstu3.java
@@ -3,17 +3,26 @@ package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
-import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
+import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description;
-import ca.uhn.fhir.rest.annotation.*;
+import ca.uhn.fhir.rest.annotation.IdParam;
+import ca.uhn.fhir.rest.annotation.Operation;
+import ca.uhn.fhir.rest.annotation.OperationParam;
+import ca.uhn.fhir.rest.annotation.Transaction;
+import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
-import org.hl7.fhir.convertors.VersionConvertor_30_40;
-import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.dstu3.model.BooleanType;
+import org.hl7.fhir.dstu3.model.Bundle;
+import org.hl7.fhir.dstu3.model.DecimalType;
+import org.hl7.fhir.dstu3.model.IntegerType;
+import org.hl7.fhir.dstu3.model.Meta;
+import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
+import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IIdType;
@@ -29,6 +38,7 @@ import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
/*
* #%L
@@ -72,7 +82,7 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus dao = (IFhirResourceDaoConceptMap) getDao();
TranslationResult result = dao.translate(translationRequest, theRequestDetails);
org.hl7.fhir.r4.model.Parameters parameters = result.toParameters();
- return org.hl7.fhir.convertors.conv40_50.Parameters.convertParameters(parameters);
+ return org.hl7.fhir.convertors.conv40_50.Parameters40_50.convertParameters(parameters);
} finally {
endRequest(theServletRequest);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaResourceProviderR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaResourceProviderR5.java
index e3e4c6b54de..ef86e4f478b 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaResourceProviderR5.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaResourceProviderR5.java
@@ -86,7 +86,7 @@ public class JpaResourceProviderR5 extends BaseJpaResour
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters parameters = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
- return org.hl7.fhir.convertors.conv40_50.Parameters.convertParameters(parameters);
+ return org.hl7.fhir.convertors.conv40_50.Parameters40_50.convertParameters(parameters);
}
@@ -99,7 +99,7 @@ public class JpaResourceProviderR5 extends BaseJpaResour
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters parameters = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
- return org.hl7.fhir.convertors.conv40_50.Parameters.convertParameters(parameters);
+ return org.hl7.fhir.convertors.conv40_50.Parameters40_50.convertParameters(parameters);
}
@Operation(name = OPERATION_META, idempotent = true, returnParameters = {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java
index 7bacb42b6ba..4a99a931bbe 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/JpaSystemProviderR5.java
@@ -68,7 +68,7 @@ public class JpaSystemProviderR5 extends BaseJpaSystemProviderDstu2Plus myUnsyncedLastUpdated = new ConcurrentHashMap<>();
-
- @Override
- public void updateSearchLastReturned(Search theSearch, Date theDate) {
- myUnsyncedLastUpdated.put(theSearch.getId(), theDate);
- }
-
- @PostConstruct
- public void scheduleJob() {
- ScheduledJobDefinition jobDetail = new ScheduledJobDefinition();
- jobDetail.setId(getClass().getName());
- jobDetail.setJobClass(Job.class);
- mySchedulerService.scheduleLocalJob(10 * DateUtils.MILLIS_PER_SECOND, jobDetail);
- }
-
- @Override
- public void flushLastUpdated() {
- TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
- txTemplate.execute(t -> {
- for (Iterator> iter = myUnsyncedLastUpdated.entrySet().iterator(); iter.hasNext(); ) {
- Map.Entry next = iter.next();
- flushLastUpdated(next.getKey(), next.getValue());
- iter.remove();
- }
- return null;
- });
- }
-
- protected abstract void flushLastUpdated(Long theSearchId, Date theLastUpdated);
-
- public static class Job implements HapiJob {
- @Autowired
- private ISearchCacheSvc myTarget;
-
- @Override
- public void execute(JobExecutionContext theContext) {
- myTarget.flushLastUpdated();
- }
- }
-
-
-}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java
index 5a008d0f61c..8086644ab79 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/DatabaseSearchCacheSvcImpl.java
@@ -47,7 +47,7 @@ import java.util.Date;
import java.util.List;
import java.util.Optional;
-public class DatabaseSearchCacheSvcImpl extends BaseSearchCacheSvcImpl {
+public class DatabaseSearchCacheSvcImpl implements ISearchCacheSvc {
/*
* Be careful increasing this number! We use the number of params here in a
* DELETE FROM foo WHERE params IN (term,term,term...)
@@ -55,7 +55,7 @@ public class DatabaseSearchCacheSvcImpl extends BaseSearchCacheSvcImpl {
*/
public static final int DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_STMT = 500;
public static final int DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_PAS = 20000;
- public static final long DEFAULT_CUTOFF_SLACK = 10 * DateUtils.MILLIS_PER_SECOND;
+ public static final long SEARCH_CLEANUP_JOB_INTERVAL_MILLIS = 10 * DateUtils.MILLIS_PER_SECOND;
private static final Logger ourLog = LoggerFactory.getLogger(DatabaseSearchCacheSvcImpl.class);
private static int ourMaximumResultsToDeleteInOneStatement = DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_STMT;
private static int ourMaximumResultsToDeleteInOnePass = DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_PAS;
@@ -65,7 +65,7 @@ public class DatabaseSearchCacheSvcImpl extends BaseSearchCacheSvcImpl {
* is being reused (because a new client request came in with the same params) right before
* the result is to be deleted
*/
- private long myCutoffSlack = DEFAULT_CUTOFF_SLACK;
+ private long myCutoffSlack = SEARCH_CLEANUP_JOB_INTERVAL_MILLIS;
@Autowired
private ISearchDao mySearchDao;
@@ -146,11 +146,6 @@ public class DatabaseSearchCacheSvcImpl extends BaseSearchCacheSvcImpl {
}
- @Override
- protected void flushLastUpdated(Long theSearchId, Date theLastUpdated) {
- mySearchDao.updateSearchLastReturned(theSearchId, theLastUpdated);
- }
-
@Transactional(Transactional.TxType.NEVER)
@Override
public void pollForStaleSearchesAndDeleteThem() {
@@ -160,7 +155,7 @@ public class DatabaseSearchCacheSvcImpl extends BaseSearchCacheSvcImpl {
long cutoffMillis = myDaoConfig.getExpireSearchResultsAfterMillis();
if (myDaoConfig.getReuseCachedSearchResultsForMillis() != null) {
- cutoffMillis = Math.max(cutoffMillis, myDaoConfig.getReuseCachedSearchResultsForMillis());
+ cutoffMillis = cutoffMillis + myDaoConfig.getReuseCachedSearchResultsForMillis();
}
final Date cutoff = new Date((now() - cutoffMillis) - myCutoffSlack);
@@ -172,7 +167,7 @@ public class DatabaseSearchCacheSvcImpl extends BaseSearchCacheSvcImpl {
TransactionTemplate tt = new TransactionTemplate(myTxManager);
final Slice toDelete = tt.execute(theStatus ->
- mySearchDao.findWhereLastReturnedBefore(cutoff, new Date(), PageRequest.of(0, 2000))
+ mySearchDao.findWhereCreatedBefore(cutoff, new Date(), PageRequest.of(0, 2000))
);
assert toDelete != null;
@@ -223,7 +218,7 @@ public class DatabaseSearchCacheSvcImpl extends BaseSearchCacheSvcImpl {
// Only delete if we don't have results left in this search
if (resultPids.getNumberOfElements() < max) {
- ourLog.debug("Deleting search {}/{} - Created[{}] -- Last returned[{}]", searchToDelete.getId(), searchToDelete.getUuid(), new InstantType(searchToDelete.getCreated()), new InstantType(searchToDelete.getSearchLastReturned()));
+ ourLog.debug("Deleting search {}/{} - Created[{}]", searchToDelete.getId(), searchToDelete.getUuid(), new InstantType(searchToDelete.getCreated()));
mySearchDao.deleteByPid(searchToDelete.getId());
} else {
ourLog.debug("Purged {} search results for deleted search {}/{}", resultPids.getSize(), searchToDelete.getId(), searchToDelete.getUuid());
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java
index 90d9b1124e6..82b35d526e2 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/cache/ISearchCacheSvc.java
@@ -78,20 +78,6 @@ public interface ISearchCacheSvc {
*/
Collection findCandidatesForReuse(String theResourceType, String theQueryString, int theQueryStringHash, Date theCreatedAfter);
- /**
- * Mark a search as having been "last used" at the given time. This method may (and probably should) be implemented
- * to work asynchronously in order to avoid hammering the database if the search gets reused many times.
- *
- * @param theSearch The search
- * @param theDate The "last returned" timestamp
- */
- void updateSearchLastReturned(Search theSearch, Date theDate);
-
- /**
- * This is mostly public for unit tests
- */
- void flushLastUpdated();
-
/**
* This method will be called periodically to delete stale searches. Implementations are not required to do anything
* if they have some other mechanism for expiring stale results other than manually looking for them
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionTriggeringSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionTriggeringSvcImpl.java
index 32630819ce4..49506449095 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionTriggeringSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionTriggeringSvcImpl.java
@@ -66,7 +66,13 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
-import java.util.concurrent.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider.RESOURCE_ID;
@@ -136,8 +142,8 @@ public class SubscriptionTriggeringSvcImpl implements ISubscriptionTriggeringSvc
SubscriptionTriggeringJobDetails jobDetails = new SubscriptionTriggeringJobDetails();
jobDetails.setJobId(UUID.randomUUID().toString());
- jobDetails.setRemainingResourceIds(resourceIds.stream().map(t->t.getValue()).collect(Collectors.toList()));
- jobDetails.setRemainingSearchUrls(searchUrls.stream().map(t->t.getValue()).collect(Collectors.toList()));
+ jobDetails.setRemainingResourceIds(resourceIds.stream().map(t -> t.getValue()).collect(Collectors.toList()));
+ jobDetails.setRemainingSearchUrls(searchUrls.stream().map(t -> t.getValue()).collect(Collectors.toList()));
if (theSubscriptionId != null) {
jobDetails.setSubscriptionId(theSubscriptionId.getIdPart());
}
@@ -386,7 +392,13 @@ public class SubscriptionTriggeringSvcImpl implements ISubscriptionTriggeringSvc
ScheduledJobDefinition jobDetail = new ScheduledJobDefinition();
jobDetail.setId(getClass().getName());
jobDetail.setJobClass(Job.class);
- mySchedulerService.scheduleLocalJob(60 * DateUtils.MILLIS_PER_SECOND, jobDetail);
+ // Currently jobs ae kept in a local ArrayList so this should be a local job, and
+ // it can fire frequently without adding load
+ mySchedulerService.scheduleLocalJob(5 * DateUtils.MILLIS_PER_SECOND, jobDetail);
+ }
+
+ public int getActiveJobCount() {
+ return myActiveJobs.size();
}
public static class Job implements HapiJob {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java
index fe2a72fbd1f..02891e7c508 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseTermReadSvcImpl.java
@@ -1414,7 +1414,6 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
TermConceptMapGroupElement termConceptMapGroupElement;
for (ConceptMap.SourceElementComponent element : group.getElement()) {
if (isBlank(element.getCode())) {
- // FIXME: JA - send this to an interceptor message so it can be output
continue;
}
termConceptMapGroupElement = new TermConceptMapGroupElement();
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java
index 461442de503..f7b151d3fa0 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermLoaderSvcImpl.java
@@ -388,7 +388,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
}
}
- // FIXME: DM 2019-09-13 - Manually add EXTERNAL_COPYRIGHT_NOTICE property until Regenstrief adds this to loinc.xml
+ // TODO: DM 2019-09-13 - Manually add EXTERNAL_COPYRIGHT_NOTICE property until Regenstrief adds this to loinc.xml
if (!propertyNamesToTypes.containsKey("EXTERNAL_COPYRIGHT_NOTICE")) {
String externalCopyRightNoticeCode = "EXTERNAL_COPYRIGHT_NOTICE";
CodeSystem.PropertyType externalCopyRightNoticeType = CodeSystem.PropertyType.STRING;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java
index 6f949a61933..aee82c3ce8c 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcDstu3.java
@@ -9,10 +9,13 @@ import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.CoverageIgnore;
import ca.uhn.fhir.util.ValidateUtil;
-import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
-import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
+import org.hl7.fhir.dstu3.model.CodeableConcept;
+import org.hl7.fhir.dstu3.model.Coding;
+import org.hl7.fhir.dstu3.model.StructureDefinition;
+import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.exceptions.FHIRException;
@@ -31,6 +34,9 @@ import java.util.List;
import java.util.Optional;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
+import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
+import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSetExpansionComponent;
/*
* #%L
@@ -104,7 +110,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = toCanonicalValueSet(valueSetToExpand);
org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent expandedR4 = super.expandValueSetInMemory(valueSetToExpandR4, null).getExpansion();
- return VersionConvertor_30_40.convertValueSetExpansionComponent(expandedR4);
+ return convertValueSetExpansionComponent(expandedR4);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -118,7 +124,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = toCanonicalValueSet(valueSetToExpand);
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSetInMemory(valueSetToExpandR4, null);
- return VersionConvertor_30_40.convertValueSet(expandedR4);
+ return convertValueSet(expandedR4);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -127,7 +133,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
@Override
protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws FHIRException {
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
- valueSetToExpandR4 = VersionConvertor_30_40.convertValueSet((ValueSet) theValueSet);
+ valueSetToExpandR4 = convertValueSet((ValueSet) theValueSet);
return valueSetToExpandR4;
}
@@ -139,7 +145,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = toCanonicalValueSet(valueSetToExpand);
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(valueSetToExpandR4, theOffset, theCount);
- return VersionConvertor_30_40.convertValueSet(expandedR4);
+ return convertValueSet(expandedR4);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -256,7 +262,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
public org.hl7.fhir.r4.model.CodeSystem getCodeSystemFromContext(String theSystem) {
CodeSystem codeSystem = myValidationSupport.fetchCodeSystem(myContext, theSystem);
try {
- return VersionConvertor_30_40.convertCodeSystem(codeSystem);
+ return convertCodeSystem(codeSystem);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -323,7 +329,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
public ValidateCodeResult validateCodeIsInPreExpandedValueSet(IBaseResource theValueSet, String theSystem, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept) {
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null");
ValueSet valueSet = (ValueSet) theValueSet;
- org.hl7.fhir.r4.model.ValueSet valueSetR4 = VersionConvertor_30_40.convertValueSet(valueSet);
+ org.hl7.fhir.r4.model.ValueSet valueSetR4 = convertValueSet(valueSet);
Coding coding = (Coding) theCoding;
org.hl7.fhir.r4.model.Coding codingR4 = null;
@@ -347,7 +353,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
public boolean isValueSetPreExpandedForCodeValidation(IBaseResource theValueSet) {
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null");
ValueSet valueSet = (ValueSet) theValueSet;
- org.hl7.fhir.r4.model.ValueSet valueSetR4 = VersionConvertor_30_40.convertValueSet(valueSet);
+ org.hl7.fhir.r4.model.ValueSet valueSetR4 = convertValueSet(valueSet);
return super.isValueSetPreExpandedForCodeValidation(valueSetR4);
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR5.java
index 6449945ddb2..a4f8ab5136b 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR5.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermReadSvcR5.java
@@ -90,21 +90,21 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
super.throwInvalidValueSet(theValueSet);
}
- return expandValueSetAndReturnVersionIndependentConcepts(org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(valueSetR5), null);
+ return expandValueSetAndReturnVersionIndependentConcepts(org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR5), null);
}
@Override
public IBaseResource expandValueSet(IBaseResource theInput) {
org.hl7.fhir.r4.model.ValueSet valueSetToExpand = toCanonicalValueSet(theInput);
org.hl7.fhir.r4.model.ValueSet valueSetR4 = super.expandValueSetInMemory(valueSetToExpand, null);
- return org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(valueSetR4);
+ return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR4);
}
@Override
public IBaseResource expandValueSet(IBaseResource theInput, int theOffset, int theCount) {
org.hl7.fhir.r4.model.ValueSet valueSetToExpand = toCanonicalValueSet(theInput);
org.hl7.fhir.r4.model.ValueSet valueSetR4 = super.expandValueSet(valueSetToExpand, theOffset, theCount);
- return org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(valueSetR4);
+ return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR4);
}
@Override
@@ -117,8 +117,8 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
public ValueSetExpander.ValueSetExpansionOutcome expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
ValueSet valueSetToExpand = new ValueSet();
valueSetToExpand.getCompose().addInclude(theInclude);
- org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSetInMemory(org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(valueSetToExpand), null);
- return new ValueSetExpander.ValueSetExpansionOutcome(org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(expandedR4));
+ org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSetInMemory(org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetToExpand), null);
+ return new ValueSetExpander.ValueSetExpansionOutcome(org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(expandedR4));
}
@Override
@@ -199,13 +199,13 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Override
public org.hl7.fhir.r4.model.CodeSystem getCodeSystemFromContext(String theSystem) {
CodeSystem codeSystemR5 = myValidationSupport.fetchCodeSystem(myContext, theSystem);
- return org.hl7.fhir.convertors.conv40_50.CodeSystem.convertCodeSystem(codeSystemR5);
+ return org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(codeSystemR5);
}
@Override
protected org.hl7.fhir.r4.model.ValueSet getValueSetFromResourceTable(ResourceTable theResourceTable) {
ValueSet valueSetR5 = myValueSetResourceDao.toResource(ValueSet.class, theResourceTable, null, false);
- return org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(valueSetR5);
+ return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR5);
}
@Override
@@ -277,7 +277,7 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Override
protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws org.hl7.fhir.exceptions.FHIRException {
- return org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet((ValueSet) theValueSet);
+ return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet((ValueSet) theValueSet);
}
@Override
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java
index 925d0503811..5fce60cfa30 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcDstu3.java
@@ -37,6 +37,9 @@ import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.EventListener;
import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
+import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
+import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
@@ -72,7 +75,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource) {
CodeSystem resourceToStore;
try {
- resourceToStore = VersionConvertor_30_40.convertCodeSystem(theCodeSystemResource);
+ resourceToStore = convertCodeSystem(theCodeSystemResource);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -89,7 +92,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) {
ConceptMap resourceToStore;
try {
- resourceToStore = VersionConvertor_30_40.convertConceptMap(theConceptMap);
+ resourceToStore = convertConceptMap(theConceptMap);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -105,7 +108,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
ValueSet valueSetDstu3;
try {
- valueSetDstu3 = VersionConvertor_30_40.convertValueSet(theValueSet);
+ valueSetDstu3 = convertValueSet(theValueSet);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java
index f0f653d3667..83cc9c0ae76 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TermVersionAdapterSvcR5.java
@@ -62,7 +62,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource) {
validateCodeSystemForStorage(theCodeSystemResource);
- CodeSystem codeSystemR4 = org.hl7.fhir.convertors.conv40_50.CodeSystem.convertCodeSystem(theCodeSystemResource);
+ CodeSystem codeSystemR4 = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(theCodeSystemResource);
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
return myCodeSystemResourceDao.update(codeSystemR4, matchUrl).getId();
@@ -74,7 +74,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
@Override
public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) {
- ConceptMap conceptMapR4 = org.hl7.fhir.convertors.conv40_50.ConceptMap.convertConceptMap(theConceptMap);
+ ConceptMap conceptMapR4 = org.hl7.fhir.convertors.conv40_50.ConceptMap40_50.convertConceptMap(theConceptMap);
if (isBlank(theConceptMap.getIdElement().getIdPart())) {
String matchUrl = "ConceptMap?url=" + UrlUtil.escapeUrlParam(theConceptMap.getUrl());
@@ -87,7 +87,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
@Override
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
- ValueSet valueSetR4 = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(theValueSet);
+ ValueSet valueSetR4 = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(theValueSet);
if (isBlank(theValueSet.getIdElement().getIdPart())) {
String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl());
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermLoaderSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermLoaderSvc.java
index 58e7195a3bc..01e55dcf267 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermLoaderSvc.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/api/ITermLoaderSvc.java
@@ -44,14 +44,11 @@ public interface ITermLoaderSvc {
UploadStatistics loadSnomedCt(List theFiles, RequestDetails theRequestDetails);
- // FIXME: remove the default implementation before 4.1.0
- default UploadStatistics loadCustom(String theSystem, List theFiles, RequestDetails theRequestDetails) { return null; };
+ UploadStatistics loadCustom(String theSystem, List theFiles, RequestDetails theRequestDetails);
- // FIXME: remove the default implementation before 4.1.0
- default UploadStatistics loadDeltaAdd(String theSystem, List theFiles, RequestDetails theRequestDetails) { return null; };
+ UploadStatistics loadDeltaAdd(String theSystem, List theFiles, RequestDetails theRequestDetails);
- // FIXME: remove the default implementation before 4.1.0
- default UploadStatistics loadDeltaRemove(String theSystem, List theFiles, RequestDetails theRequestDetails) { return null; };
+ UploadStatistics loadDeltaRemove(String theSystem, List theFiles, RequestDetails theRequestDetails);
interface FileDescriptor {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java
index 6c7c2c14427..ecf3dce5c73 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/loinc/LoincHandler.java
@@ -86,7 +86,7 @@ public class LoincHandler implements IRecordHandler {
concept.addPropertyString(nextPropertyName, nextPropertyValue);
break;
case CODING:
- // FIXME: handle "Ser/Plas^Donor"
+ // TODO: handle "Ser/Plas^Donor"
String propertyValue = nextPropertyValue;
if (nextPropertyName.equals("COMPONENT")) {
if (propertyValue.contains("^")) {
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java
index df32f31e341..f02a9203011 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java
@@ -1,9 +1,5 @@
package ca.uhn.fhir.jpa.dao.dstu2;
-import static org.hamcrest.Matchers.containsString;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
@@ -32,7 +28,11 @@ import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
-import java.util.Arrays;
+import java.util.Collections;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2ValidateTest.class);
@@ -94,15 +94,14 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
myStructureDefinitionDao.create(sd, mySrd);
Observation input = new Observation();
- ResourceMetadataKeyEnum.PROFILES.put(input, Arrays.asList(new IdDt(sd.getUrl())));
+ ResourceMetadataKeyEnum.PROFILES.put(input, Collections.singletonList(new IdDt(sd.getUrl())));
input.addIdentifier().setSystem("http://acme").setValue("12345");
input.getEncounter().setReference("http://foo.com/Encounter/9");
input.setStatus(ObservationStatusEnum.FINAL);
input.getCode().addCoding().setSystem("http://loinc.org").setCode("12345");
- String encoded = null;
- MethodOutcome outcome = null;
+ String encoded;
ValidationModeEnum mode = ValidationModeEnum.CREATE;
switch (enc) {
case JSON:
@@ -130,12 +129,12 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
}
@Test
- public void testValidateResourceContainingProfileDeclarationInvalid() throws Exception {
+ public void testValidateResourceContainingProfileDeclarationInvalid() {
String methodName = "testValidateResourceContainingProfileDeclarationInvalid";
Observation input = new Observation();
String profileUri = "http://example.com/StructureDefinition/" + methodName;
- ResourceMetadataKeyEnum.PROFILES.put(input, Arrays.asList(new IdDt(profileUri)));
+ ResourceMetadataKeyEnum.PROFILES.put(input, Collections.singletonList(new IdDt(profileUri)));
input.addIdentifier().setSystem("http://acme").setValue("12345");
input.getEncounter().setReference("http://foo.com/Encounter/9");
@@ -148,7 +147,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
String ooString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome());
ourLog.info(ooString);
- assertThat(ooString, containsString("StructureDefinition reference \\\"" + profileUri + "\\\" could not be resolved"));
+ assertThat(ooString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' could not be resolved, so has not been checked"));
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java
index 45bb5e84837..bdc3ad3a2d7 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java
@@ -35,7 +35,6 @@ import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.io.IOUtils;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
-import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.exceptions.FHIRException;
@@ -60,6 +59,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
+import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
import static org.junit.Assert.fail;
@RunWith(SpringJUnit4ClassRunner.class)
@@ -386,7 +386,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
*/
public static ConceptMap createConceptMap() {
try {
- return VersionConvertor_30_40.convertConceptMap(BaseJpaR4Test.createConceptMap());
+ return convertConceptMap(BaseJpaR4Test.createConceptMap());
} catch (FHIRException fe) {
throw new InternalErrorException(fe);
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java
index 3619811ca47..7430378c272 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java
@@ -15,6 +15,7 @@ import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
+import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.utils.IResourceValidator;
@@ -99,7 +100,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
myValueSetDao.create(vs);
ValueSet expansion = myValueSetDao.expandByIdentifier("http://ccim.on.ca/fhir/iar/ValueSet/iar-citizenship-status", null);
- ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion));
+ ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion));
// Questionnaire q = loadResourceFromClasspath(Questionnaire.class,"/dstu3/iar/Questionnaire-iar-test.xml" );
// myQuestionnaireDao.create(q);
@@ -322,15 +323,11 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
ValidationModeEnum mode = ValidationModeEnum.CREATE;
String encoded = myFhirCtx.newJsonParser().encodeResourceToString(input);
- try {
- myObservationDao.validate(input, null, encoded, EncodingEnum.JSON, mode, null, mySrd);
- fail();
- } catch (PreconditionFailedException e) {
- String ooString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome());
- ourLog.info(ooString);
- assertThat(ooString, containsString("StructureDefinition reference \\\"" + profileUri + "\\\" could not be resolved"));
- }
-
+ MethodOutcome output = myObservationDao.validate(input, null, encoded, EncodingEnum.JSON, mode, null, mySrd);
+ OperationOutcome oo = (OperationOutcome) output.getOperationOutcome();
+ String outputString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
+ ourLog.info(outputString);
+ assertThat(outputString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' could not be resolved, so has not been checked"));
}
@Test
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
index 7dfffc7dfb9..a3f8a136228 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
@@ -64,7 +64,6 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.util.AopTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import java.io.IOException;
@@ -409,7 +408,6 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
}
@Before
- @Transactional()
public void beforePurgeDatabase() {
purgeDatabase(myDaoConfig, mySystemDao, myResourceReindexingSvc, mySearchCoordinatorSvc, mySearchParamRegistry, myBulkDataExportSvc);
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java
index fcd0961bd9f..c81ca66f935 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchPageExpiryTest.java
@@ -32,7 +32,7 @@ import javax.annotation.Nullable;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
-import static ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl.DEFAULT_CUTOFF_SLACK;
+import static ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl.SEARCH_CLEANUP_JOB_INTERVAL_MILLIS;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.*;
@@ -47,7 +47,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
@After()
public void after() {
DatabaseSearchCacheSvcImpl staleSearchDeletingSvc = AopTestUtils.getTargetObject(mySearchCacheSvc);
- staleSearchDeletingSvc.setCutoffSlackForUnitTest(DEFAULT_CUTOFF_SLACK);
+ staleSearchDeletingSvc.setCutoffSlackForUnitTest(SEARCH_CLEANUP_JOB_INTERVAL_MILLIS);
DatabaseSearchCacheSvcImpl.setNowForUnitTests(null);
}
@@ -81,8 +81,11 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
Thread.sleep(10);
- myDaoConfig.setExpireSearchResultsAfterMillis(1000L);
- myDaoConfig.setReuseCachedSearchResultsForMillis(500L);
+ long reuseCachedSearchResultsForMillis = 500L;
+ myDaoConfig.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsForMillis);
+ long millisBetweenReuseAndExpire = 800L;
+ long expireSearchResultsAfterMillis = 1000L;
+ myDaoConfig.setExpireSearchResultsAfterMillis(expireSearchResultsAfterMillis);
long start = System.currentTimeMillis();
DatabaseSearchCacheSvcImpl.setNowForUnitTests(start);
@@ -107,9 +110,9 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
assertEquals(searchUuid1, searchUuid2);
- TestUtil.sleepAtLeast(501);
+ TestUtil.sleepAtLeast(reuseCachedSearchResultsForMillis + 1);
- // We're now past 500ms so we shouldn't reuse the search
+ // We're now past reuseCachedSearchResultsForMillis so we shouldn't reuse the search
final String searchUuid3;
{
@@ -124,35 +127,36 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
// Search just got used so it shouldn't be deleted
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(start + 500);
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(start + reuseCachedSearchResultsForMillis);
+ final AtomicLong search1timestamp = new AtomicLong();
+ final AtomicLong search2timestamp = new AtomicLong();
final AtomicLong search3timestamp = new AtomicLong();
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
- Search search3 = mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3).orElseThrow(()->new InternalErrorException("Search doesn't exist"));
- assertNotNull(search3);
+ Search search1 = mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid1).orElseThrow(()->new InternalErrorException("Search doesn't exist"));
+ assertNotNull(search1);
+ search1timestamp.set(search1.getCreated().getTime());
Search search2 = mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid2).orElseThrow(()->new InternalErrorException("Search doesn't exist"));
assertNotNull(search2);
- search3timestamp.set(search2.getSearchLastReturned().getTime());
+ search2timestamp.set(search2.getCreated().getTime());
+ Search search3 = mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3).orElseThrow(()->new InternalErrorException("Search doesn't exist"));
+ assertNotNull(search3);
+ search3timestamp.set(search3.getCreated().getTime());
}
});
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(search3timestamp.get() + 800);
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(search1timestamp.get() + millisBetweenReuseAndExpire);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
- assertNotNull(mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3));
- }
- });
- newTxTemplate().execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
- assertNotNull(mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid1));
+ assertTrue(mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3).isPresent());
+ assertTrue(mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid1).isPresent());
}
});
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(search3timestamp.get() + 1100);
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(search1timestamp.get() + reuseCachedSearchResultsForMillis + expireSearchResultsAfterMillis + 1);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
@@ -163,14 +167,12 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
});
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(search3timestamp.get() + 2100);
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(search3timestamp.get() + reuseCachedSearchResultsForMillis + expireSearchResultsAfterMillis + 1);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
await().until(()-> newTxTemplate().execute(t -> !mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid1).isPresent()));
await().until(()-> newTxTemplate().execute(t -> !mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3).isPresent()));
-
-
}
@Test
@@ -197,7 +199,6 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
params.add(Patient.SP_FAMILY, new StringParam("EXPIRE"));
final IBundleProvider bundleProvider = myPatientDao.search(params);
assertThat(toUnqualifiedVersionlessIds(bundleProvider), containsInAnyOrder(pid1, pid2));
- assertThat(toUnqualifiedVersionlessIds(bundleProvider), containsInAnyOrder(pid1, pid2));
waitForSearchToSave(bundleProvider.getUuid());
final AtomicLong start = new AtomicLong();
@@ -213,9 +214,11 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
});
- myDaoConfig.setExpireSearchResultsAfterMillis(500);
- myDaoConfig.setReuseCachedSearchResultsForMillis(500L);
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(start.get() + 499);
+ int expireSearchResultsAfterMillis = 700;
+ myDaoConfig.setExpireSearchResultsAfterMillis(expireSearchResultsAfterMillis);
+ long reuseCachedSearchResultsForMillis = 400L;
+ myDaoConfig.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsForMillis);
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(start.get() + expireSearchResultsAfterMillis - 1);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
@@ -224,7 +227,7 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
});
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(start.get() + 600);
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(start.get() + expireSearchResultsAfterMillis + reuseCachedSearchResultsForMillis + 1);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
@@ -251,8 +254,12 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
Thread.sleep(10);
- myDaoConfig.setExpireSearchResultsAfterMillis(1000L);
- myDaoConfig.setReuseCachedSearchResultsForMillis(500L);
+ long expireSearchResultsAfterMillis = 1000L;
+ myDaoConfig.setExpireSearchResultsAfterMillis(expireSearchResultsAfterMillis);
+
+ long reuseCachedSearchResultsForMillis = 500L;
+ myDaoConfig.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsForMillis);
+
long start = System.currentTimeMillis();
final String searchUuid1;
@@ -278,9 +285,10 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
assertEquals(searchUuid1, searchUuid2);
- TestUtil.sleepAtLeast(501);
+ TestUtil.sleepAtLeast(reuseCachedSearchResultsForMillis + 1);
+ myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
- // We're now past 500ms so we shouldn't reuse the search
+ // We're now past reuseCachedSearchResultsForMillis so we shouldn't reuse the search
final String searchUuid3;
{
@@ -293,37 +301,35 @@ public class FhirResourceDaoR4SearchPageExpiryTest extends BaseJpaR4Test {
}
assertNotEquals(searchUuid1, searchUuid3);
- // Search just got used so it shouldn't be deleted
+ waitForSearchToSave(searchUuid3);
+
+ // Search hasn't expired yet so it shouldn't be deleted
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
+ final AtomicLong search1timestamp = new AtomicLong();
final AtomicLong search3timestamp = new AtomicLong();
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
+ Search search1 = mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid1).orElseThrow(()->new InternalErrorException("Search doesn't exist"));
Search search3 = mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3).orElseThrow(()->new InternalErrorException("Search doesn't exist"));
assertNotNull(search3);
+ search1timestamp.set(search1.getCreated().getTime());
search3timestamp.set(search3.getCreated().getTime());
}
});
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(search3timestamp.get() + 800);
-
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(search1timestamp.get() + expireSearchResultsAfterMillis + reuseCachedSearchResultsForMillis + 1);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
- newTxTemplate().execute(new TransactionCallbackWithoutResult() {
- @Override
- protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
- assertNotNull(mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3));
- }
- });
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
assertFalse(mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid1).isPresent());
+ assertTrue(mySearchEntityDao.findByUuidAndFetchIncludes(searchUuid3).isPresent());
}
});
- DatabaseSearchCacheSvcImpl.setNowForUnitTests(search3timestamp.get() + 2100);
-
+ DatabaseSearchCacheSvcImpl.setNowForUnitTests(search3timestamp.get() + expireSearchResultsAfterMillis + reuseCachedSearchResultsForMillis + 1);
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
@Override
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/FhirResourceDaoR4SearchWithElasticSearchTest.java
index bfe7f9cba39..23ee3628fc5 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/FhirResourceDaoR4SearchWithElasticSearchTest.java
@@ -47,7 +47,6 @@ import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4ConfigWithElasticSearch.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-@Ignore // FIXME: remove
public class FhirResourceDaoR4SearchWithElasticSearchTest 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";
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java
index 74bfa659695..2351887144f 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java
@@ -395,15 +395,11 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
ValidationModeEnum mode = ValidationModeEnum.CREATE;
String encoded = myFhirCtx.newJsonParser().encodeResourceToString(input);
- try {
- myObservationDao.validate(input, null, encoded, EncodingEnum.JSON, mode, null, mySrd);
- fail();
- } catch (PreconditionFailedException e) {
- String ooString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome());
- ourLog.info(ooString);
- assertThat(ooString, containsString("StructureDefinition reference \\\"" + profileUri + "\\\" could not be resolved"));
- }
-
+ MethodOutcome output = myObservationDao.validate(input, null, encoded, EncodingEnum.JSON, mode, null, mySrd);
+ org.hl7.fhir.r4.model.OperationOutcome oo = (org.hl7.fhir.r4.model.OperationOutcome) output.getOperationOutcome();
+ String outputString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo);
+ ourLog.info(outputString);
+ assertThat(outputString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' could not be resolved, so has not been checked"));
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java
index 69a03290a8a..45edc4928c7 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3Test.java
@@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.provider.r4.ResourceProviderR4Test;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
+import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.UriDt;
@@ -65,6 +66,7 @@ import java.math.BigDecimal;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
+import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
@@ -3003,7 +3005,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
.count(5)
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid1 = toSearchUuidFromLinkNext(result1);
Search search1 = newTxTemplate().execute(new TransactionCallback() {
@@ -3012,7 +3013,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
return mySearchEntityDao.findByUuidAndFetchIncludes(uuid1).orElseThrow(() -> new InternalErrorException(""));
}
});
- Date lastReturned1 = search1.getSearchLastReturned();
+ Date created1 = search1.getCreated();
Bundle result2 = ourClient
.search()
@@ -3021,7 +3022,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
.count(5)
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid2 = toSearchUuidFromLinkNext(result2);
Search search2 = newTxTemplate().execute(new TransactionCallback() {
@@ -3030,9 +3030,9 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
return mySearchEntityDao.findByUuidAndFetchIncludes(uuid2).orElseThrow(() -> new InternalErrorException(""));
}
});
- Date lastReturned2 = search2.getSearchLastReturned();
+ Date created2 = search2.getCreated();
- assertTrue(lastReturned2.getTime() > lastReturned1.getTime());
+ assertEquals(created2.getTime(), created1.getTime());
Thread.sleep(1500);
@@ -3067,24 +3067,22 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
.forResource("Organization")
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid1 = toSearchUuidFromLinkNext(result1);
Search search1 = newTxTemplate().execute(theStatus -> mySearchEntityDao.findByUuidAndFetchIncludes(uuid1).orElseThrow(() -> new InternalErrorException("")));
- Date lastReturned1 = search1.getSearchLastReturned();
+ Date created1 = search1.getCreated();
Bundle result2 = ourClient
.search()
.forResource("Organization")
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid2 = toSearchUuidFromLinkNext(result2);
Search search2 = newTxTemplate().execute(theStatus -> mySearchEntityDao.findByUuidAndFetchIncludes(uuid2).orElseThrow(() -> new InternalErrorException("")));
- Date lastReturned2 = search2.getSearchLastReturned();
+ Date created2 = search2.getCreated();
- assertTrue(lastReturned2.getTime() > lastReturned1.getTime());
+ assertEquals(created2.getTime(), created1.getTime());
assertEquals(uuid1, uuid2);
}
@@ -4282,6 +4280,55 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
}
+ @Test
+ public void testNearSearchApproximate() {
+ Location loc = new Location();
+ double latitude = CoordCalculatorTest.LATITUDE_UHN;
+ double longitude = CoordCalculatorTest.LONGITUDE_UHN;
+ Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
+ loc.setPosition(position);
+ IIdType locId = ourClient.create().resource(loc).execute().getId().toUnqualifiedVersionless();
+
+ { // In the box
+ double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
+ String url = "/Location?" +
+ Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
+ "&" +
+ Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
+
+ Bundle actual = ourClient
+ .search()
+ .byUrl(ourServerBase + "/" + url)
+ .encodedJson()
+ .prettyPrint()
+ .returnBundle(Bundle.class)
+ .execute();
+
+ assertEquals(1, actual.getEntry().size());
+ assertEquals(locId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
+ }
+ { // Outside the box
+ double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
+ String url = "/Location?" +
+ Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
+ "&" +
+ Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
+
+ myCaptureQueriesListener.clear();
+ Bundle actual = ourClient
+ .search()
+ .byUrl(ourServerBase + "/" + url)
+ .encodedJson()
+ .prettyPrint()
+ .returnBundle(Bundle.class)
+ .execute();
+ myCaptureQueriesListener.logSelectQueries();
+
+ assertEquals(0, actual.getEntry().size());
+ }
+
+ }
+
private String toStr(Date theDate) {
return new InstantDt(theDate).getValueAsString();
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java
index 22a94634be4..a8f485ba05d 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java
@@ -14,27 +14,15 @@ import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.rest.api.Constants;
-import ca.uhn.fhir.rest.api.MethodOutcome;
-import ca.uhn.fhir.rest.api.PreferReturnEnum;
-import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
-import ca.uhn.fhir.rest.api.SummaryEnum;
+import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.client.api.IClientInterceptor;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
import ca.uhn.fhir.rest.gclient.StringClientParam;
-import ca.uhn.fhir.rest.param.DateRangeParam;
-import ca.uhn.fhir.rest.param.NumberParam;
-import ca.uhn.fhir.rest.param.ParamPrefixEnum;
-import ca.uhn.fhir.rest.param.StringAndListParam;
-import ca.uhn.fhir.rest.param.StringOrListParam;
-import ca.uhn.fhir.rest.param.StringParam;
-import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
-import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
-import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
-import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
-import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
+import ca.uhn.fhir.rest.param.*;
+import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.UrlUtil;
@@ -46,29 +34,16 @@ import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPatch;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.*;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;
import org.hamcrest.Matchers;
-import org.hl7.fhir.instance.model.api.IAnyResource;
-import org.hl7.fhir.instance.model.api.IBaseBundle;
-import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
-import org.hl7.fhir.instance.model.api.IBaseResource;
-import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.r4.model.*;
-import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
-import org.hl7.fhir.r4.model.Bundle.BundleLinkComponent;
-import org.hl7.fhir.r4.model.Bundle.BundleType;
-import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
-import org.hl7.fhir.r4.model.Bundle.SearchEntryMode;
+import org.hl7.fhir.r4.model.Bundle.*;
import org.hl7.fhir.r4.model.Encounter.EncounterLocationComponent;
import org.hl7.fhir.r4.model.Encounter.EncounterStatus;
import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender;
@@ -77,11 +52,7 @@ import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.Questionnaire.QuestionnaireItemType;
import org.hl7.fhir.r4.model.Subscription.SubscriptionChannelType;
import org.hl7.fhir.r4.model.Subscription.SubscriptionStatus;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
+import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.AopTestUtils;
import org.springframework.transaction.TransactionStatus;
@@ -96,28 +67,14 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.*;
import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast;
import static ca.uhn.fhir.jpa.util.TestUtil.sleepOneClick;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
@SuppressWarnings("Duplicates")
public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
@@ -4115,11 +4072,10 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.count(5)
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid1 = toSearchUuidFromLinkNext(result1);
Search search1 = newTxTemplate().execute(theStatus -> mySearchEntityDao.findByUuidAndFetchIncludes(uuid1).orElseThrow(() -> new InternalErrorException("")));
- Date lastReturned1 = search1.getSearchLastReturned();
+ Date created1 = search1.getCreated();
Bundle result2 = ourClient
.search()
@@ -4128,13 +4084,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.count(5)
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid2 = toSearchUuidFromLinkNext(result2);
Search search2 = newTxTemplate().execute(theStatus -> mySearchEntityDao.findByUuidAndFetchIncludes(uuid2).orElseThrow(() -> new InternalErrorException("")));
- Date lastReturned2 = search2.getSearchLastReturned();
+ Date created2 = search2.getCreated();
- assertTrue(lastReturned2.getTime() > lastReturned1.getTime());
+ assertEquals(created2.getTime(), created1.getTime());
Thread.sleep(1500);
@@ -4145,7 +4100,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.count(5)
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
String uuid3 = toSearchUuidFromLinkNext(result3);
@@ -4170,11 +4124,10 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.forResource("Organization")
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid1 = toSearchUuidFromLinkNext(result1);
Search search1 = newTxTemplate().execute(theStatus -> mySearchEntityDao.findByUuidAndFetchIncludes(uuid1).orElseThrow(() -> new InternalErrorException("")));
- Date lastReturned1 = search1.getSearchLastReturned();
+ Date created1 = search1.getCreated();
sleepOneClick();
@@ -4183,13 +4136,12 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
.forResource("Organization")
.returnBundle(Bundle.class)
.execute();
- mySearchCacheSvc.flushLastUpdated();
final String uuid2 = toSearchUuidFromLinkNext(result2);
Search search2 = newTxTemplate().execute(theStatus -> mySearchEntityDao.findByUuidAndFetchIncludes(uuid2).orElseThrow(() -> new InternalErrorException("")));
- Date lastReturned2 = search2.getSearchLastReturned();
+ Date created2 = search2.getCreated();
- assertTrue(lastReturned2.getTime() > lastReturned1.getTime());
+ assertEquals(created2.getTime(), created1.getTime());
assertEquals(uuid1, uuid2);
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java
index a760af6a195..c66c824022c 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/StaleSearchDeletingSvcR4Test.java
@@ -9,12 +9,10 @@ import ca.uhn.fhir.jpa.entity.SearchResult;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
-import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl;
import ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl;
import ca.uhn.fhir.rest.gclient.IClientExecutable;
import ca.uhn.fhir.rest.gclient.IQuery;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
-import ca.uhn.fhir.test.utilities.UnregisterScheduledProcessor;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.r4.model.Bundle;
@@ -25,7 +23,6 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.TestPropertySource;
import org.springframework.test.util.AopTestUtils;
import java.util.Date;
@@ -50,7 +47,7 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
public void after() throws Exception {
super.after();
DatabaseSearchCacheSvcImpl staleSearchDeletingSvc = AopTestUtils.getTargetObject(mySearchCacheSvc);
- staleSearchDeletingSvc.setCutoffSlackForUnitTest(DatabaseSearchCacheSvcImpl.DEFAULT_CUTOFF_SLACK);
+ staleSearchDeletingSvc.setCutoffSlackForUnitTest(DatabaseSearchCacheSvcImpl.SEARCH_CLEANUP_JOB_INTERVAL_MILLIS);
DatabaseSearchCacheSvcImpl.setMaximumResultsToDeleteForUnitTest(DatabaseSearchCacheSvcImpl.DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_STMT);
DatabaseSearchCacheSvcImpl.setMaximumResultsToDeleteInOnePassForUnitTest(DatabaseSearchCacheSvcImpl.DEFAULT_MAX_RESULTS_TO_DELETE_IN_ONE_PAS);
}
@@ -121,7 +118,6 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
search.setCreated(DateUtils.addDays(new Date(), -10000));
search.setSearchType(SearchTypeEnum.SEARCH);
search.setResourceType("Patient");
- search.setSearchLastReturned(DateUtils.addDays(new Date(), -10000));
search = mySearchEntityDao.save(search);
for (int i = 0; i < 15; i++) {
@@ -163,7 +159,6 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
search.setCreated(DateUtils.addDays(new Date(), -10000));
search.setSearchType(SearchTypeEnum.SEARCH);
search.setResourceType("Patient");
- search.setSearchLastReturned(DateUtils.addDays(new Date(), -10000));
mySearchEntityDao.save(search);
});
@@ -190,7 +185,6 @@ public class StaleSearchDeletingSvcR4Test extends BaseResourceProviderR4Test {
search.setCreated(DateUtils.addDays(new Date(), -10000));
search.setSearchType(SearchTypeEnum.SEARCH);
search.setResourceType("Patient");
- search.setSearchLastReturned(DateUtils.addDays(new Date(), -10000));
search = mySearchEntityDao.save(search);
});
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java
index bb5a68b22e9..cfb73e25a0b 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/TerminologyUploaderProviderR4Test.java
@@ -1,8 +1,12 @@
package ca.uhn.fhir.jpa.provider.r4;
+import ca.uhn.fhir.jpa.entity.TermCodeSystem;
+import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
+import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
+import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.TestUtil;
@@ -21,6 +25,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -253,6 +258,67 @@ public class TerminologyUploaderProviderR4Test extends BaseResourceProviderR4Tes
);
}
+ @Test
+ public void testApplyDeltaAdd_UsingCodeSystemWithComma() throws IOException {
+
+ // Create initial codesystem
+ {
+ CodeSystem codeSystem = new CodeSystem();
+ codeSystem.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT);
+ codeSystem.setUrl("https://good.health");
+
+ LoggingInterceptor interceptor = new LoggingInterceptor(true);
+ ourClient.registerInterceptor(interceptor);
+ ourClient
+ .create()
+ .resource(codeSystem)
+ .execute();
+ ourClient.unregisterInterceptor(interceptor);
+ }
+
+ // Add a child with a really long description
+ Parameters outcome;
+ {
+ Parameters inputBundle = loadResourceFromClasspath(Parameters.class, "/term-delta-json.json");
+
+ LoggingInterceptor interceptor = new LoggingInterceptor(true);
+ ourClient.registerInterceptor(interceptor);
+ outcome = ourClient
+ .operation()
+ .onType(CodeSystem.class)
+ .named(JpaConstants.OPERATION_APPLY_CODESYSTEM_DELTA_ADD)
+ .withParameters(inputBundle)
+ .execute();
+ ourClient.unregisterInterceptor(interceptor);
+ }
+
+ String encoded = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(
+ "\"name\": \"conceptCount\"",
+ "\"valueInteger\": 2",
+ "\"name\": \"target\"",
+ "\"reference\": \"CodeSystem/"
+ ));
+
+ assertHierarchyContains(
+ "1111222233 seq=0",
+ " 1111222234 seq=0"
+ );
+
+ runInTransaction(()->{
+ TermCodeSystem codeSystem = myTermCodeSystemDao.findByCodeSystemUri("https://good.health");
+ TermCodeSystemVersion version = codeSystem.getCurrentVersion();
+ TermConcept code = myTermConceptDao.findByCodeSystemAndCode(version, "1111222233").get();
+ assertEquals("Some label for the parent - with a dash too", code.getDisplay());
+
+ code = myTermConceptDao.findByCodeSystemAndCode(version, "1111222234").get();
+ assertEquals("Some very very very very very looooooong child label with a coma, another one, one more, more and final one", code.getDisplay());
+ });
+ }
+
+
+
@Test
public void testApplyDeltaAdd_UsingCodeSystemWithVeryLongDescription() {
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java
index 17cf99e22ff..a622a7a4933 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImplTest.java
@@ -182,41 +182,17 @@ public class SearchCoordinatorSvcImplTest {
when(mySearchBuilder.createQuery(any(), any(), any())).thenReturn(iter);
doAnswer(loadPids()).when(mySearchBuilder).loadResourcesByPid(any(Collection.class), any(Collection.class), any(List.class), anyBoolean(), any());
- when(mySearchResultCacheSvc.fetchResultPids(any(), anyInt(), anyInt())).thenAnswer(t -> {
- List returnedValues = iter.getReturnedValues();
- int offset = t.getArgument(1, Integer.class);
- int end = t.getArgument(2, Integer.class);
- end = Math.min(end, returnedValues.size());
- offset = Math.min(offset, returnedValues.size());
- ourLog.info("findWithSearchUuid {} - {} out of {} values", offset, end, returnedValues.size());
- return returnedValues.subList(offset, end);
- });
-
- when(mySearchResultCacheSvc.fetchAllResultPids(any())).thenReturn(allResults);
-
- when(mySearchCacheSvc.tryToMarkSearchAsInProgress(any())).thenAnswer(t->{
+ when(mySearchCacheSvc.save(any())).thenAnswer(t -> {
Search search = t.getArgument(0, Search.class);
- assertEquals(SearchStatusEnum.PASSCMPLET, search.getStatus());
- search.setStatus(SearchStatusEnum.LOADING);
- return Optional.of(search);
+ myCurrentSearch = search;
+ return search;
});
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNotNull(result.getUuid());
assertEquals(null, result.size());
- List resources;
-
- when(mySearchCacheSvc.save(any())).thenAnswer(t -> {
- Search search = t.getArgument(0, Search.class);
- myCurrentSearch = search;
- return search;
- });
- when(mySearchCacheSvc.fetchByUuid(any())).thenAnswer(t -> Optional.ofNullable(myCurrentSearch));
- IFhirResourceDao dao = myCallingDao;
- when(myDaoRegistry.getResourceDao(any(String.class))).thenReturn(dao);
-
- resources = result.getResources(0, 100000);
+ List resources = result.getResources(0, 100000);
assertEquals(790, resources.size());
assertEquals("10", resources.get(0).getIdElement().getValueAsString());
assertEquals("799", resources.get(789).getIdElement().getValueAsString());
@@ -604,6 +580,11 @@ public class SearchCoordinatorSvcImplTest {
return myWrap.getSkippedCount();
}
+ @Override
+ public int getNonSkippedCount() {
+ return myCount;
+ }
+
@Override
public void close() {
// nothing
@@ -613,6 +594,7 @@ public class SearchCoordinatorSvcImplTest {
public static class ResultIterator extends BaseIterator implements IResultIterator {
private final Iterator myWrap;
+ private int myCount;
ResultIterator(Iterator theWrap) {
myWrap = theWrap;
@@ -625,6 +607,7 @@ public class SearchCoordinatorSvcImplTest {
@Override
public ResourcePersistentId next() {
+ myCount++;
return myWrap.next();
}
@@ -633,6 +616,11 @@ public class SearchCoordinatorSvcImplTest {
return 0;
}
+ @Override
+ public int getNonSkippedCount() {
+ return myCount;
+ }
+
@Override
public void close() {
// nothing
@@ -699,6 +687,11 @@ public class SearchCoordinatorSvcImplTest {
}
}
+ @Override
+ public int getNonSkippedCount() {
+ return 0;
+ }
+
@Override
public void close() {
// nothing
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java
index c12fad6d306..e79e49fe76e 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java
@@ -58,6 +58,7 @@ public class MatchUrlServiceTest extends BaseJpaTest {
Location.SP_NEAR + "=1000.0:2000.0" +
"&" +
Location.SP_NEAR_DISTANCE + "=" + kmDistance + "|http://unitsofmeasure.org|km", ourCtx.getResourceDefinition("Location"));
+ map.setLocationDistance();
QuantityParam nearDistanceParam = map.getNearDistanceParam();
assertEquals(1, map.size());
@@ -74,6 +75,8 @@ public class MatchUrlServiceTest extends BaseJpaTest {
"&" +
Location.SP_NEAR_DISTANCE + "=2|http://unitsofmeasure.org|km",
ourCtx.getResourceDefinition("Location"));
+ map.setLocationDistance();
+
fail();
} catch (IllegalArgumentException e) {
assertEquals("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present", e.getMessage());
@@ -89,7 +92,8 @@ public class MatchUrlServiceTest extends BaseJpaTest {
"," +
"2|http://unitsofmeasure.org|km",
ourCtx.getResourceDefinition("Location"));
- map.setLoadSynchronous(true);
+ map.setLocationDistance();
+
fail();
} catch (IllegalArgumentException e) {
assertEquals("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present", e.getMessage());
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/SubscriptionTriggeringDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/SubscriptionTriggeringDstu3Test.java
index 20b7cc1f52b..8ce8bb95fc7 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/SubscriptionTriggeringDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/SubscriptionTriggeringDstu3Test.java
@@ -17,7 +17,6 @@ import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.test.utilities.JettyUtil;
-import ca.uhn.fhir.test.utilities.UnregisterScheduledProcessor;
import com.google.common.collect.Lists;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
@@ -39,14 +38,14 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.TestPropertySource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
+import static org.awaitility.Awaitility.await;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -56,10 +55,6 @@ import static org.junit.Assert.fail;
* Test the rest-hook subscriptions
*/
@SuppressWarnings("Duplicates")
-@TestPropertySource(properties = {
- UnregisterScheduledProcessor.SCHEDULING_DISABLED + "=false"
-})
-@DirtiesContext
public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SubscriptionTriggeringDstu3Test.class);
@@ -194,6 +189,9 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
waitForQueueToDrain();
+
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+
waitForSize(0, ourCreatedObservations);
waitForSize(2, ourUpdatedObservations);
@@ -248,6 +246,13 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
responseValue = response.getParameter().get(0).getValue().primitiveValue();
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ waitForSize(33, ourUpdatedObservations);
+
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
waitForSize(51, ourUpdatedObservations);
waitForSize(0, ourCreatedObservations);
waitForSize(0, ourCreatedPatients);
@@ -257,8 +262,6 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
@Test
public void testTriggerUsingOrSeparatedList_MultipleStrings() throws Exception {
- myDaoConfig.setSearchPreFetchThresholds(Lists.newArrayList(13, 22, 100));
-
String payload = "application/fhir+json";
IdType sub2id = createSubscription("Patient?", payload, ourListenerServerBase).getIdElement();
@@ -284,8 +287,18 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
- waitForSize(0, ourCreatedPatients);
- waitForSize(3, ourUpdatedPatients);
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ assertEquals(0, mySubscriptionTriggeringSvc.getActiveJobCount());
+
+ assertEquals(0, ourCreatedPatients.size());
+ await().until(() -> ourUpdatedPatients.size() == 3);
}
@@ -316,6 +329,8 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+
waitForSize(0, ourCreatedPatients);
waitForSize(3, ourUpdatedPatients);
@@ -367,6 +382,9 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
responseValue = response.getParameter().get(0).getValue().primitiveValue();
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+
waitForSize(10, ourUpdatedObservations);
waitForSize(0, ourCreatedObservations);
waitForSize(0, ourCreatedPatients);
@@ -421,6 +439,8 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
String responseValue = response.getParameter().get(0).getValue().primitiveValue();
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+
waitForSize(20, ourUpdatedObservations);
waitForSize(0, ourCreatedObservations);
waitForSize(0, ourCreatedPatients);
@@ -458,6 +478,8 @@ public class SubscriptionTriggeringDstu3Test extends BaseResourceProviderDstu3Te
assertThat(responseValue, containsString("Subscription triggering job submitted as JOB ID"));
waitForQueueToDrain();
+ mySubscriptionTriggeringSvc.runDeliveryPass();
+
waitForSize(0, ourCreatedObservations);
waitForSize(1, ourUpdatedObservations);
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/validator/ValidatorAcrossVersionsTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/validator/ValidatorAcrossVersionsTest.java
index c335a1ac6ea..87fcc302bba 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/validator/ValidatorAcrossVersionsTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/validator/ValidatorAcrossVersionsTest.java
@@ -54,8 +54,8 @@ public class ValidatorAcrossVersionsTest {
ourLog.info(ctxDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()));
assertEquals(2, result.getMessages().size());
- assertEquals("No questionnaire is identified, so no validation can be performed against the base questionnaire", result.getMessages().get(0).getMessage());
- assertEquals("Profile http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse, Element 'QuestionnaireResponse.status': minimum required = 1, but only found 0", result.getMessages().get(1).getMessage());
+ assertEquals("Profile http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse, Element 'QuestionnaireResponse.status': minimum required = 1, but only found 0", result.getMessages().get(0).getMessage());
+ assertEquals("No questionnaire is identified, so no validation can be performed against the base questionnaire", result.getMessages().get(1).getMessage());
}
}
diff --git a/hapi-fhir-jpaserver-base/src/test/resources/term-delta-json.json b/hapi-fhir-jpaserver-base/src/test/resources/term-delta-json.json
new file mode 100644
index 00000000000..78e18fccaaa
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/resources/term-delta-json.json
@@ -0,0 +1,30 @@
+{
+ "resourceType": "Parameters",
+ "parameter": [
+ {
+ "name": "system",
+ "valueUri": "https://good.health"
+ },
+ {
+ "name": "codeSystem",
+ "resource": {
+ "resourceType": "CodeSystem",
+ "status": "active",
+ "content": "not-present",
+ "url": "https://good.health",
+ "concept": [
+ {
+ "code": "1111222233",
+ "display": "Some label for the parent - with a dash too",
+ "concept": [
+ {
+ "code": "1111222234",
+ "display": "Some very very very very very looooooong child label with a coma, another one, one more, more and final one"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/hapi-fhir-jpaserver-migrate/pom.xml b/hapi-fhir-jpaserver-migrate/pom.xml
index 345bf13d5ee..2820928227b 100644
--- a/hapi-fhir-jpaserver-migrate/pom.xml
+++ b/hapi-fhir-jpaserver-migrate/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java
index a743ad281e7..8b60927345e 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java
@@ -63,6 +63,8 @@ public class FlywayMigrator extends BaseMigrator {
if (isDryRun()) {
StringBuilder statementBuilder = buildExecutedStatementsString();
ourLog.info("SQL that would be executed:\n\n***********************************\n{}***********************************", statementBuilder);
+ } else {
+ ourLog.info("Schema migrated successfully.");
}
} catch (Exception e) {
throw e;
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java
index e27668fd0fe..86d1d92bcd6 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/TaskOnlyMigrator.java
@@ -51,7 +51,11 @@ public class TaskOnlyMigrator extends BaseMigrator {
next.setConnectionProperties(connectionProperties);
try {
- ourLog.info("Executing task of type: {}", next.getClass().getSimpleName());
+ if (isDryRun()) {
+ ourLog.info("Dry run {} {}", next.getFlywayVersion(), next.getDescription());
+ } else {
+ ourLog.info("Executing {} {}", next.getFlywayVersion(), next.getDescription());
+ }
next.execute();
addExecutedStatements(next.getExecutedStatements());
} catch (SQLException e) {
@@ -61,6 +65,8 @@ public class TaskOnlyMigrator extends BaseMigrator {
if (isDryRun()) {
StringBuilder statementBuilder = buildExecutedStatementsString();
ourLog.info("SQL that would be executed:\n\n***********************************\n{}***********************************", statementBuilder);
+ } else {
+ ourLog.info("Schema migrated successfully.");
}
}
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
index 51667c1374f..7638ed1b601 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java
@@ -62,10 +62,12 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks {
protected void init420() { // 20191015 - present
Builder version = forVersion(VersionEnum.V4_2_0);
- // Eliminate circular dependency.
- version.onTable("HFJ_RESOURCE").dropColumn("20200130.1", "FORCED_ID_PID");
- version.onTable("HFJ_RES_VER").dropColumn("20200130.2", "FORCED_ID_PID");
- version.onTable("HFJ_RES_VER").addForeignKey("20200130.3", "FK_RESOURCE_HISTORY_RESOURCE").toColumn("RES_ID").references("HFJ_RESOURCE", "RES_ID");
+ // TermValueSetConceptDesignation
+ version.onTable("TRM_VALUESET_C_DESIGNATION").dropIndex("20200202.1", "IDX_VALUESET_C_DSGNTN_VAL").failureAllowed();
+ Builder.BuilderWithTableName searchTable = version.onTable("HFJ_SEARCH");
+ searchTable.dropIndex("20200203.1", "IDX_SEARCH_LASTRETURNED");
+ searchTable.dropColumn("20200203.2", "SEARCH_LAST_RETURNED");
+ searchTable.addIndex("20200203.3", "IDX_SEARCH_CREATED").unique(false).withColumns("CREATED");
}
protected void init410() { // 20190815 - 20191014
diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java
index a7de3803e1d..ea6431e8fbb 100644
--- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java
+++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/api/Builder.java
@@ -158,20 +158,22 @@ public class Builder {
return myTableName;
}
- public void dropIndex(String theVersion, String theIndexName) {
- dropIndexOptional(false, theVersion, theIndexName);
+ public BuilderCompleteTask dropIndex(String theVersion, String theIndexName) {
+ BaseTask task = dropIndexOptional(false, theVersion, theIndexName);
+ return new BuilderCompleteTask(task);
}
public void dropIndexStub(String theVersion, String theIndexName) {
dropIndexOptional(true, theVersion, theIndexName);
}
- private void dropIndexOptional(boolean theDoNothing, String theVersion, String theIndexName) {
+ private DropIndexTask dropIndexOptional(boolean theDoNothing, String theVersion, String theIndexName) {
DropIndexTask task = new DropIndexTask(myRelease, theVersion);
task.setIndexName(theIndexName);
task.setTableName(myTableName);
task.setDoNothing(theDoNothing);
addTask(task);
+ return task;
}
public void renameIndex(String theVersion, String theOldIndexName, String theNewIndexName) {
@@ -286,11 +288,12 @@ public class Builder {
withColumnsOptional(true, theColumnNames);
}
- public void withColumns(String... theColumnNames) {
- withColumnsOptional(false, theColumnNames);
+ public BuilderCompleteTask withColumns(String... theColumnNames) {
+ BaseTask task = withColumnsOptional(false, theColumnNames);
+ return new BuilderCompleteTask(task);
}
- private void withColumnsOptional(boolean theDoNothing, String... theColumnNames) {
+ private AddIndexTask withColumnsOptional(boolean theDoNothing, String... theColumnNames) {
AddIndexTask task = new AddIndexTask(myRelease, myVersion);
task.setTableName(myTableName);
task.setIndexName(myIndexName);
@@ -298,6 +301,7 @@ public class Builder {
task.setColumns(theColumnNames);
task.setDoNothing(theDoNothing);
addTask(task);
+ return task;
}
}
}
@@ -463,6 +467,12 @@ public class Builder {
myTask.setFailureAllowed(true);
return this;
}
+
+ public BuilderCompleteTask doNothing() {
+ myTask.setDoNothing(true);
+ return this;
+ }
+
}
}
diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml
index 123f22b7a3a..83b438d3efc 100644
--- a/hapi-fhir-jpaserver-model/pom.xml
+++ b/hapi-fhir-jpaserver-model/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
index a7570dcf71e..10d7189410a 100644
--- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
+++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceTable.java
@@ -54,12 +54,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
private static final int MAX_PROFILE_LENGTH = 200;
private static final long serialVersionUID = 1L;
-// @Transient
-// private transient byte[] myResource;
-//
-// @Transient
-// private transient ResourceEncodingEnum myEncoding;
-
/**
* Holds the narrative text only - Used for Fulltext searching but not directly stored in the DB
*/
diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml
index 06f462936c4..709f74dfc10 100755
--- a/hapi-fhir-jpaserver-searchparam/pom.xml
+++ b/hapi-fhir-jpaserver-searchparam/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java
index 6cd49534031..fb77ea8af24 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java
@@ -26,13 +26,11 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterType;
-import ca.uhn.fhir.model.dstu2.resource.Location;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ParameterUtil;
-import ca.uhn.fhir.rest.param.QuantityAndListParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.ReflectionUtil;
import ca.uhn.fhir.util.UrlUtil;
@@ -115,9 +113,6 @@ public class MatchUrlService {
} else if (Constants.PARAM_SOURCE.equals(nextParamName)) {
IQueryParameterAnd> param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList);
paramMap.add(nextParamName, param);
- } else if (Location.SP_NEAR_DISTANCE.equals(nextParamName)) {
- QuantityAndListParam nearDistanceAndListParam = (QuantityAndListParam) ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.QUANTITY, nextParamName, paramList);
- paramMap.setNearDistanceParam(nearDistanceAndListParam);
} else if (nextParamName.startsWith("_")) {
// ignore these since they aren't search params (e.g. _sort)
} else {
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/SearchParameterMap.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/SearchParameterMap.java
index a159ce3b6fa..958e58c2f1c 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/SearchParameterMap.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/SearchParameterMap.java
@@ -5,15 +5,17 @@ import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.Include;
-import ca.uhn.fhir.model.dstu2.resource.Location;
import ca.uhn.fhir.rest.api.*;
-import ca.uhn.fhir.rest.param.*;
+import ca.uhn.fhir.rest.param.DateParam;
+import ca.uhn.fhir.rest.param.DateRangeParam;
+import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.util.ObjectUtil;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
+import org.hl7.fhir.dstu3.model.Location;
import java.io.Serializable;
import java.util.*;
@@ -495,29 +497,38 @@ public class SearchParameterMap implements Serializable {
}
}
- public void setNearDistanceParam(QuantityAndListParam theQuantityAndListParam) {
- List orTokens = theQuantityAndListParam.getValuesAsQueryTokens();
- if (orTokens.isEmpty()) {
- return;
- }
- if (orTokens.size() > 1) {
- throw new IllegalArgumentException("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present");
- }
- QuantityOrListParam quantityOrListParam = orTokens.get(0);
- List tokens = quantityOrListParam.getValuesAsQueryTokens();
- if (tokens.isEmpty()) {
- return;
- }
- if (tokens.size() > 1) {
- throw new IllegalArgumentException("Only one " + Location.SP_NEAR_DISTANCE + " parameter may be present");
- }
- myNearDistanceParam = tokens.get(0);
+ public void setNearDistanceParam(QuantityParam theQuantityParam) {
+ myNearDistanceParam = theQuantityParam;
}
public QuantityParam getNearDistanceParam() {
return myNearDistanceParam;
}
+ public void setLocationDistance() {
+ if (containsKey(Location.SP_NEAR_DISTANCE)) {
+ List> paramAndList = get(Location.SP_NEAR_DISTANCE);
+
+ if (paramAndList.isEmpty()) {
+ return;
+ }
+ if (paramAndList.size() > 1) {
+ throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
+ }
+ List paramOrList = paramAndList.get(0);
+ if (paramOrList.isEmpty()) {
+ return;
+ }
+ if (paramOrList.size() > 1) {
+ throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
+ }
+ setNearDistanceParam((QuantityParam) paramOrList.get(0));
+
+ // Need to remove near-distance or it we'll get a hashcode predicate for it
+ remove(Location.SP_NEAR_DISTANCE);
+ }
+ }
+
public enum EverythingModeEnum {
/*
* Don't reorder! We rely on the ordinals
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java
index 9626f14282e..d27f51fc814 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java
@@ -26,12 +26,16 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.context.IWorkerContext;
-import org.hl7.fhir.r5.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r5.hapi.ctx.DefaultProfileValidationSupport;
+import org.hl7.fhir.r5.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r5.hapi.ctx.IValidationSupport;
-import org.hl7.fhir.r5.model.*;
+import org.hl7.fhir.r5.model.Base;
+import org.hl7.fhir.r5.model.IdType;
+import org.hl7.fhir.r5.model.Resource;
+import org.hl7.fhir.r5.model.ResourceType;
+import org.hl7.fhir.r5.model.TypeDetails;
+import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
-import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
import java.util.Collections;
@@ -115,7 +119,7 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
}
@Override
- public Base resolveReference(Object theAppContext, String theUrl) throws FHIRException {
+ public Base resolveReference(Object appContext, String theUrl, Base refContext) throws FHIRException {
/*
* When we're doing resolution within the SearchParamExtractor, if we want
diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java
index c93c5e14ba8..d83eb5048c9 100644
--- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java
+++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java
@@ -40,6 +40,7 @@ import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.MetaUtil;
import ca.uhn.fhir.util.UrlUtil;
+import org.hl7.fhir.dstu3.model.Location;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
@@ -88,7 +89,7 @@ public class InMemoryResourceMatcher {
if (searchParameterMap.getLastUpdated() != null) {
return InMemoryMatchResult.unsupportedFromParameterAndReason(Constants.PARAM_LASTUPDATED, InMemoryMatchResult.STANDARD_PARAMETER);
}
- if (searchParameterMap.getNearDistanceParam() != null) {
+ if (searchParameterMap.containsKey(Location.SP_NEAR)) {
return InMemoryMatchResult.unsupportedFromReason(InMemoryMatchResult.LOCATION_NEAR);
}
diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml
index 19a6c3caf27..a7e80f6ec98 100644
--- a/hapi-fhir-jpaserver-subscription/pom.xml
+++ b/hapi-fhir-jpaserver-subscription/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
index 32f3752d80e..e6234a4fec8 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
+++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../pom.xml
@@ -157,7 +157,7 @@
ca.uhn.hapi.fhir
hapi-fhir-converter
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml
index 56d24a8322d..7e17a896660 100644
--- a/hapi-fhir-server/pom.xml
+++ b/hapi-fhir-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IRestfulResponse.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IRestfulResponse.java
index dd5896228a1..857666e2375 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IRestfulResponse.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IRestfulResponse.java
@@ -19,17 +19,21 @@ package ca.uhn.fhir.rest.api.server;
* limitations under the License.
* #L%
*/
-import java.io.*;
+
+import ca.uhn.fhir.rest.api.MethodOutcome;
+import ca.uhn.fhir.rest.api.SummaryEnum;
+import org.hl7.fhir.instance.model.api.IBaseBinary;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.instance.model.api.IPrimitiveType;
+
+import java.io.IOException;
+import java.io.Writer;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.hl7.fhir.instance.model.api.*;
-
-import ca.uhn.fhir.rest.api.MethodOutcome;
-import ca.uhn.fhir.rest.api.SummaryEnum;
-
public interface IRestfulResponse {
Object streamResponseAsResource(IBaseResource theActualResourceToReturn, boolean thePrettyPrint, Set theSummaryMode, int theStatusCode, String theStatusMessage, boolean theRespondGzip, boolean theAddContentLocation) throws IOException;
@@ -40,7 +44,7 @@ public interface IRestfulResponse {
*/
Object returnResponse(ParseAction> outcome, int operationStatus, boolean allowPrefer, MethodOutcome response, String resourceName) throws IOException;
- Writer getResponseWriter(int theStatusCode, String theStatusMessage, String theContentType, String theCharset, boolean theRespondGzip) throws UnsupportedEncodingException, IOException;
+ Writer getResponseWriter(int theStatusCode, String theStatusMessage, String theContentType, String theCharset, boolean theRespondGzip) throws IOException;
Object sendWriterResponse(int status, String contentType, String charset, Writer writer) throws IOException;
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
index 08cd779442c..3c32507105a 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
@@ -360,11 +360,13 @@ public class RestfulServer extends HttpServlet implements IRestfulServer supertype = clazz.getSuperclass();
while (!Object.class.equals(supertype)) {
count += findResourceMethods(theProvider, supertype);
+ count += findResourceMethodsOnInterfaces(theProvider, supertype.getInterfaces());
supertype = supertype.getSuperclass();
}
try {
count += findResourceMethods(theProvider, clazz);
+ count += findResourceMethodsOnInterfaces(theProvider, clazz.getInterfaces());
} catch (ConfigurationException e) {
throw new ConfigurationException("Failure scanning class " + clazz.getSimpleName() + ": " + e.getMessage(), e);
}
@@ -373,6 +375,15 @@ public class RestfulServer extends HttpServlet implements IRestfulServer[] interfaces) {
+ int count = 0;
+ for (Class> anInterface : interfaces) {
+ count += findResourceMethods(theProvider, anInterface);
+ count += findResourceMethodsOnInterfaces(theProvider, anInterface.getInterfaces());
+ }
+ return count;
+ }
+
private int findResourceMethods(Object theProvider, Class> clazz) throws ConfigurationException {
int count = 0;
@@ -1604,14 +1615,23 @@ public class RestfulServer extends HttpServlet implements IRestfulServer resourceNames = new ArrayList<>();
while (!Object.class.equals(supertype)) {
removeResourceMethods(theProvider, supertype, resourceNames);
+ removeResourceMethodsOnInterfaces(theProvider, supertype.getInterfaces(), resourceNames);
supertype = supertype.getSuperclass();
}
removeResourceMethods(theProvider, clazz, resourceNames);
+ removeResourceMethodsOnInterfaces(theProvider, clazz.getInterfaces(), resourceNames);
for (String resourceName : resourceNames) {
myResourceNameToBinding.remove(resourceName);
}
}
+ private void removeResourceMethodsOnInterfaces(Object theProvider, Class>[] interfaces, Collection resourceNames) {
+ for (Class> anInterface : interfaces) {
+ removeResourceMethods(theProvider, anInterface, resourceNames);
+ removeResourceMethodsOnInterfaces(theProvider, anInterface.getInterfaces(), resourceNames);
+ }
+ }
+
/*
* Collect the set of RESTful methods for a single class when it is being unregistered
*/
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
index d21620f5c79..0ef51233a04 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
@@ -28,11 +28,16 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser;
-import ca.uhn.fhir.rest.api.*;
+import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.api.EncodingEnum;
+import ca.uhn.fhir.rest.api.PreferHeader;
+import ca.uhn.fhir.rest.api.PreferReturnEnum;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
+import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
+import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.api.server.IRestfulResponse;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
-import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.method.ElementsParameter;
@@ -40,7 +45,13 @@ import ca.uhn.fhir.rest.server.method.SummaryEnumParameter;
import ca.uhn.fhir.util.BinaryUtil;
import ca.uhn.fhir.util.DateUtils;
import ca.uhn.fhir.util.UrlUtil;
-import org.hl7.fhir.instance.model.api.*;
+import org.hl7.fhir.instance.model.api.IAnyResource;
+import org.hl7.fhir.instance.model.api.IBaseBinary;
+import org.hl7.fhir.instance.model.api.IBaseReference;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IDomainResource;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
@@ -51,7 +62,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import static org.apache.commons.lang3.StringUtils.*;
+import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import static org.apache.commons.lang3.StringUtils.replace;
+import static org.apache.commons.lang3.StringUtils.trim;
public class RestfulServerUtils {
static final Pattern ACCEPT_HEADER_PATTERN = Pattern.compile("\\s*([a-zA-Z0-9+.*/-]+)\\s*(;\\s*([a-zA-Z]+)\\s*=\\s*([a-zA-Z0-9.]+)\\s*)?(,?)");
@@ -754,12 +768,12 @@ public class RestfulServerUtils {
}
public static Object streamResponseAsResource(IRestfulServerDefaults theServer, IBaseResource theResource, Set theSummaryMode, int stausCode, boolean theAddContentLocationHeader,
- boolean respondGzip, RequestDetails theRequestDetails) throws IOException {
+ boolean respondGzip, RequestDetails theRequestDetails) throws IOException {
return streamResponseAsResource(theServer, theResource, theSummaryMode, stausCode, null, theAddContentLocationHeader, respondGzip, theRequestDetails, null, null);
}
public static Object streamResponseAsResource(IRestfulServerDefaults theServer, IBaseResource theResource, Set theSummaryMode, int theStatusCode, String theStatusMessage,
- boolean theAddContentLocationHeader, boolean respondGzip, RequestDetails theRequestDetails, IIdType theOperationResourceId, IPrimitiveType theOperationResourceLastUpdated)
+ boolean theAddContentLocationHeader, boolean respondGzip, RequestDetails theRequestDetails, IIdType theOperationResourceId, IPrimitiveType theOperationResourceLastUpdated)
throws IOException {
IRestfulResponse response = theRequestDetails.getResponse();
@@ -895,23 +909,10 @@ public class RestfulServerUtils {
IParser parser = getNewParser(theServer.getFhirContext(), forVersion, theRequestDetails);
parser.encodeResourceToWriter(theResource, writer);
}
- //FIXME resource leak
+
return response.sendWriterResponse(theStatusCode, contentType, charset, writer);
}
- // static Integer tryToExtractNamedParameter(HttpServletRequest theRequest, String name) {
- // String countString = theRequest.getParameter(name);
- // Integer count = null;
- // if (isNotBlank(countString)) {
- // try {
- // count = Integer.parseInt(countString);
- // } catch (NumberFormatException e) {
- // ourLog.debug("Failed to parse _count value '{}': {}", countString, e);
- // }
- // }
- // return count;
- // }
-
public static String createEtag(String theVersionId) {
return "W/\"" + theVersionId + '"';
}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/IncludeParameter.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/IncludeParameter.java
index 83e253898f3..6e3cb7fa1fe 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/IncludeParameter.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/IncludeParameter.java
@@ -154,7 +154,7 @@ class IncludeParameter extends BaseQueryParameter {
}
return new Include(value, recurse);
}
- //FIXME null access
+
retValCollection.add(new Include(value, recurse));
}
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/MethodUtil.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/MethodUtil.java
index 9c6fc1e76de..87b648840bf 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/MethodUtil.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/MethodUtil.java
@@ -192,7 +192,7 @@ public class MethodUtil {
b.append(theMethod.getName());
b.append("' is annotated with @");
b.append(ResourceParam.class.getSimpleName());
- b.append(" but has a type that is not an implemtation of ");
+ b.append(" but has a type that is not an implementation of ");
b.append(IBaseResource.class.getCanonicalName());
b.append(" or String or byte[]");
throw new ConfigurationException(b.toString());
diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRestfulResponse.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRestfulResponse.java
index cb518bb8d57..ee71f6e210b 100644
--- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRestfulResponse.java
+++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRestfulResponse.java
@@ -20,23 +20,22 @@ package ca.uhn.fhir.rest.server.servlet;
* #L%
*/
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.zip.GZIPOutputStream;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-
-import org.hl7.fhir.instance.model.api.IBaseBinary;
-
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.server.ParseAction;
import ca.uhn.fhir.rest.server.RestfulResponse;
+import org.hl7.fhir.instance.model.api.IBaseBinary;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.zip.GZIPOutputStream;
public class ServletRestfulResponse extends RestfulResponse {
@@ -48,23 +47,23 @@ public class ServletRestfulResponse extends RestfulResponse createServerConformanceProvider(RestfulServer theRestfulServer) {
+ return new IServerConformanceProvider() {
+
+ @Override
+ @Metadata
+ public IBaseConformance getServerConformance(HttpServletRequest theRequest, RequestDetails theRequestDetails) {
+ return mock(IBaseConformance.class);
+ }
+
+ @Override
+ public void setRestfulServer(RestfulServer theRestfulServer) {
+ }
+ };
+ }
+
+ @Override
+ public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
+ return new MyResourceProvider();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private static class MyResourceProvider implements IResourceProvider {
+ @Create
+ public MethodOutcome create(@ResourceParam IBaseResource theResource) {
+ return mock(MethodOutcome.class);
+ }
+
+ @Override
+ public Class extends IBaseResource> getResourceType() {
+ return IBaseResource.class;
+ }
+ }
+
+}
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
index e6f6a6546cd..834ad669a7d 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
index 6460fdaa090..31805755c96 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
hapi-fhir-spring-boot-sample-client-apache
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
index ec9c4c7b647..1d4b77cb9f0 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
hapi-fhir-spring-boot-sample-client-okhttp
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
index 45d11f2b0a0..09556aa2e9d 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
hapi-fhir-spring-boot-sample-server-jersey
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jpa/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jpa/pom.xml
index 2f99de20e6b..a087c508c21 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jpa/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jpa/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
hapi-fhir-spring-boot-sample-server-jpa
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
index bdeeb2a13a3..5b9868d5d9c 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
hapi-fhir-spring-boot-samples
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
index 95bbb629d7f..4869dd92e80 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml
index 83dcdd267d7..1b15296e40b 100644
--- a/hapi-fhir-spring-boot/pom.xml
+++ b/hapi-fhir-spring-boot/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml
index c12b498af04..2e2a8777742 100644
--- a/hapi-fhir-structures-dstu2.1/pom.xml
+++ b/hapi-fhir-structures-dstu2.1/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2.1/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2_1Test.java b/hapi-fhir-structures-dstu2.1/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2_1Test.java
index 315736213f7..b611feb0055 100644
--- a/hapi-fhir-structures-dstu2.1/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2_1Test.java
+++ b/hapi-fhir-structures-dstu2.1/src/test/java/ca/uhn/fhir/parser/JsonParserDstu2_1Test.java
@@ -1170,44 +1170,6 @@ public class JsonParserDstu2_1Test {
assertEquals(" ", out);
}
- // FIXME: this should pass
- @Test
- @Ignore
- public void testNamespacePreservationEncode() throws Exception {
- //@formatter:off
- String input = "" +
- "" +
- "" +
- "" +
- "@fhirabend" +
- " " +
- " " +
- " ";
- //@formatter:on
- Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, input);
-
- String expected = "@fhirabend ";
- assertEquals(expected, parsed.getText().getDiv().getValueAsString());
-
- String encoded = ourCtx.newJsonParser().encodeResourceToString(parsed);
- ourLog.info(encoded);
- assertThat(encoded, containsString("\"div\":\"" + expected.replace("\"", "\\\"") + "\""));
- }
-
- // TODO: this should pass
- @Test
- @Ignore
- public void testNamespacePreservationParse() throws Exception {
- String input = "{\"resourceType\":\"Patient\",\"text\":{\"div\":\"@fhirabend \"}}";
- Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, input);
- XhtmlNode div = parsed.getText().getDiv();
-
- assertEquals("@fhirabend ", div.getValueAsString());
-
- String encoded = ourCtx.newXmlParser().encodeResourceToString(parsed);
- assertEquals("@fhirabend ", encoded);
- }
-
@Test
public void testOmitResourceId() {
Patient p = new Patient();
diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml
index cb64e29ef8d..48444b154a0 100644
--- a/hapi-fhir-structures-dstu2/pom.xml
+++ b/hapi-fhir-structures-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/IncludeDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/IncludeDstu2Test.java
index 66648cd8afe..d67c4468f42 100644
--- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/IncludeDstu2Test.java
+++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/IncludeDstu2Test.java
@@ -41,9 +41,6 @@ import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
-/**
- * Created by dsotnikov on 2/25/2014.
- */
public class IncludeDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(IncludeDstu2Test.class);
@@ -310,9 +307,6 @@ public class IncludeDstu2Test {
}
- /**
- * Created by dsotnikov on 2/25/2014.
- */
public static class DummyPatientResourceProvider implements IResourceProvider {
@Search(queryName = "containedInclude")
diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml
index e8955655dd3..f8d1d20457a 100644
--- a/hapi-fhir-structures-dstu3/pom.xml
+++ b/hapi-fhir-structures-dstu3/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/ctx/HapiWorkerContext.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/ctx/HapiWorkerContext.java
index cf67693767e..84e62466d92 100644
--- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/ctx/HapiWorkerContext.java
+++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/ctx/HapiWorkerContext.java
@@ -106,14 +106,22 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
@Override
public T fetchResource(Class theClass, String theUri) {
+ Validate.notBlank(theUri, "theUri must not be null or blank");
if (myValidationSupport == null) {
return null;
} else {
- @SuppressWarnings("unchecked")
- T retVal = (T) myFetchedResourceCache.get(theUri, t->{
- return myValidationSupport.fetchResource(myCtx, theClass, theUri);
- });
- return retVal;
+ try {
+ //noinspection unchecked
+ return (T) myFetchedResourceCache.get(theUri, t -> {
+ T resource = myValidationSupport.fetchResource(myCtx, theClass, theUri);
+ if (resource == null) {
+ throw new IllegalArgumentException();
+ }
+ return resource;
+ });
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
}
}
diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java
index 3211b621a89..3b58f877a14 100644
--- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java
+++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/parser/JsonParserDstu3Test.java
@@ -1593,44 +1593,6 @@ public class JsonParserDstu3Test {
assertEquals(" ", out);
}
- // FIXME: this should pass
- @Test
- @Ignore
- public void testNamespacePreservationEncode() {
- //@formatter:off
- String input = "" +
- "" +
- "" +
- "" +
- "@fhirabend" +
- " " +
- " " +
- " ";
- //@formatter:on
- Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, input);
-
- String expected = "@fhirabend ";
- assertEquals(expected, parsed.getText().getDiv().getValueAsString());
-
- String encoded = ourCtx.newJsonParser().encodeResourceToString(parsed);
- ourLog.info(encoded);
- assertThat(encoded, containsString("\"div\":\"" + expected.replace("\"", "\\\"") + "\""));
- }
-
- // TODO: this should pass
- @Test
- @Ignore
- public void testNamespacePreservationParse() {
- String input = "{\"resourceType\":\"Patient\",\"text\":{\"div\":\"@fhirabend \"}}";
- Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, input);
- XhtmlNode div = parsed.getText().getDiv();
-
- assertEquals("@fhirabend ", div.getValueAsString());
-
- String encoded = ourCtx.newXmlParser().encodeResourceToString(parsed);
- assertEquals("@fhirabend ", encoded);
- }
-
@Test
public void testOmitResourceId() {
Patient p = new Patient();
diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/client/GenericClientDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/client/GenericClientDstu3Test.java
index 625b0ba0a85..40bb7342a37 100644
--- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/client/GenericClientDstu3Test.java
+++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/rest/client/GenericClientDstu3Test.java
@@ -1538,21 +1538,21 @@ public class GenericClientDstu3Test {
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;
- client
- .search()
- .forResource(Patient.class)
- .sort().ascending("address")
- .returnBundle(Bundle.class)
- .execute();
- assertEquals("http://example.com/fhir/Patient?_sort=address", capt.getAllValues().get(idx++).getURI().toASCIIString());
-
- client
- .search()
- .forResource(Patient.class)
- .sort().descending("address")
- .returnBundle(Bundle.class)
- .execute();
- assertEquals("http://example.com/fhir/Patient?_sort=-address", capt.getAllValues().get(idx++).getURI().toASCIIString());
+// client
+// .search()
+// .forResource(Patient.class)
+// .sort().ascending("address")
+// .returnBundle(Bundle.class)
+// .execute();
+// assertEquals("http://example.com/fhir/Patient?_sort=address", capt.getAllValues().get(idx++).getURI().toASCIIString());
+//
+// client
+// .search()
+// .forResource(Patient.class)
+// .sort().descending("address")
+// .returnBundle(Bundle.class)
+// .execute();
+// assertEquals("http://example.com/fhir/Patient?_sort=-address", capt.getAllValues().get(idx++).getURI().toASCIIString());
client
.search()
diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml
index f92fd6871e2..ab9eb4e3214 100644
--- a/hapi-fhir-structures-hl7org-dstu2/pom.xml
+++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml
index e4e51da7cfa..cdea8e99b14 100644
--- a/hapi-fhir-structures-r4/pom.xml
+++ b/hapi-fhir-structures-r4/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/JsonParserR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/JsonParserR4Test.java
index 64904f62529..5527e7602b6 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/JsonParserR4Test.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/JsonParserR4Test.java
@@ -10,6 +10,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullWriter;
import org.apache.commons.lang.StringUtils;
import org.hl7.fhir.r4.model.*;
+import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
@@ -52,6 +53,38 @@ public class JsonParserR4Test extends BaseTest {
ourLog.info(narrative);
}
+ @Test
+ public void testNamespacePrefixTrimmedFromNarrative() {
+ String input = "" +
+ "" +
+ "" +
+ "" +
+ "@fhirabend" +
+ " " +
+ " " +
+ " ";
+ Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, input);
+
+ String expected = "@fhirabend";
+ assertEquals(expected, parsed.getText().getDiv().getValueAsString());
+
+ String encoded = ourCtx.newJsonParser().encodeResourceToString(parsed);
+ ourLog.info(encoded);
+ assertThat(encoded, containsString("\"div\":\"" + expected.replace("\"", "\\\"") + "\""));
+ }
+
+ @Test
+ public void testNamespacePrefixStrippedOnJsonParse() {
+ String input = "{\"resourceType\":\"Patient\",\"text\":{\"div\":\"@fhirabend \"}}";
+ Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, input);
+ XhtmlNode div = parsed.getText().getDiv();
+
+ assertEquals("@fhirabend", div.getValueAsString());
+
+ String encoded = ourCtx.newXmlParser().encodeResourceToString(parsed);
+ assertEquals("@fhirabend ", encoded);
+ }
+
@Test
public void testEncodeExtensionOnBinaryData() {
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientR4Test.java
index 6336aeca665..70c27a03c0d 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientR4Test.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ClientR4Test.java
@@ -4,11 +4,14 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.rest.annotation.At;
+import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Elements;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.RequiredParam;
+import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
@@ -18,6 +21,7 @@ import ca.uhn.fhir.rest.client.apache.ApacheHttpRequest;
import ca.uhn.fhir.rest.client.apache.ResourceEntity;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.rest.client.api.IGenericClient;
+import ca.uhn.fhir.rest.client.api.IRestfulClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
@@ -36,6 +40,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
@@ -228,6 +233,80 @@ public class ClientR4Test {
assertEquals("200", response.getId().getVersionIdPart());
}
+ interface MyClient extends IRestfulClient {
+
+ @Search()
+ List search(@IncludeParam String theInclude);
+
+
+ }
+
+
+ @Test
+ public void testStringIncludeTest() throws Exception {
+
+ Bundle bundle = new Bundle();
+ bundle.setType(Bundle.BundleType.SEARCHSET);
+
+ ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class);
+ when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
+ when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK"));
+ when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
+ when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(ourCtx.newXmlParser().encodeResourceToString(bundle)), StandardCharsets.UTF_8));
+ when(myHttpResponse.getAllHeaders()).thenReturn(new Header[0]);
+
+ MyClient client = ourCtx.newRestfulClient(MyClient.class, "http://foo");
+ List response = client.search("Patient:organization");
+
+ assertEquals(HttpGet.class, capt.getValue().getClass());
+ HttpGet post = (HttpGet) capt.getValue();
+ assertEquals("http://foo/Patient?_include=Patient%3Aorganization", post.getURI().toString());
+ }
+
+ @Test
+ public void testCreateWithInvalidType() throws Exception {
+
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:foo").setValue("123");
+ String serialized = ourCtx.newXmlParser().encodeResourceToString(patient);
+
+ ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class);
+ when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
+ when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK"));
+ when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
+ when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(serialized), StandardCharsets.UTF_8));
+ when(myHttpResponse.getAllHeaders()).thenReturn(toHeaderArray("Location", "http://example.com/fhir/Patient/100/_history/200"));
+
+ try {
+ ourCtx.newRestfulClient(ITestClientWithCreateWithInvalidParameterType.class, "http://foo");
+ fail();
+ } catch (ConfigurationException e) {
+ assertEquals("Method 'createPatient' is annotated with @ResourceParam but has a type that is not an implementation of org.hl7.fhir.instance.model.api.IBaseResource", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testCreateWithValidAndInvalidType() throws Exception {
+
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:foo").setValue("123");
+ String serialized = ourCtx.newXmlParser().encodeResourceToString(patient);
+
+ ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class);
+ when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
+ when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK"));
+ when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
+ when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(serialized), StandardCharsets.UTF_8));
+ when(myHttpResponse.getAllHeaders()).thenReturn(toHeaderArray("Location", "http://example.com/fhir/Patient/100/_history/200"));
+
+ try {
+ ourCtx.newRestfulClient(ITestClientWithCreateWithValidAndInvalidParameterType.class, "http://foo");
+ fail();
+ } catch (ConfigurationException e) {
+ assertEquals("Parameter #2/2 of method 'createPatient' on type 'ca.uhn.fhir.rest.client.ClientR4Test.ITestClientWithCreateWithValidAndInvalidParameterType' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter", e.getMessage());
+ }
+ }
+
@Test
public void testDelete() throws Exception {
@@ -946,6 +1025,45 @@ public class ClientR4Test {
}
+ @Test
+ public void testSearchWithAt() throws Exception {
+
+ String msg = getPatientFeedWithOneResult();
+
+ ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class);
+ when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
+ when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
+ when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
+ when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8));
+
+ ITestClient client = ourCtx.newRestfulClient(ITestClient.class, "http://foo");
+ client.getPatientWithAt(new InstantType("2010-10-01T01:02:03.0Z"));
+
+ assertEquals("http://foo/Patient?_at=2010-10-01T01%3A02%3A03.0Z", capt.getValue().getURI().toString());
+
+ }
+
+ @Test
+ public void testUnannotatedMethod() throws Exception {
+
+ String msg = getPatientFeedWithOneResult();
+
+ ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class);
+ when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
+ when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
+ when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
+ when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8));
+
+ ITestClientWithUnannotatedMethod client = ourCtx.newRestfulClient(ITestClientWithUnannotatedMethod.class, "http://foo");
+ try {
+ client.getPatientWithAt(new InstantType("2010-10-01T01:02:03.0Z"));
+ fail();
+ } catch (UnsupportedOperationException e) {
+ assertEquals("The method 'getPatientWithAt' in type ITestClientWithUnannotatedMethod has no handler. Did you forget to annotate it with a RESTful method annotation?", e.getMessage());
+ }
+
+ }
+
@Test
public void testSearchWithOptionalParam() throws Exception {
@@ -978,7 +1096,6 @@ public class ClientR4Test {
}
-
@Test
public void testSearchWithStringIncludes() throws Exception {
@@ -1183,7 +1300,6 @@ public class ClientR4Test {
}
-
@Test
public void testValidateOutcomeResponse() throws Exception {
@@ -1213,7 +1329,6 @@ public class ClientR4Test {
assertNull(response.getResource());
}
-
@Test
public void testVRead() throws Exception {
@@ -1324,6 +1439,18 @@ public class ClientR4Test {
}
}
+ public interface ITestClientWithCreateWithInvalidParameterType extends IRestfulClient {
+
+ @Create()
+ MethodOutcome createPatient(@ResourceParam int thePatient);
+ }
+
+ public interface ITestClientWithCreateWithValidAndInvalidParameterType extends IRestfulClient {
+
+ @Create()
+ MethodOutcome createPatient(@ResourceParam Patient thePatient, int theInt);
+ }
+
interface ITestClientWithAndOr extends IBasicClient {
@Search()
@@ -1382,6 +1509,10 @@ public class ClientR4Test {
}
+ interface ITestClientWithUnannotatedMethod extends IRestfulClient {
+ void getPatientWithAt(@At InstantType theInstantType);
+ }
+
@ResourceDef(name = "Patient")
public static class CustomPatient extends Patient {
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java
index 15f2d88c9c0..370f8e663fe 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java
@@ -17,40 +17,40 @@ import ca.uhn.fhir.rest.param.*;
public interface ITestClient extends IBasicClient {
@Create
- public MethodOutcome createPatient(@ResourceParam Patient thePatient);
+ MethodOutcome createPatient(@ResourceParam Patient thePatient);
@Search()
- public List getPatientByDateRange(@RequiredParam(name = "dateRange") DateRangeParam theIdentifiers);
+ List getPatientByDateRange(@RequiredParam(name = "dateRange") DateRangeParam theIdentifiers);
@Search(type=Observation.class)
- public Bundle getObservationByNameValueDate(@RequiredParam(name = Observation.SP_CODE_VALUE_DATE, compositeTypes= {StringParam.class,DateParam.class}) CompositeParam theIdentifiers);
+ Bundle getObservationByNameValueDate(@RequiredParam(name = Observation.SP_CODE_VALUE_DATE, compositeTypes = {StringParam.class, DateParam.class}) CompositeParam theIdentifiers);
@Search()
- public List getPatientByDob(@RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theBirthDate);
+ List getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
@Search(type=ExtendedPatient.class)
- public List getPatientByDobWithGenericResourceReturnType(@RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theBirthDate);
+ List getPatientByDobWithGenericResourceReturnType(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
@Search(type=ExtendedPatient.class)
- public List getPatientByDobWithGenericResourceReturnType2(@RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theBirthDate);
+ List getPatientByDobWithGenericResourceReturnType2(@RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
@Search()
- public List getPatientMultipleIdentifiers(@RequiredParam(name = "ids") TokenOrListParam theIdentifiers);
+ List getPatientMultipleIdentifiers(@RequiredParam(name = "ids") TokenOrListParam theIdentifiers);
@Search(queryName="someQueryNoParams")
- public Patient getPatientNoParams();
+ Patient getPatientNoParams();
@Search(queryName="someQueryOneParam")
- public Patient getPatientOneParam(@RequiredParam(name="param1") StringParam theParam);
+ Patient getPatientOneParam(@RequiredParam(name = "param1") StringParam theParam);
@Search(type=Patient.class)
- public Bundle findPatient(@RequiredParam(name = "param") StringAndListParam theStrings);
+ Bundle findPatient(@RequiredParam(name = "param") StringAndListParam theStrings);
@Search()
- public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringParam theString, @IncludeParam List theIncludes);
+ Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringParam theString, @IncludeParam List theIncludes);
@Update
- public MethodOutcome updatePatient(@IdParam IdType theId, @ResourceParam Patient thePatient);
+ MethodOutcome updatePatient(@IdParam IdType theId, @ResourceParam Patient thePatient);
@Delete(type=DiagnosticReport.class)
void deleteDiagnosticReport(@IdParam IdType theId);
@@ -89,7 +89,8 @@ public interface ITestClient extends IBasicClient {
Patient findPatientQuantity(@RequiredParam(name="quantityParam") QuantityParam theQuantityType);
@Search(compartmentName="compartmentName")
- public List getPatientByCompartmentAndDob(@IdParam IdType theIdType, @RequiredParam(name=Patient.SP_BIRTHDATE) DateParam theBirthDate);
-
+ List getPatientByCompartmentAndDob(@IdParam IdType theIdType, @RequiredParam(name = Patient.SP_BIRTHDATE) DateParam theBirthDate);
+ @Search
+ Patient getPatientWithAt(@At InstantType theInstantType);
}
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/IncludeTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/IncludeTest.java
index b99d57cf3c9..b477eb48cdc 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/IncludeTest.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/IncludeTest.java
@@ -262,9 +262,21 @@ public class IncludeTest {
}
}
- /**
- * Created by dsotnikov on 2/25/2014.
- */
+ @Test
+ public void testStringInclude() throws Exception {
+ HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=stringInclude&_include=foo");
+ try (CloseableHttpResponse status = ourClient.execute(httpGet)) {
+ String responseContent = IOUtils.toString(status.getEntity().getContent());
+
+ assertEquals(200, status.getStatusLine().getStatusCode());
+ Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, responseContent);
+ assertEquals(1, bundle.getEntry().size());
+
+ Patient p = BundleUtil.toListOfResourcesOfType(ourCtx, bundle, Patient.class).get(0);
+ assertEquals("foo", p.getIdentifierFirstRep().getValue());
+ }
+ }
+
public static class DummyDiagnosticReportResourceProvider implements IResourceProvider {
@Override
@@ -392,6 +404,17 @@ public class IncludeTest {
return retVal;
}
+
+ @Search(queryName = "stringInclude")
+ public List stringInclude(@IncludeParam String theInclude) {
+ Patient p = new Patient();
+ p.setId("p");
+ p.addIdentifier().setValue(theInclude);
+
+ return Arrays.asList(p);
+ }
+
+
@Override
public Class getResourceType() {
return Patient.class;
diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerInvalidDefinitionR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerInvalidDefinitionR4Test.java
index e2509542a19..3868584a9bc 100644
--- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerInvalidDefinitionR4Test.java
+++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/ServerInvalidDefinitionR4Test.java
@@ -54,7 +54,7 @@ public class ServerInvalidDefinitionR4Test {
} catch (ServletException e) {
assertThat(e.getCause().toString(), StringContains.containsString("ConfigurationException"));
assertThat(e.getCause().toString(), StringContains
- .containsString("Method 'update' is annotated with @ResourceParam but has a type that is not an implemtation of org.hl7.fhir.instance.model.api.IBaseResource or String or byte[]"));
+ .containsString("Method 'update' is annotated with @ResourceParam but has a type that is not an implementation of org.hl7.fhir.instance.model.api.IBaseResource or String or byte[]"));
}
}
diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml
index 92dabe9671b..ffd8da62120 100644
--- a/hapi-fhir-structures-r5/pom.xml
+++ b/hapi-fhir-structures-r5/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java b/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java
index c48a81f8f5e..c88ada2d294 100644
--- a/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java
+++ b/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java
@@ -343,6 +343,11 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
return fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + typeName);
}
+ @Override
+ public StructureDefinition fetchRawProfile(String url) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public List getTypeNames() {
throw new UnsupportedOperationException();
diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml
index d010e06b048..6caefd3117b 100644
--- a/hapi-fhir-test-utilities/pom.xml
+++ b/hapi-fhir-test-utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
@@ -19,17 +19,17 @@
ca.uhn.hapi.fhir
hapi-fhir-base
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-server
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-client
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml
index b8bca0e0dad..107e75d8313 100644
--- a/hapi-fhir-testpage-overlay/pom.xml
+++ b/hapi-fhir-testpage-overlay/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml
index ad05fd25d1a..c4bae7d6848 100644
--- a/hapi-fhir-validation-resources-dstu2.1/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml
index 45aa002c077..d8b4b070e80 100644
--- a/hapi-fhir-validation-resources-dstu2/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml
index 566d901943a..152a124fc68 100644
--- a/hapi-fhir-validation-resources-dstu3/pom.xml
+++ b/hapi-fhir-validation-resources-dstu3/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml
index e0284321e23..901d583f414 100644
--- a/hapi-fhir-validation-resources-r4/pom.xml
+++ b/hapi-fhir-validation-resources-r4/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml
index afa97d77f1c..708cbe421a7 100644
--- a/hapi-fhir-validation-resources-r5/pom.xml
+++ b/hapi-fhir-validation-resources-r5/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index 751a3b721ee..9a7e1c13971 100644
--- a/hapi-fhir-validation/pom.xml
+++ b/hapi-fhir-validation/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/ValidatorWrapper.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/ValidatorWrapper.java
index d1c28f2b274..37323be9e1c 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/ValidatorWrapper.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/ValidatorWrapper.java
@@ -4,20 +4,24 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.util.XmlUtil;
import ca.uhn.fhir.validation.IValidationContext;
-import com.google.gson.*;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import org.apache.commons.codec.Charsets;
import org.apache.commons.io.input.ReaderInputStream;
+import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Manager;
+import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.r5.utils.IResourceValidator;
-import org.hl7.fhir.r5.utils.ValidationProfileSet;
import org.hl7.fhir.r5.validation.InstanceValidator;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
-import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.io.InputStream;
@@ -33,7 +37,9 @@ public class ValidatorWrapper {
private boolean myAnyExtensionsAllowed;
private boolean myErrorForUnknownProfiles;
private boolean myNoTerminologyChecks;
+ private boolean myAssumeValidRestReferences;
private Collection extends String> myExtensionDomains;
+ private IResourceValidator.IValidatorResourceFetcher myValidatorResourceFetcher;
/**
* Constructor
@@ -42,6 +48,15 @@ public class ValidatorWrapper {
super();
}
+ public boolean isAssumeValidRestReferences() {
+ return myAssumeValidRestReferences;
+ }
+
+ public ValidatorWrapper setAssumeValidRestReferences(boolean assumeValidRestReferences) {
+ this.myAssumeValidRestReferences = assumeValidRestReferences;
+ return this;
+ }
+
public ValidatorWrapper setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel theBestPracticeWarningLevel) {
myBestPracticeWarningLevel = theBestPracticeWarningLevel;
return this;
@@ -67,6 +82,12 @@ public class ValidatorWrapper {
return this;
}
+
+ public ValidatorWrapper setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) {
+ this.myValidatorResourceFetcher = validatorResourceFetcher;
+ return this;
+ }
+
public List validate(IWorkerContext theWorkerContext, IValidationContext> theValidationContext) {
InstanceValidator v;
FHIRPathEngine.IEvaluationContext evaluationCtx = new org.hl7.fhir.r5.hapi.validation.FhirInstanceValidator.NullEvaluationContext();
@@ -76,19 +97,21 @@ public class ValidatorWrapper {
throw new ConfigurationException(e);
}
+ v.setAssumeValidRestReferences(isAssumeValidRestReferences());
v.setBestPracticeWarningLevel(myBestPracticeWarningLevel);
v.setAnyExtensionsAllowed(myAnyExtensionsAllowed);
v.setResourceIdRule(IResourceValidator.IdStatus.OPTIONAL);
v.setNoTerminologyChecks(myNoTerminologyChecks);
v.setErrorForUnknownProfiles(myErrorForUnknownProfiles);
v.getExtensionDomains().addAll(myExtensionDomains);
+ v.setFetcher(myValidatorResourceFetcher);
v.setAllowXsiLocation(true);
List messages = new ArrayList<>();
- ValidationProfileSet profileSet = new ValidationProfileSet();
+ List profileUrls = new ArrayList<>();
for (String next : theValidationContext.getOptions().getProfiles()) {
- profileSet.getCanonical().add(new ValidationProfileSet.ProfileRegistration(next, true));
+ fetchAndAddProfile(theWorkerContext, profileUrls, next);
}
String input = theValidationContext.getResourceAsString();
@@ -109,14 +132,14 @@ public class ValidatorWrapper {
// Determine if meta/profiles are present...
ArrayList profiles = determineIfProfilesSpecified(document);
for (String nextProfile : profiles) {
- profileSet.getCanonical().add(new ValidationProfileSet.ProfileRegistration(nextProfile, true));
+ fetchAndAddProfile(theWorkerContext, profileUrls, nextProfile);
}
String resourceAsString = theValidationContext.getResourceAsString();
InputStream inputStream = new ReaderInputStream(new StringReader(resourceAsString), Charsets.UTF_8);
Manager.FhirFormat format = Manager.FhirFormat.XML;
- v.validate(null, messages, inputStream, format, profileSet);
+ v.validate(null, messages, inputStream, format, profileUrls);
} else if (encoding == EncodingEnum.JSON) {
@@ -129,7 +152,8 @@ public class ValidatorWrapper {
if (profileElement != null && profileElement.isJsonArray()) {
JsonArray profiles = profileElement.getAsJsonArray();
for (JsonElement element : profiles) {
- profileSet.getCanonical().add(new ValidationProfileSet.ProfileRegistration(element.getAsString(), true));
+ String nextProfile = element.getAsString();
+ fetchAndAddProfile(theWorkerContext, profileUrls, nextProfile);
}
}
}
@@ -138,7 +162,7 @@ public class ValidatorWrapper {
InputStream inputStream = new ReaderInputStream(new StringReader(resourceAsString), Charsets.UTF_8);
Manager.FhirFormat format = Manager.FhirFormat.JSON;
- v.validate(null, messages, inputStream, format, profileSet);
+ v.validate(null, messages, inputStream, format, profileUrls);
} else {
throw new IllegalArgumentException("Unknown encoding: " + encoding);
@@ -157,17 +181,16 @@ public class ValidatorWrapper {
return messages;
}
-
- private String determineResourceName(Document theDocument) {
- NodeList list = theDocument.getChildNodes();
- for (int i = 0; i < list.getLength(); i++) {
- if (list.item(i) instanceof Element) {
- return list.item(i).getLocalName();
- }
+ private void fetchAndAddProfile(IWorkerContext theWorkerContext, List theProfileStructureDefinitions, String theUrl) throws org.hl7.fhir.exceptions.FHIRException {
+ try {
+ StructureDefinition structureDefinition = theWorkerContext.fetchResourceWithException(StructureDefinition.class, theUrl);
+ theProfileStructureDefinitions.add(structureDefinition);
+ } catch (FHIRException e) {
+ ourLog.debug("Failed to load profile: {}", theUrl);
}
- return theDocument.getDocumentElement().getLocalName();
}
+
private ArrayList determineIfProfilesSpecified(Document theDocument) {
ArrayList profileNames = new ArrayList<>();
NodeList list = theDocument.getChildNodes().item(0).getChildNodes();
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/FhirInstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/FhirInstanceValidator.java
index e583381a5ee..e4ab01d7f78 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/FhirInstanceValidator.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/FhirInstanceValidator.java
@@ -1,14 +1,10 @@
package org.hl7.fhir.dstu2016may.hapi.validation;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
+import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.Constants;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import ca.uhn.fhir.validation.IValidationContext;
+import ca.uhn.fhir.validation.IValidatorModule;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.apache.commons.lang3.Validate;
@@ -18,28 +14,45 @@ import org.apache.commons.lang3.time.DateUtils;
import org.fhir.ucum.UcumService;
import org.hl7.fhir.common.hapi.validation.ValidatorWrapper;
import org.hl7.fhir.convertors.VersionConvertor_14_50;
+import org.hl7.fhir.convertors.conv14_50.CodeSystem14_50;
+import org.hl7.fhir.convertors.conv14_50.StructureDefinition14_50;
+import org.hl7.fhir.convertors.conv14_50.ValueSet14_50;
+import org.hl7.fhir.dstu2016may.model.CodeSystem;
+import org.hl7.fhir.dstu2016may.model.CodeableConcept;
+import org.hl7.fhir.dstu2016may.model.Coding;
+import org.hl7.fhir.dstu2016may.model.ImplementationGuide;
+import org.hl7.fhir.dstu2016may.model.Questionnaire;
+import org.hl7.fhir.dstu2016may.model.StructureDefinition;
+import org.hl7.fhir.dstu2016may.model.ValueSet;
import org.hl7.fhir.exceptions.DefinitionException;
+import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.formats.IParser;
import org.hl7.fhir.r5.formats.ParserType;
import org.hl7.fhir.r5.model.CanonicalResource;
+import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.utils.INarrativeGenerator;
import org.hl7.fhir.r5.utils.IResourceValidator;
-import org.hl7.fhir.r5.model.Resource;
-import org.hl7.fhir.dstu2016may.model.*;
-import org.hl7.fhir.exceptions.FHIRException;
-import org.hl7.fhir.utilities.TerminologyServiceOptions;
import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationOptions;
-import org.w3c.dom.*;
+import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
-import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
-import ca.uhn.fhir.validation.IValidationContext;
-import ca.uhn.fhir.validation.IValidatorModule;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
@@ -382,7 +395,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
}
public org.hl7.fhir.r5.model.StructureDefinition convert(StructureDefinition next) {
- org.hl7.fhir.r5.model.StructureDefinition structureDefinition = VersionConvertor_14_50.convertStructureDefinition(next);
+ org.hl7.fhir.r5.model.StructureDefinition structureDefinition = StructureDefinition14_50.convertStructureDefinition(next);
if (next.getDerivation() != org.hl7.fhir.dstu2016may.model.StructureDefinition.TypeDerivationRule.CONSTRAINT) {
structureDefinition.setType(next.getName());
}
@@ -408,7 +421,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent conceptDefinition = null;
if (theResult.asConceptDefinition() != null) {
try {
- conceptDefinition = VersionConvertor_14_50.convertConceptDefinitionComponent(theResult.asConceptDefinition());
+ conceptDefinition = CodeSystem14_50.convertConceptDefinitionComponent(theResult.asConceptDefinition());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -428,7 +441,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
public org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome expandVS(org.hl7.fhir.r5.model.ValueSet source, boolean cacheOk, boolean heiarchical) {
ValueSet convertedSource;
try {
- convertedSource = VersionConvertor_14_50.convertValueSet(source);
+ convertedSource = ValueSet14_50.convertValueSet(source);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -437,7 +450,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
org.hl7.fhir.r5.model.ValueSet convertedResult = null;
if (expanded.getValueset() != null) {
try {
- convertedResult = VersionConvertor_14_50.convertValueSet(expanded.getValueset());
+ convertedResult = ValueSet14_50.convertValueSet(expanded.getValueset());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -458,7 +471,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
ValueSet.ConceptSetComponent convertedInc = null;
if (inc != null) {
try {
- convertedInc = VersionConvertor_14_50.convertConceptSetComponent(inc);
+ convertedInc = ValueSet14_50.convertConceptSetComponent(inc);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -468,7 +481,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent valueSetExpansionComponent = null;
if (expansion != null) {
try {
- valueSetExpansionComponent = VersionConvertor_14_50.convertValueSetExpansionComponent(expansion);
+ valueSetExpansionComponent = ValueSet14_50.convertValueSetExpansionComponent(expansion);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -492,7 +505,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
return null;
}
try {
- return VersionConvertor_14_50.convertCodeSystem(fetched);
+ return CodeSystem14_50.convertCodeSystem(fetched);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -572,6 +585,11 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + typeName);
}
+ @Override
+ public org.hl7.fhir.r5.model.StructureDefinition fetchRawProfile(String url) {
+ return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, url);
+ }
+
@Override
public List getTypeNames() {
@@ -665,7 +683,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
try {
if (vs != null) {
- convertedVs = VersionConvertor_14_50.convertValueSet(vs);
+ convertedVs = ValueSet14_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -680,7 +698,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
ValueSet convertedVs = null;
try {
if (vs != null) {
- convertedVs = VersionConvertor_14_50.convertValueSet(vs);
+ convertedVs = ValueSet14_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -700,7 +718,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
convertedCode = VersionConvertor_14_50.convertCoding(code);
}
if (vs != null) {
- convertedVs = VersionConvertor_14_50.convertValueSet(vs);
+ convertedVs = ValueSet14_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -720,7 +738,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
convertedCode = VersionConvertor_14_50.convertCodeableConcept(code);
}
if (vs != null) {
- convertedVs = VersionConvertor_14_50.convertValueSet(vs);
+ convertedVs = ValueSet14_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidator.java
index ba3c7a8755f..609941ba6a9 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidator.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidator.java
@@ -23,6 +23,7 @@ import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.ImplementationGuide;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.dstu3.model.Resource;
+import org.hl7.fhir.dstu3.model.SearchParameter;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.exceptions.FHIRException;
@@ -56,6 +57,13 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import static org.hl7.fhir.convertors.conv30_50.CodeSystem30_50.convertCodeSystem;
+import static org.hl7.fhir.convertors.conv30_50.CodeSystem30_50.convertConceptDefinitionComponent;
+import static org.hl7.fhir.convertors.conv30_50.StructureDefinition30_50.convertStructureDefinition;
+import static org.hl7.fhir.convertors.conv30_50.ValueSet30_50.convertConceptSetComponent;
+import static org.hl7.fhir.convertors.conv30_50.ValueSet30_50.convertValueSet;
+import static org.hl7.fhir.convertors.conv30_50.ValueSet30_50.convertValueSetExpansionComponent;
+
@SuppressWarnings({"PackageAccessibility", "Duplicates"})
public class FhirInstanceValidator extends BaseValidatorBridge implements IInstanceValidatorModule {
@@ -66,10 +74,12 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
private StructureDefinition myStructureDefintion;
private IValidationSupport myValidationSupport;
private boolean noTerminologyChecks = false;
+ private IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher;
private volatile WorkerContextWrapper myWrappedWorkerContext;
private boolean errorForUnknownProfiles;
private List myExtensionDomains = Collections.emptyList();
+ private boolean assumeValidRestReferences;
/**
* Constructor
@@ -285,10 +295,28 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
.setErrorForUnknownProfiles(isErrorForUnknownProfiles())
.setExtensionDomains(getExtensionDomains())
.setNoTerminologyChecks(isNoTerminologyChecks())
+ .setValidatorResourceFetcher(getValidatorResourceFetcher())
+ .setAssumeValidRestReferences(isAssumeValidRestReferences())
.validate(wrappedWorkerContext, theValidationCtx);
}
+ public IResourceValidator.IValidatorResourceFetcher getValidatorResourceFetcher() {
+ return validatorResourceFetcher;
+ }
+
+ public void setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) {
+ this.validatorResourceFetcher = validatorResourceFetcher;
+ }
+
+ public boolean isAssumeValidRestReferences() {
+ return assumeValidRestReferences;
+ }
+
+ public void setAssumeValidRestReferences(boolean assumeValidRestReferences) {
+ this.assumeValidRestReferences = assumeValidRestReferences;
+ }
+
private static class WorkerContextWrapper implements IWorkerContext {
private final HapiWorkerContext myWrap;
@@ -327,6 +355,9 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
case "ImplementationGuide":
fetched = myWrap.fetchResource(ImplementationGuide.class, key.getUri());
break;
+ case "SearchParameter":
+ fetched = myWrap.fetchResource(SearchParameter.class, key.getUri());
+ break;
default:
throw new UnsupportedOperationException("Don't know how to fetch " + key.getResourceName());
}
@@ -386,7 +417,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
retVal = new ArrayList<>();
for (StructureDefinition next : myWrap.allStructures()) {
try {
- retVal.add(VersionConvertor_30_50.convertStructureDefinition(next));
+ retVal.add(convertStructureDefinition(next));
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -416,7 +447,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent conceptDefinition = null;
if (theResult.asConceptDefinition() != null) {
try {
- conceptDefinition = VersionConvertor_30_50.convertConceptDefinitionComponent(theResult.asConceptDefinition());
+ conceptDefinition = convertConceptDefinitionComponent(theResult.asConceptDefinition());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -436,7 +467,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
public ValueSetExpander.ValueSetExpansionOutcome expandVS(org.hl7.fhir.r5.model.ValueSet source, boolean cacheOk, boolean heiarchical) {
ValueSet convertedSource;
try {
- convertedSource = VersionConvertor_30_50.convertValueSet(source);
+ convertedSource = convertValueSet(source);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -445,7 +476,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
org.hl7.fhir.r5.model.ValueSet convertedResult = null;
if (expanded.getValueset() != null) {
try {
- convertedResult = VersionConvertor_30_50.convertValueSet(expanded.getValueset());
+ convertedResult = convertValueSet(expanded.getValueset());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -467,7 +498,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
ValueSet.ConceptSetComponent convertedInc = null;
if (inc != null) {
try {
- convertedInc = VersionConvertor_30_50.convertConceptSetComponent(inc);
+ convertedInc = convertConceptSetComponent(inc);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -477,7 +508,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent valueSetExpansionComponent = null;
if (expansion != null) {
try {
- valueSetExpansionComponent = VersionConvertor_30_50.convertValueSetExpansionComponent(expansion);
+ valueSetExpansionComponent = convertValueSetExpansionComponent(expansion);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -495,7 +526,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
return null;
}
try {
- return VersionConvertor_30_50.convertCodeSystem(fetched);
+ return convertCodeSystem(fetched);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -584,6 +615,11 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + typeName);
}
+ @Override
+ public org.hl7.fhir.r5.model.StructureDefinition fetchRawProfile(String url) {
+ return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, url);
+ }
+
@Override
public List getTypeNames() {
return myWrap.getTypeNames();
@@ -676,7 +712,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
try {
if (vs != null) {
- convertedVs = VersionConvertor_30_50.convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -691,7 +727,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
ValueSet convertedVs = null;
try {
if (vs != null) {
- convertedVs = VersionConvertor_30_50.convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -711,7 +747,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
convertedCode = VersionConvertor_30_50.convertCoding(code);
}
if (vs != null) {
- convertedVs = VersionConvertor_30_50.convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -731,7 +767,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
convertedCode = VersionConvertor_30_50.convertCodeableConcept(code);
}
if (vs != null) {
- convertedVs = VersionConvertor_30_50.convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/FhirInstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/FhirInstanceValidator.java
index a92e2a957af..877c9cfa880 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/FhirInstanceValidator.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/FhirInstanceValidator.java
@@ -27,12 +27,13 @@ import org.fhir.ucum.UcumService;
import org.hl7.fhir.converter.NullVersionConverterAdvisor50;
import org.hl7.fhir.convertors.VersionConvertorAdvisor50;
import org.hl7.fhir.convertors.VersionConvertor_10_50;
+import org.hl7.fhir.convertors.conv10_50.ValueSet10_50;
+import org.hl7.fhir.convertors.conv14_50.CodeSystem14_50;
import org.hl7.fhir.dstu2.model.CodeableConcept;
import org.hl7.fhir.dstu2.model.Coding;
import org.hl7.fhir.dstu2.model.Questionnaire;
import org.hl7.fhir.dstu2.model.StructureDefinition;
import org.hl7.fhir.dstu2.model.ValueSet;
-import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.context.IWorkerContext;
@@ -60,6 +61,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -69,6 +71,11 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.hl7.fhir.convertors.VersionConvertor_10_50.convertCoding;
+import static org.hl7.fhir.convertors.conv10_50.StructureDefinition10_50.convertStructureDefinition;
+import static org.hl7.fhir.convertors.conv10_50.ValueSet10_50.convertConceptSetComponent;
+import static org.hl7.fhir.convertors.conv10_50.ValueSet10_50.convertValueSet;
+import static org.hl7.fhir.convertors.conv10_50.ValueSet10_50.convertValueSetExpansionComponent;
public class FhirInstanceValidator extends BaseValidatorBridge implements IInstanceValidatorModule {
@@ -81,8 +88,19 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
private StructureDefinition myStructureDefintion;
private IValidationSupport myValidationSupport;
private boolean noTerminologyChecks = false;
+
+ public boolean isAssumeValidRestReferences() {
+ return assumeValidRestReferences;
+ }
+
+ public void setAssumeValidRestReferences(boolean assumeValidRestReferences) {
+ this.assumeValidRestReferences = assumeValidRestReferences;
+ }
+
+ private boolean assumeValidRestReferences;
private volatile WorkerContextWrapper myWrappedWorkerContext;
private VersionConvertorAdvisor50 myAdvisor = new NullVersionConverterAdvisor50();
+ private IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher;
/**
* Constructor
@@ -287,6 +305,8 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
v.setAnyExtensionsAllowed(isAnyExtensionsAllowed());
v.setResourceIdRule(IdStatus.OPTIONAL);
v.setNoTerminologyChecks(isNoTerminologyChecks());
+ v.setFetcher(getValidatorResourceFetcher());
+ v.setAssumeValidRestReferences(isAssumeValidRestReferences());
List messages = new ArrayList<>();
@@ -388,6 +408,14 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
return messages;
}
+ public IResourceValidator.IValidatorResourceFetcher getValidatorResourceFetcher() {
+ return validatorResourceFetcher;
+ }
+
+ public void setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) {
+ this.validatorResourceFetcher = validatorResourceFetcher;
+ }
+
@Override
protected List validate(IValidationContext> theCtx) {
return validate(theCtx.getFhirContext(), theCtx.getResourceAsString(), theCtx.getResourceAsStringEncoding());
@@ -428,7 +456,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
return null;
}
}
- profileText = IOUtils.toString(inputStream, "UTF-8");
+ profileText = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
} catch (IOException e1) {
if (theMessages != null) {
theMessages.add(new ValidationMessage().setLevel(IssueSeverity.FATAL)
@@ -457,11 +485,17 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
case "StructureDefinition":
fetched = myWrap.fetchResource(StructureDefinition.class, key.getUri());
break;
+ case "CodeSystem":
case "ValueSet":
fetched = myWrap.fetchResource(ValueSet.class, key.getUri());
- break;
- case "CodeSystem":
- fetched = myWrap.fetchResource(ValueSet.class, key.getUri());
+
+ ValueSet fetchedVs = (ValueSet) fetched;
+ if (!fetchedVs.hasCompose()) {
+ if (fetchedVs.hasCodeSystem()) {
+ fetchedVs.getCompose().addInclude().setSystem(fetchedVs.getCodeSystem().getSystem());
+ }
+ }
+
break;
case "Questionnaire":
fetched = myWrap.fetchResource(Questionnaire.class, key.getUri());
@@ -477,7 +511,15 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
}
try {
- org.hl7.fhir.r5.model.Resource converted = new VersionConvertor_10_50(myAdvisor).convertResource(fetched);
+ org.hl7.fhir.r5.model.Resource converted;
+ if ("CodeSystem".equals(key.getUri())) {
+ NullVersionConverterAdvisor50 advisor = new NullVersionConverterAdvisor50();
+ converted = ValueSet10_50.convertValueSet((ValueSet) fetched, advisor);
+ converted = advisor.getCodeSystem((org.hl7.fhir.r5.model.ValueSet) converted);
+ } else {
+ converted = VersionConvertor_10_50.convertResource(fetched);
+ }
+
if (fetched instanceof StructureDefinition) {
StructureDefinition fetchedSd = (StructureDefinition) fetched;
@@ -501,7 +543,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
public WorkerContextWrapper(HapiWorkerContext theWorkerContext) {
myWrap = theWorkerContext;
- myConverter = new VersionConvertor_10_50(myAdvisor);
+ myConverter = new VersionConvertor_10_50();
}
@Override
@@ -510,7 +552,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
}
@Override
- public void generateSnapshot(org.hl7.fhir.r5.model.StructureDefinition p) throws DefinitionException, FHIRException {
+ public void generateSnapshot(org.hl7.fhir.r5.model.StructureDefinition p) throws FHIRException {
}
@@ -547,7 +589,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
retVal = new ArrayList<>();
for (StructureDefinition next : myWrap.allStructures()) {
try {
- org.hl7.fhir.r5.model.StructureDefinition converted = new VersionConvertor_10_50(myAdvisor).convertStructureDefinition(next);
+ org.hl7.fhir.r5.model.StructureDefinition converted = convertStructureDefinition(next);
if (converted != null) {
retVal.add(converted);
}
@@ -587,7 +629,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
public ValueSetExpander.ValueSetExpansionOutcome expandVS(org.hl7.fhir.r5.model.ValueSet source, boolean cacheOk, boolean heiarchical) {
ValueSet convertedSource = null;
try {
- convertedSource = new VersionConvertor_10_50(myAdvisor).convertValueSet(source);
+ convertedSource = convertValueSet(source);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -596,7 +638,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
org.hl7.fhir.r5.model.ValueSet convertedResult = null;
if (expanded.getValueset() != null) {
try {
- convertedResult = new VersionConvertor_10_50(myAdvisor).convertValueSet(expanded.getValueset());
+ convertedResult = convertValueSet(expanded.getValueset());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -618,7 +660,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
ValueSet.ConceptSetComponent convertedInc = null;
if (inc != null) {
try {
- convertedInc = new VersionConvertor_10_50(myAdvisor).convertConceptSetComponent(inc);
+ convertedInc = convertConceptSetComponent(inc);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -628,7 +670,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent valueSetExpansionComponent = null;
if (expansion != null) {
try {
- valueSetExpansionComponent = new VersionConvertor_10_50(myAdvisor).convertValueSetExpansionComponent(expansion);
+ valueSetExpansionComponent = convertValueSetExpansionComponent(expansion);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -733,6 +775,11 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+typeName);
}
+ @Override
+ public org.hl7.fhir.r5.model.StructureDefinition fetchRawProfile(String url) {
+ return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, url);
+ }
+
@Override
public void setUcumService(UcumService ucumService) {
throw new UnsupportedOperationException();
@@ -825,7 +872,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
try {
if (vs != null) {
- convertedVs = new VersionConvertor_10_50(myAdvisor).convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -840,8 +887,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
ValueSet convertedVs = null;
try {
if (vs != null) {
- VersionConvertorAdvisor50 advisor50 = new NullVersionConverterAdvisor50();
- convertedVs = new VersionConvertor_10_50(advisor50).convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -858,10 +904,10 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
try {
if (code != null) {
- convertedCode = new VersionConvertor_10_50(myAdvisor).convertCoding(code);
+ convertedCode = convertCoding(code);
}
if (vs != null) {
- convertedVs = new VersionConvertor_10_50(myAdvisor).convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -878,10 +924,10 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
try {
if (code != null) {
- convertedCode = new VersionConvertor_10_50(myAdvisor).convertCodeableConcept(code);
+ convertedCode = VersionConvertor_10_50.convertCodeableConcept(code);
}
if (vs != null) {
- convertedVs = new VersionConvertor_10_50(myAdvisor).convertValueSet(vs);
+ convertedVs = convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/HapiWorkerContext.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/HapiWorkerContext.java
index 9cdae210cd8..1788fd582a5 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/HapiWorkerContext.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/HapiWorkerContext.java
@@ -199,7 +199,7 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
nextSystem = nextComposeConceptSet.getSystem();
}
- if (StringUtils.equals(nextSystem, nextComposeConceptSet.getSystem())) {
+ if (Constants.codeSystemNotNeeded(theSystem) || StringUtils.equals(nextSystem, nextComposeConceptSet.getSystem())) {
for (ConceptReferenceComponent nextComposeCode : nextComposeConceptSet.getConcept()) {
ConceptDefinitionComponent conceptDef = new ConceptDefinitionComponent();
conceptDef.setCode(nextComposeCode.getCode());
@@ -211,7 +211,13 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
}
if (nextComposeConceptSet.getConcept().isEmpty()){
- ValidationResult result = validateCode(nextSystem, theCode, null);
+
+ String validateSystem = nextSystem;
+ if (Constants.codeSystemNotNeeded(nextSystem)) {
+ validateSystem = nextComposeConceptSet.getSystem();
+ }
+
+ ValidationResult result = validateCode(validateSystem, theCode, null);
if (result.isOk()){
return result;
}
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java
index d7c52d229a1..d5441294501 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/hapi/validation/FhirInstanceValidator.java
@@ -59,7 +59,8 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
private IValidationSupport myValidationSupport;
private boolean noTerminologyChecks = false;
private volatile WorkerContextWrapper myWrappedWorkerContext;
-
+ private IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher;
+ private boolean assumeValidRestReferences;
private boolean errorForUnknownProfiles;
private List extensionDomains = Collections.emptyList();
@@ -225,13 +226,32 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
.setErrorForUnknownProfiles(isErrorForUnknownProfiles())
.setExtensionDomains(getExtensionDomains())
.setNoTerminologyChecks(isNoTerminologyChecks())
+ .setValidatorResourceFetcher(getValidatorResourceFetcher())
+ .setAssumeValidRestReferences(isAssumeValidRestReferences())
.validate(wrappedWorkerContext, theValidationCtx);
}
+ public IResourceValidator.IValidatorResourceFetcher getValidatorResourceFetcher() {
+ return validatorResourceFetcher;
+ }
+
+ public void setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) {
+ this.validatorResourceFetcher = validatorResourceFetcher;
+ }
+
+
private List getExtensionDomains() {
return extensionDomains;
}
+ public boolean isAssumeValidRestReferences() {
+ return assumeValidRestReferences;
+ }
+
+ public void setAssumeValidRestReferences(boolean assumeValidRestReferences) {
+ this.assumeValidRestReferences = assumeValidRestReferences;
+ }
+
private static class WorkerContextWrapper implements IWorkerContext {
private final HapiWorkerContext myWrap;
@@ -317,7 +337,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
retVal = new ArrayList<>();
for (StructureDefinition next : myWrap.allStructures()) {
try {
- retVal.add(org.hl7.fhir.convertors.conv40_50.StructureDefinition.convertStructureDefinition(next));
+ retVal.add(org.hl7.fhir.convertors.conv40_50.StructureDefinition40_50.convertStructureDefinition(next));
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -347,7 +367,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent conceptDefinition = null;
if (theResult.asConceptDefinition() != null) {
try {
- conceptDefinition = org.hl7.fhir.convertors.conv40_50.CodeSystem.convertConceptDefinitionComponent(theResult.asConceptDefinition());
+ conceptDefinition = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertConceptDefinitionComponent(theResult.asConceptDefinition());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -367,7 +387,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
public ValueSetExpander.ValueSetExpansionOutcome expandVS(org.hl7.fhir.r5.model.ValueSet source, boolean cacheOk, boolean heiarchical) {
ValueSet convertedSource;
try {
- convertedSource = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(source);
+ convertedSource = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(source);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -376,7 +396,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
org.hl7.fhir.r5.model.ValueSet convertedResult = null;
if (expanded.getValueset() != null) {
try {
- convertedResult = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(expanded.getValueset());
+ convertedResult = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(expanded.getValueset());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -398,7 +418,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
ValueSet.ConceptSetComponent convertedInc = null;
if (inc != null) {
try {
- convertedInc = org.hl7.fhir.convertors.conv40_50.ValueSet.convertConceptSetComponent(inc);
+ convertedInc = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertConceptSetComponent(inc);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -408,7 +428,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
org.hl7.fhir.r5.model.ValueSet valueSetExpansion = null;
if (expansion != null) {
try {
- valueSetExpansion = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(expansion.getValueset());
+ valueSetExpansion = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(expansion.getValueset());
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -424,7 +444,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
return null;
}
try {
- return org.hl7.fhir.convertors.conv40_50.CodeSystem.convertCodeSystem(fetched);
+ return org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(fetched);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
@@ -509,6 +529,11 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + typeName);
}
+ @Override
+ public org.hl7.fhir.r5.model.StructureDefinition fetchRawProfile(String url) {
+ return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, url);
+ }
+
@Override
public List getTypeNames() {
return myWrap.getTypeNames();
@@ -605,7 +630,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
try {
if (vs != null) {
- convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(vs);
+ convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -620,7 +645,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
ValueSet convertedVs = null;
try {
if (vs != null) {
- convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(vs);
+ convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -640,7 +665,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
convertedCode = VersionConvertor_40_50.convertCoding(code);
}
if (vs != null) {
- convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(vs);
+ convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
@@ -660,7 +685,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
convertedCode = VersionConvertor_40_50.convertCodeableConcept(code);
}
if (vs != null) {
- convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet.convertValueSet(vs);
+ convertedVs = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(vs);
}
} catch (FHIRException e) {
throw new InternalErrorException(e);
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r5/hapi/validation/FhirInstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r5/hapi/validation/FhirInstanceValidator.java
index 02a3fd839d2..a6ced0b4654 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r5/hapi/validation/FhirInstanceValidator.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r5/hapi/validation/FhirInstanceValidator.java
@@ -54,7 +54,9 @@ public class FhirInstanceValidator extends org.hl7.fhir.r5.hapi.validation.BaseV
private boolean noTerminologyChecks = false;
private volatile WorkerContextWrapper myWrappedWorkerContext;
private boolean errorForUnknownProfiles;
+ private boolean assumeValidRestReferences;
private List myExtensionDomains = Collections.emptyList();
+ private IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher;
/**
* Constructor
@@ -220,9 +222,27 @@ public class FhirInstanceValidator extends org.hl7.fhir.r5.hapi.validation.BaseV
.setErrorForUnknownProfiles(isErrorForUnknownProfiles())
.setExtensionDomains(getExtensionDomains())
.setNoTerminologyChecks(isNoTerminologyChecks())
+ .setValidatorResourceFetcher(getValidatorResourceFetcher())
+ .setAssumeValidRestReferences(isAssumeValidRestReferences())
.validate(wrappedWorkerContext, theValidationCtx);
}
+ public IResourceValidator.IValidatorResourceFetcher getValidatorResourceFetcher() {
+ return validatorResourceFetcher;
+ }
+
+ public void setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) {
+ this.validatorResourceFetcher = validatorResourceFetcher;
+ }
+
+ public boolean isAssumeValidRestReferences() {
+ return assumeValidRestReferences;
+ }
+
+ public void setAssumeValidRestReferences(boolean assumeValidRestReferences) {
+ this.assumeValidRestReferences = assumeValidRestReferences;
+ }
+
private static class WorkerContextWrapper implements IWorkerContext {
private final HapiWorkerContext myWrap;
@@ -514,6 +534,11 @@ public class FhirInstanceValidator extends org.hl7.fhir.r5.hapi.validation.BaseV
return fetchResource(org.hl7.fhir.r5.model.StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + typeName);
}
+ @Override
+ public StructureDefinition fetchRawProfile(String url) {
+ return myWrap.fetchRawProfile(url);
+ }
+
@Override
public List getTypeNames() {
return myWrap.getTypeNames();
@@ -706,7 +731,7 @@ public class FhirInstanceValidator extends org.hl7.fhir.r5.hapi.validation.BaseV
}
@Override
- public Base resolveReference(Object appContext, String url) throws FHIRException {
+ public Base resolveReference(Object appContext, String url, Base refContext) throws FHIRException {
return null;
}
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidatorDstu3Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidatorDstu3Test.java
index bace1c7268e..29fbca55962 100644
--- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidatorDstu3Test.java
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/FhirInstanceValidatorDstu3Test.java
@@ -24,10 +24,12 @@ import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine;
import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.r5.utils.IResourceValidator;
import org.junit.*;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
+import org.mockito.internal.matchers.Any;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -41,8 +43,7 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class FhirInstanceValidatorDstu3Test {
@@ -975,7 +976,7 @@ public class FhirInstanceValidatorDstu3Test {
myInstanceVal.setValidationSupport(myMockSupport);
ValidationResult output = myVal.validateWithResult(input);
List errors = logResultsAndReturnNonInformationalOnes(output);
- assertThat(errors.toString(), containsString("StructureDefinition reference \"http://foo/structuredefinition/myprofile\" could not be resolved"));
+ assertThat(errors.toString(), containsString("Profile reference 'http://foo/structuredefinition/myprofile' could not be resolved, so has not been checked"));
}
@Test
@@ -1145,6 +1146,20 @@ public class FhirInstanceValidatorDstu3Test {
ourLog.info(output.getMessages().get(0).getMessage());
}
+ @Test
+ public void testInvocationOfValidatorFetcher() throws IOException {
+ String input = IOUtils.toString(FhirInstanceValidatorDstu3Test.class.getResourceAsStream("/dstu3-rick-test.json"), Charsets.UTF_8);
+
+ IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
+ when(resourceFetcher.validationPolicy(any(),anyString(), anyString())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
+ myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
+ myVal.validateWithResult(input);
+
+ verify(resourceFetcher, times(3)).resolveURL(any(), anyString(), anyString());
+ verify(resourceFetcher, times(4)).validationPolicy(any(), anyString(), anyString());
+ verify(resourceFetcher, times(4)).fetch(any(), anyString());
+ }
+
@Test
public void testValueWithWhitespace() throws IOException {
String input = IOUtils.toString(FhirInstanceValidatorDstu3Test.class.getResourceAsStream("/dstu3-rick-test.json"), Charsets.UTF_8);
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java
index d4bbfac740e..7cbd9968f1e 100644
--- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireResponseValidatorDstu3Test.java
@@ -704,7 +704,7 @@ public class QuestionnaireResponseValidatorDstu3Test {
coding.setCode("1293");
QuestionnaireResponseItemAnswerComponent answer = qrItem.addAnswer();
answer.setValue(coding);
- coding.addExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-hidden", new BooleanType(true));
+ coding.addExtension("http://hl7.org/fhir/StructureDefinition/iso21090-CO-value", new DecimalType("1.0"));
qr.addItem().setLinkId("2B").addAnswer().setValue(new BooleanType(true));
String reference = qr.getQuestionnaire().getReference();
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireValidatorDstu3Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireValidatorDstu3Test.java
index 4a8ececb99a..9e8a25f5a42 100644
--- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireValidatorDstu3Test.java
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/dstu3/hapi/validation/QuestionnaireValidatorDstu3Test.java
@@ -20,6 +20,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
+import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
@@ -71,7 +72,7 @@ public class QuestionnaireValidatorDstu3Test {
ValidationResult errors = myVal.validateWithResult(q);
ourLog.info(errors.toString());
assertThat(errors.isSuccessful(), Matchers.is(true));
- assertThat(errors.getMessages(), Matchers.empty());
+ assertThat(errors.getMessages().stream().filter(t->t.getSeverity().ordinal() > ResultSeverityEnum.INFORMATION.ordinal()).collect(Collectors.toList()), Matchers.empty());
}
}
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java
index ce094c1a8a8..fe617e9b955 100644
--- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/FhirInstanceValidatorR4Test.java
@@ -66,9 +66,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.times;
public class FhirInstanceValidatorR4Test extends BaseTest {
@@ -397,7 +398,11 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myVal.validateWithResult(encoded);
List errors = logResultsAndReturnNonInformationalOnes(output);
- assertEquals(46, errors.size());
+ errors = errors
+ .stream()
+ .filter(t->t.getMessage().contains("Bundle entry missing fullUrl"))
+ .collect(Collectors.toList());
+ assertEquals(5, errors.size());
}
@Test
@@ -633,8 +638,8 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
CachingValidationSupport support = new CachingValidationSupport(new ValidationSupportChain(defaultSupport, valSupport));
// Prepopulate SDs
- valSupport.addStructureDefinition(loadStructureDefinition(defaultSupport, "/dstu3/myconsent-profile.xml"));
- valSupport.addStructureDefinition(loadStructureDefinition(defaultSupport, "/dstu3/myconsent-ext.xml"));
+ valSupport.addStructureDefinition(loadStructureDefinition(defaultSupport, "/r4/myconsent-profile.xml"));
+ valSupport.addStructureDefinition(loadStructureDefinition(defaultSupport, "/r4/myconsent-ext.xml"));
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator(support));
@@ -652,6 +657,8 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
.setSystem("http://terminology.hl7.org/CodeSystem/consentcategorycodes")
.setCode("acd");
+
+
// Should pass
ValidationResult output = val.validateWithResult(input);
List all = logResultsAndReturnErrorOnes(output);
@@ -1031,7 +1038,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
myInstanceVal.setValidationSupport(myMockSupport);
ValidationResult output = myVal.validateWithResult(input);
List errors = logResultsAndReturnNonInformationalOnes(output);
- assertThat(errors.toString(), containsString("StructureDefinition reference \"http://foo/structuredefinition/myprofile\" could not be resolved"));
+ assertThat(errors.toString(), containsString("Profile reference 'http://foo/structuredefinition/myprofile' could not be resolved, so has not been checked"));
}
@Test
@@ -1250,6 +1257,21 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
assertEquals(0, all.size());
}
+ @Test
+ public void testInvocationOfValidatorFetcher() throws IOException {
+
+ String encoded = loadResource("/r4/r4-caredove-bundle.json");
+
+ IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
+ when(resourceFetcher.validationPolicy(any(),anyString(), anyString())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
+ myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
+ myVal.validateWithResult(encoded);
+
+ verify(resourceFetcher, times(14)).resolveURL(any(), anyString(), anyString());
+ verify(resourceFetcher, times(12)).validationPolicy(any(), anyString(), anyString());
+ verify(resourceFetcher, times(12)).fetch(any(), anyString());
+ }
+
@Test
@Ignore
public void testValidateStructureDefinition() throws IOException {
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/QuestionnaireValidatorR4Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/QuestionnaireValidatorR4Test.java
index b6b88d44c15..ff872af31f4 100644
--- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/QuestionnaireValidatorR4Test.java
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r4/validation/QuestionnaireValidatorR4Test.java
@@ -23,6 +23,8 @@ import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.stream.Collectors;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
@@ -72,7 +74,7 @@ public class QuestionnaireValidatorR4Test {
ValidationResult errors = myVal.validateWithResult(q);
ourLog.info(errors.toString());
assertThat(errors.isSuccessful(), Matchers.is(true));
- assertThat(errors.getMessages(), Matchers.empty());
+ assertThat(errors.getMessages().stream().filter(t->t.getSeverity().ordinal() > ResultSeverityEnum.INFORMATION.ordinal()).collect(Collectors.toList()), Matchers.empty());
}
}
diff --git a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/FhirInstanceValidatorR5Test.java b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/FhirInstanceValidatorR5Test.java
index c9f23538e15..05a8e54e3ff 100644
--- a/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/FhirInstanceValidatorR5Test.java
+++ b/hapi-fhir-validation/src/test/java/org/hl7/fhir/r5/validation/FhirInstanceValidatorR5Test.java
@@ -53,9 +53,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.times;
public class FhirInstanceValidatorR5Test {
@@ -363,9 +364,7 @@ public class FhirInstanceValidatorR5Test {
}
- // FIXME: enable and change performed to occurrence
@Test
- @Ignore
public void testCompareTimesWithDifferentTimezones() {
Procedure procedure = new Procedure();
procedure.setStatus(Enumerations.EventStatus.COMPLETED);
@@ -417,6 +416,23 @@ public class FhirInstanceValidatorR5Test {
assertThat(nonInfo, empty());
}
+
+
+ @Test
+ public void testInvocationOfValidatorFetcher() throws IOException {
+
+ String input = IOUtils.toString(FhirInstanceValidator.class.getResourceAsStream("/vitals.json"), Charsets.UTF_8);
+
+ IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
+ when(resourceFetcher.validationPolicy(any(),anyString(), anyString())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
+ myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
+ myVal.validateWithResult(input);
+
+ verify(resourceFetcher, times(12)).resolveURL(any(), anyString(), anyString());
+ verify(resourceFetcher, times(3)).validationPolicy(any(), anyString(), anyString());
+ verify(resourceFetcher, times(3)).fetch(any(), anyString());
+ }
+
@Test
public void testIsNoTerminologyChecks() {
assertFalse(myInstanceVal.isNoTerminologyChecks());
@@ -776,7 +792,7 @@ public class FhirInstanceValidatorR5Test {
myInstanceVal.setValidationSupport(myMockSupport);
ValidationResult output = myVal.validateWithResult(input);
List errors = logResultsAndReturnNonInformationalOnes(output);
- assertThat(errors.toString(), containsString("StructureDefinition reference \"http://foo/structuredefinition/myprofile\" could not be resolved"));
+ assertThat(errors.toString(), containsString("Profile reference 'http://foo/structuredefinition/myprofile' could not be resolved, so has not been checked"));
}
@Test
diff --git a/hapi-fhir-validation/src/test/resources/r4/myconsent-ext.xml b/hapi-fhir-validation/src/test/resources/r4/myconsent-ext.xml
new file mode 100644
index 00000000000..2049e440b22
--- /dev/null
+++ b/hapi-fhir-validation/src/test/resources/r4/myconsent-ext.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hapi-fhir-validation/src/test/resources/r4/myconsent-profile.xml b/hapi-fhir-validation/src/test/resources/r4/myconsent-profile.xml
new file mode 100644
index 00000000000..0396797fe88
--- /dev/null
+++ b/hapi-fhir-validation/src/test/resources/r4/myconsent-profile.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hapi-fhir-validation/src/test/resources/vitals.json b/hapi-fhir-validation/src/test/resources/vitals.json
new file mode 100644
index 00000000000..78b3e733c6b
--- /dev/null
+++ b/hapi-fhir-validation/src/test/resources/vitals.json
@@ -0,0 +1,97 @@
+{
+ "resourceType": "Observation",
+ "id": "satO2",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/StructureDefinition/vitalsigns"
+ ]
+ },
+ "text": {
+ "status": "generated",
+ "div": "Generated Narrative with Details
id: satO2
meta:
identifier: o1223435-10
partOf: Procedure/ob
status: final
category: Vital Signs (Details : {http://terminology.hl7.org/CodeSystem/observation-category code 'vital-signs' = 'Vital Signs', given as 'Vital Signs'})
code: Oxygen saturation in Arterial blood (Details : {LOINC code '2708-6' = 'Oxygen saturation in Arterial blood', given as 'Oxygen saturation in Arterial blood'}; {LOINC code '59408-5' = 'Oxygen saturation in Arterial blood by Pulse oximetry', given as 'Oxygen saturation in Arterial blood by Pulse oximetry'}; {urn:iso:std:iso:11073:10101 code '150456' = '150456', given as 'MDC_PULS_OXIM_SAT_O2'})
subject: Patient/example
effective: Dec 5, 2014 9:30:10 AM
value: 95 % (Details: UCUM code % = '%')
interpretation: Normal (applies to non-numeric results) (Details : {http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation code 'N' = 'Normal', given as 'Normal'})
device: DeviceMetric/example
ReferenceRanges
- Low High * 90 % (Details: UCUM code % = '%') 99 % (Details: UCUM code % = '%')
"
+ },
+ "identifier": [
+ {
+ "system": "http://goodcare.org/observation/id",
+ "value": "o1223435-10"
+ }
+ ],
+ "partOf": [
+ {
+ "reference": "Procedure/ob"
+ }
+ ],
+ "status": "final",
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/observation-category",
+ "code": "vital-signs",
+ "display": "Vital Signs"
+ }
+ ],
+ "text": "Vital Signs"
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://loinc.org",
+ "code": "2708-6",
+ "display": "Oxygen saturation in Arterial blood"
+ },
+ {
+ "system": "http://loinc.org",
+ "code": "59408-5",
+ "display": "Oxygen saturation in Arterial blood by Pulse oximetry"
+ },
+ {
+ "system": "urn:iso:std:iso:11073:10101",
+ "code": "150456",
+ "display": "MDC_PULS_OXIM_SAT_O2"
+ }
+ ]
+ },
+ "subject": {
+ "reference": "Patient/example"
+ },
+ "effectiveDateTime": "2014-12-05T09:30:10+01:00",
+ "valueQuantity": {
+ "value": 95,
+ "unit": "%",
+ "system": "http://unitsofmeasure.org",
+ "code": "%"
+ },
+ "interpretation": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
+ "code": "N",
+ "display": "Normal"
+ }
+ ],
+ "text": "Normal (applies to non-numeric results)"
+ }
+ ],
+ "device": {
+ "reference": "DeviceMetric/example"
+ },
+ "referenceRange": [
+ {
+ "low": {
+ "value": 90,
+ "unit": "%",
+ "system": "http://unitsofmeasure.org",
+ "code": "%"
+ },
+ "high": {
+ "value": 99,
+ "unit": "%",
+ "system": "http://unitsofmeasure.org",
+ "code": "%"
+ }
+ }
+ ]
+}
diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml
index ec1362ebd4c..4caaad9f81f 100644
--- a/hapi-tinder-plugin/pom.xml
+++ b/hapi-tinder-plugin/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../pom.xml
@@ -58,37 +58,37 @@
ca.uhn.hapi.fhir
hapi-fhir-structures-dstu3
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-structures-hl7org-dstu2
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-structures-r4
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-structures-r5
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-validation-resources-dstu2
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-validation-resources-dstu3
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
ca.uhn.hapi.fhir
hapi-fhir-validation-resources-r4
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
org.apache.velocity
diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml
index 9e07aca1de0..55d2ca62a4f 100644
--- a/hapi-tinder-test/pom.xml
+++ b/hapi-tinder-test/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index 890013750e2..ef8d1092440 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-fhir
pom
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
HAPI-FHIR
An open-source implementation of the FHIR specification in Java.
https://hapifhir.io
@@ -590,6 +590,11 @@
dionmcm
+
+ ttntrifork
+ Trifork
+ Tue Toft Nørgård
+
@@ -601,7 +606,7 @@
- 4.1.42-SNAPSHOT
+ 4.2.1-SNAPSHOT
1.0.2
-Dfile.encoding=UTF-8 -Xmx2048m
@@ -1902,12 +1907,12 @@
org.apache.maven.plugins
maven-checkstyle-plugin
- 3.0.0
+ 3.1.0
com.puppycrawl.tools
checkstyle
- 8.18
+ 8.29
@@ -2555,6 +2560,30 @@
-Dfile.encoding=UTF-8 -Xmx2048m -XX:TieredStopAtLevel=1 -XX:+UseParallelGC -Xverify:none -Dfile.encoding=UTF-8 -Xss128M -XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=2048M
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+
+
+ validate
+ generate-sources
+
+ src/checkstyle/checkstyle_config_nofixmes.xml
+ UTF-8
+ true
+ true
+ false
+
+
+ check
+
+
+
+
+
+
NOPARALLEL
diff --git a/restful-server-example/pom.xml b/restful-server-example/pom.xml
index 69440e2adf4..4813953ee4a 100644
--- a/restful-server-example/pom.xml
+++ b/restful-server-example/pom.xml
@@ -8,7 +8,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../pom.xml
diff --git a/src/checkstyle/checkstyle_config_nofixmes.xml b/src/checkstyle/checkstyle_config_nofixmes.xml
new file mode 100644
index 00000000000..2fd2fc95aad
--- /dev/null
+++ b/src/checkstyle/checkstyle_config_nofixmes.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
index acc1aa4da1b..5c69d2bfd64 100644
--- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
+++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
index e2c2c0c28dc..f3a5689802a 100644
--- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
index 2b0fddd66ed..56809aad658 100644
--- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 4.2.0-SNAPSHOT
+ 4.3.0-SNAPSHOT
../../pom.xml