diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java index eb2dbba07f9..91a622301cd 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java @@ -32,9 +32,11 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.function.Supplier; import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -77,9 +79,9 @@ public interface IValidationSupport { * Expands the given portion of a ValueSet * * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. - * @param theExpansionOptions If provided (may be null), contains options controlling the expansion - * @param theValueSetToExpand The valueset that should be expanded + * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. + * @param theExpansionOptions If provided (may be null), contains options controlling the expansion + * @param theValueSetToExpand The valueset that should be expanded * @return The expansion, or null */ default ValueSetExpansionOutcome expandValueSet(ValidationSupportContext theValidationSupportContext, @Nullable ValueSetExpansionOptions theExpansionOptions, @Nonnull IBaseResource theValueSetToExpand) { @@ -116,15 +118,33 @@ public interface IValidationSupport { * Loads a resource needed by the validation (a StructureDefinition, or a * ValueSet) * - * @param theClass The type of the resource to load + *

+ * Note: Since 5.3.0, {@literal theClass} can be {@literal null} + *

+ * + * @param theClass The type of the resource to load, or null to return any resource with the given canonical URI * @param theUri The resource URI * @return Returns the resource, or null if no resource with the * given URI can be found */ - default T fetchResource(Class theClass, String theUri) { - Validate.notNull(theClass, "theClass must not be null or blank"); + @SuppressWarnings("unchecked") + default T fetchResource(@Nullable Class theClass, String theUri) { Validate.notBlank(theUri, "theUri must not be null or blank"); + if (theClass == null) { + Supplier[] sources = new Supplier[]{ + () -> fetchStructureDefinition(theUri), + () -> fetchValueSet(theUri), + () -> fetchCodeSystem(theUri) + }; + return (T) Arrays + .stream(sources) + .map(t -> t.get()) + .filter(t -> t != null) + .findFirst() + .orElse(null); + } + switch (getFhirContext().getResourceType(theClass)) { case "StructureDefinition": return theClass.cast(fetchStructureDefinition(theUri)); @@ -150,8 +170,8 @@ public interface IValidationSupport { * or validated * * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. - * @param theSystem The URI for the code system, e.g. "http://loinc.org" + * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. + * @param theSystem The URI for the code system, e.g. "http://loinc.org" * @return Returns true if codes in the given code system can be * validated */ @@ -172,11 +192,11 @@ public interface IValidationSupport { * binding fields (e.g. Observation.code in the default profile. * * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. - * @param theOptions Provides options controlling the validation - * @param theCodeSystem The code system, e.g. "http://loinc.org" - * @param theCode The code, e.g. "1234-5" - * @param theDisplay The display name, if it should also be validated + * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. + * @param theOptions Provides options controlling the validation + * @param theCodeSystem The code system, e.g. "http://loinc.org" + * @param theCode The code, e.g. "1234-5" + * @param theDisplay The display name, if it should also be validated * @return Returns a validation result object */ default CodeValidationResult validateCode(ValidationSupportContext theValidationSupportContext, ConceptValidationOptions theOptions, String theCodeSystem, String theCode, String theDisplay, String theValueSetUrl) { @@ -189,11 +209,11 @@ public interface IValidationSupport { * binding fields (e.g. Observation.code in the default profile. * * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. - * @param theCodeSystem The code system, e.g. "http://loinc.org" - * @param theCode The code, e.g. "1234-5" - * @param theDisplay The display name, if it should also be validated - * @param theValueSet The ValueSet to validate against. Must not be null, and must be a ValueSet resource. + * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. + * @param theCodeSystem The code system, e.g. "http://loinc.org" + * @param theCode The code, e.g. "1234-5" + * @param theDisplay The display name, if it should also be validated + * @param theValueSet The ValueSet to validate against. Must not be null, and must be a ValueSet resource. * @return Returns a validation result object, or null if this validation support module can not handle this kind of request */ default CodeValidationResult validateCodeInValueSet(ValidationSupportContext theValidationSupportContext, ConceptValidationOptions theOptions, String theCodeSystem, String theCode, String theDisplay, @Nonnull IBaseResource theValueSet) { @@ -204,9 +224,9 @@ public interface IValidationSupport { * Look up a code using the system and code value * * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. - * @param theSystem The CodeSystem URL - * @param theCode The code + * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. + * @param theSystem The CodeSystem URL + * @param theCode The code */ default LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { return null; @@ -217,8 +237,8 @@ public interface IValidationSupport { * validation support module * * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. - * @param theValueSetUrl The ValueSet canonical URL + * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. + * @param theValueSetUrl The ValueSet canonical URL */ default boolean isValueSetSupported(ValidationSupportContext theValidationSupportContext, String theValueSetUrl) { return false; @@ -228,7 +248,7 @@ public interface IValidationSupport { * Generate a snapshot from the given differential profile. * * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to - * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. + * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. * @return Returns null if this module does not know how to handle this request */ default IBaseResource generateSnapshot(ValidationSupportContext theValidationSupportContext, IBaseResource theInput, String theUrl, String theWebUrl, String theProfileName) { @@ -249,6 +269,25 @@ public interface IValidationSupport { } + enum IssueSeverity { + /** + * The issue caused the action to fail, and no further checking could be performed. + */ + FATAL, + /** + * The issue is sufficiently important to cause the action to fail. + */ + ERROR, + /** + * The issue is not important enough to cause the action to fail, but may cause it to be performed suboptimally or in a way that is not as desired. + */ + WARNING, + /** + * The issue has no relation to the degree of success of the action. + */ + INFORMATION + } + class ConceptDesignation { private String myLanguage; private String myUseSystem; @@ -365,25 +404,6 @@ public interface IValidationSupport { } } - enum IssueSeverity { - /** - * The issue caused the action to fail, and no further checking could be performed. - */ - FATAL, - /** - * The issue is sufficiently important to cause the action to fail. - */ - ERROR, - /** - * The issue is not important enough to cause the action to fail, but may cause it to be performed suboptimally or in a way that is not as desired. - */ - WARNING, - /** - * The issue has no relation to the degree of success of the action. - */ - INFORMATION - } - class CodeValidationResult { private String myCode; private String myMessage; diff --git a/hapi-fhir-docs/src/test/java/ca/uhn/hapi/fhir/docs/ChangelogFilesTest.java b/hapi-fhir-docs/src/test/java/ca/uhn/hapi/fhir/docs/ChangelogFilesTest.java index 399d889bfa3..579982577ce 100644 --- a/hapi-fhir-docs/src/test/java/ca/uhn/hapi/fhir/docs/ChangelogFilesTest.java +++ b/hapi-fhir-docs/src/test/java/ca/uhn/hapi/fhir/docs/ChangelogFilesTest.java @@ -66,6 +66,9 @@ public class ChangelogFilesTest { // this one is optional boolean haveIssue = fieldNames.remove("issue"); + // this one is optional + fieldNames.remove("backport"); + assertThat("Invalid element in " + next + ": " + fieldNames, fieldNames, empty()); if (haveIssue) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/binstore/FilesystemBinaryStorageSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/binstore/FilesystemBinaryStorageSvcImpl.java index 8ac6b6ace81..07648601c5b 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/binstore/FilesystemBinaryStorageSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/binstore/FilesystemBinaryStorageSvcImpl.java @@ -32,11 +32,11 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.CountingInputStream; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IIdType; -import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.annotation.PostConstruct; import java.io.*; import java.util.Date; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index d5ad689a154..04c29943127 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -103,8 +103,6 @@ import org.hl7.fhir.instance.model.api.IBaseParameters; 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 org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Required; import org.springframework.data.domain.SliceImpl; @@ -539,7 +537,7 @@ public abstract class BaseHapiFhirResourceDao extends B return myDeleteExpungeService.expungeByResourcePids(theUrl, myResourceName, new SliceImpl<>(ResourcePersistentId.toLongList(theResourceIds)), theTheRequest); } - @NotNull + @Nonnull @Override public DeleteMethodOutcome deletePidList(String theUrl, Collection theResourceIds, DeleteConflictList theDeleteConflicts, RequestDetails theRequest) { StopWatch w = new StopWatch(); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java index 51e5f2dc559..a5a89c5a84a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FulltextSearchSvcImpl.java @@ -20,54 +20,34 @@ package ca.uhn.fhir.jpa.dao; * #L% */ -import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.dao.data.IForcedIdDao; import ca.uhn.fhir.jpa.dao.index.IdHelperService; import ca.uhn.fhir.jpa.model.config.PartitionSettings; -import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.TokenParam; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.Validate; -import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.search.highlight.Formatter; -import org.apache.lucene.search.highlight.Highlighter; -import org.apache.lucene.search.highlight.Scorer; -import org.apache.lucene.search.highlight.TextFragment; -import org.apache.lucene.search.highlight.TokenGroup; -import org.hibernate.search.backend.lucene.index.LuceneIndexManager; import org.hibernate.search.engine.search.predicate.dsl.BooleanPredicateClausesStep; import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory; -import org.hibernate.search.engine.search.query.SearchQuery; import org.hibernate.search.mapper.orm.Search; -import org.hibernate.search.mapper.orm.mapping.SearchMapping; import org.hibernate.search.mapper.orm.session.SearchSession; import org.hl7.fhir.instance.model.api.IAnyResource; -import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionTemplate; +import javax.annotation.Nonnull; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContextType; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -76,20 +56,20 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; public class FulltextSearchSvcImpl implements IFulltextSearchSvc { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FulltextSearchSvcImpl.class); - - @PersistenceContext(type = PersistenceContextType.TRANSACTION) - private EntityManager myEntityManager; - - @Autowired - private PlatformTransactionManager myTxManager; - @Autowired protected IForcedIdDao myForcedIdDao; - + @PersistenceContext(type = PersistenceContextType.TRANSACTION) + private EntityManager myEntityManager; + @Autowired + private PlatformTransactionManager myTxManager; @Autowired private IdHelperService myIdHelperService; private Boolean ourDisabled; + @Autowired + private IRequestPartitionHelperSvc myRequestPartitionHelperService; + @Autowired + private PartitionSettings myPartitionSettings; /** * Constructor @@ -98,28 +78,28 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc { super(); } - private void addTextSearch(SearchPredicateFactory f, BooleanPredicateClausesStep b, List> theTerms, String theFieldName, String theFieldNameEdgeNGram, String theFieldNameTextNGram){ + private void addTextSearch(SearchPredicateFactory f, BooleanPredicateClausesStep b, List> theTerms, String theFieldName, String theFieldNameEdgeNGram, String theFieldNameTextNGram) { if (theTerms == null) { return; } for (List nextAnd : theTerms) { Set terms = extractOrStringParams(nextAnd); - if (terms.size() == 1) { - b.must(f.phrase() - .field(theFieldName) - .boost(4.0f) - .matching(terms.iterator().next().toLowerCase()) - .slop(2)); - } else if (terms.size() > 1){ - String joinedTerms = StringUtils.join(terms, ' '); - b.must(f.match().field(theFieldName).matching(joinedTerms)); - } else { - ourLog.debug("No Terms found in query parameter {}", nextAnd); - } + if (terms.size() == 1) { + b.must(f.phrase() + .field(theFieldName) + .boost(4.0f) + .matching(terms.iterator().next().toLowerCase()) + .slop(2)); + } else if (terms.size() > 1) { + String joinedTerms = StringUtils.join(terms, ' '); + b.must(f.match().field(theFieldName).matching(joinedTerms)); + } else { + ourLog.debug("No Terms found in query parameter {}", nextAnd); } } + } - @NotNull + @Nonnull private Set extractOrStringParams(List nextAnd) { Set terms = new HashSet<>(); for (IQueryParameterType nextOr : nextAnd) { @@ -229,10 +209,4 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc { return doSearch(theResourceName, theParams, null); } - @Autowired - private IRequestPartitionHelperSvc myRequestPartitionHelperService; - - @Autowired - private PartitionSettings myPartitionSettings; - } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java index c5e177d7e45..d3a1fe2adf1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/JpaPersistedResourceValidationSupport.java @@ -46,9 +46,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Nullable; import javax.annotation.PostConstruct; import javax.transaction.Transactional; +import java.util.Arrays; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import static org.apache.commons.lang3.StringUtils.isBlank; @@ -104,110 +107,13 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport @Override @SuppressWarnings({"unchecked", "unused"}) - public T fetchResource(Class theClass, String theUri) { + public T fetchResource(@Nullable Class theClass, String theUri) { if (isBlank(theUri)) { return null; } - String key = theClass.getSimpleName() + " " + theUri; - IBaseResource fetched = myLoadCache.get(key, t -> { - IdType id = new IdType(theUri); - boolean localReference = false; - if (id.hasBaseUrl() == false && id.hasIdPart() == true) { - localReference = true; - } - - String resourceName = myFhirContext.getResourceType(theClass); - IBundleProvider search; - switch (resourceName) { - case "ValueSet": - if (localReference) { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronousUpTo(1); - params.add(IAnyResource.SP_RES_ID, new StringParam(theUri)); - search = myDaoRegistry.getResourceDao(resourceName).search(params); - if (search.size() == 0) { - params = new SearchParameterMap(); - params.setLoadSynchronousUpTo(1); - params.add(ValueSet.SP_URL, new UriParam(theUri)); - search = myDaoRegistry.getResourceDao(resourceName).search(params); - } - } else { - int versionSeparator = theUri.lastIndexOf('|'); - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronousUpTo(1); - if (versionSeparator != -1) { - params.add(ValueSet.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1))); - params.add(ValueSet.SP_URL, new UriParam(theUri.substring(0, versionSeparator))); - } else { - params.add(ValueSet.SP_URL, new UriParam(theUri)); - } - params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC)); - search = myDaoRegistry.getResourceDao(resourceName).search(params); - } - break; - case "StructureDefinition": { - // Don't allow the core FHIR definitions to be overwritten - if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) { - String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length()); - if (myFhirContext.getElementDefinition(typeName) != null) { - return myNoMatch; - } - } - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronousUpTo(1); - params.add(StructureDefinition.SP_URL, new UriParam(theUri)); - search = myDaoRegistry.getResourceDao("StructureDefinition").search(params); - break; - } - case "Questionnaire": { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronousUpTo(1); - if (localReference || myFhirContext.getVersion().getVersion().isEquivalentTo(FhirVersionEnum.DSTU2)) { - params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart())); - } else { - params.add(Questionnaire.SP_URL, new UriParam(id.getValue())); - } - search = myDaoRegistry.getResourceDao("Questionnaire").search(params); - break; - } - case "CodeSystem": { - int versionSeparator = theUri.lastIndexOf('|'); - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronousUpTo(1); - if (versionSeparator != -1) { - params.add(CodeSystem.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1))); - params.add(CodeSystem.SP_URL, new UriParam(theUri.substring(0, versionSeparator))); - } else { - params.add(CodeSystem.SP_URL, new UriParam(theUri)); - } - params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC)); - search = myDaoRegistry.getResourceDao(resourceName).search(params); - break; - } - case "ImplementationGuide": - case "SearchParameter": { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronousUpTo(1); - params.add(ImplementationGuide.SP_URL, new UriParam(theUri)); - search = myDaoRegistry.getResourceDao(resourceName).search(params); - break; - } - default: - throw new IllegalArgumentException("Can't fetch resource type: " + resourceName); - } - - Integer size = search.size(); - if (size == null || size == 0) { - return myNoMatch; - } - - if (size > 1) { - ourLog.warn("Found multiple {} instances with URL search value of: {}", resourceName, theUri); - } - - return search.getResources(0, 1).get(0); - }); + String key = theClass + " " + theUri; + IBaseResource fetched = myLoadCache.get(key, t -> doFetchResource(theClass, theUri)); if (fetched == myNoMatch) { return null; @@ -216,6 +122,119 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport return (T) fetched; } + private IBaseResource doFetchResource(@Nullable Class theClass, String theUri) { + if (theClass == null) { + Supplier[] fetchers = new Supplier[]{ + () -> doFetchResource(ValueSet.class, theUri), + () -> doFetchResource(CodeSystem.class, theUri), + () -> doFetchResource(StructureDefinition.class, theUri) + }; + return Arrays + .stream(fetchers) + .map(t -> t.get()) + .filter(t -> t != myNoMatch) + .findFirst() + .orElse(myNoMatch); + } + + IdType id = new IdType(theUri); + boolean localReference = false; + if (id.hasBaseUrl() == false && id.hasIdPart() == true) { + localReference = true; + } + + String resourceName = myFhirContext.getResourceType(theClass); + IBundleProvider search; + switch (resourceName) { + case "ValueSet": + if (localReference) { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronousUpTo(1); + params.add(IAnyResource.SP_RES_ID, new StringParam(theUri)); + search = myDaoRegistry.getResourceDao(resourceName).search(params); + if (search.size() == 0) { + params = new SearchParameterMap(); + params.setLoadSynchronousUpTo(1); + params.add(ValueSet.SP_URL, new UriParam(theUri)); + search = myDaoRegistry.getResourceDao(resourceName).search(params); + } + } else { + int versionSeparator = theUri.lastIndexOf('|'); + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronousUpTo(1); + if (versionSeparator != -1) { + params.add(ValueSet.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1))); + params.add(ValueSet.SP_URL, new UriParam(theUri.substring(0, versionSeparator))); + } else { + params.add(ValueSet.SP_URL, new UriParam(theUri)); + } + params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC)); + search = myDaoRegistry.getResourceDao(resourceName).search(params); + } + break; + case "StructureDefinition": { + // Don't allow the core FHIR definitions to be overwritten + if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) { + String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length()); + if (myFhirContext.getElementDefinition(typeName) != null) { + return myNoMatch; + } + } + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronousUpTo(1); + params.add(StructureDefinition.SP_URL, new UriParam(theUri)); + search = myDaoRegistry.getResourceDao("StructureDefinition").search(params); + break; + } + case "Questionnaire": { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronousUpTo(1); + if (localReference || myFhirContext.getVersion().getVersion().isEquivalentTo(FhirVersionEnum.DSTU2)) { + params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart())); + } else { + params.add(Questionnaire.SP_URL, new UriParam(id.getValue())); + } + search = myDaoRegistry.getResourceDao("Questionnaire").search(params); + break; + } + case "CodeSystem": { + int versionSeparator = theUri.lastIndexOf('|'); + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronousUpTo(1); + if (versionSeparator != -1) { + params.add(CodeSystem.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1))); + params.add(CodeSystem.SP_URL, new UriParam(theUri.substring(0, versionSeparator))); + } else { + params.add(CodeSystem.SP_URL, new UriParam(theUri)); + } + params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC)); + search = myDaoRegistry.getResourceDao(resourceName).search(params); + break; + } + case "ImplementationGuide": + case "SearchParameter": { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronousUpTo(1); + params.add(ImplementationGuide.SP_URL, new UriParam(theUri)); + search = myDaoRegistry.getResourceDao(resourceName).search(params); + break; + } + default: + throw new IllegalArgumentException("Can't fetch resource type: " + resourceName); + } + + Integer size = search.size(); + if (size == null || size == 0) { + return myNoMatch; + } + + if (size > 1) { + ourLog.warn("Found multiple {} instances with URL search value of: {}", resourceName, theUri); + } + + return search.getResources(0, 1).get(0); + } + @Override public FhirContext getFhirContext() { return myFhirContext; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/partition/PartitionManagementProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/partition/PartitionManagementProvider.java index e148a42d6ea..ce5d66f0a6f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/partition/PartitionManagementProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/partition/PartitionManagementProvider.java @@ -29,9 +29,10 @@ import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.util.ParametersUtil; import org.hl7.fhir.instance.model.api.IBaseParameters; import org.hl7.fhir.instance.model.api.IPrimitiveType; -import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Nonnull; + import static ca.uhn.fhir.jpa.partition.PartitionLookupSvcImpl.validatePartitionIdSupplied; import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.hl7.fhir.instance.model.api.IPrimitiveType.toValueOrNull; @@ -151,7 +152,7 @@ public class PartitionManagementProvider { return retVal; } - @NotNull + @Nonnull private PartitionEntity parseInput(@OperationParam(name = ProviderConstants.PARTITION_MANAGEMENT_PARTITION_ID, min = 1, max = 1, typeName = "integer") IPrimitiveType thePartitionId, @OperationParam(name = ProviderConstants.PARTITION_MANAGEMENT_PARTITION_NAME, min = 1, max = 1, typeName = "code") IPrimitiveType thePartitionName, @OperationParam(name = ProviderConstants.PARTITION_MANAGEMENT_PARTITION_DESC, min = 0, max = 1, typeName = "string") IPrimitiveType thePartitionDescription) { PartitionEntity input = new PartitionEntity(); if (thePartitionId != null) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java index a6f27c7c177..8d1f45b35cf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java @@ -52,7 +52,6 @@ import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import com.google.common.annotations.VisibleForTesting; import org.hl7.fhir.instance.model.api.IBaseResource; -import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -191,7 +190,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider { return retVal; } - @NotNull + @Nonnull private RequestPartitionId getRequestPartitionId() { if (myRequestPartitionId == null) { if (mySearchEntity.getResourceId() != null) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java index 6878a1d2934..80328cf2f73 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java @@ -576,7 +576,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc { return null; } - @org.jetbrains.annotations.Nullable + @Nullable private Integer getLoadSynchronousUpToOrNull(CacheControlDirective theCacheControlDirective) { final Integer loadSynchronousUpTo; if (theCacheControlDirective != null && theCacheControlDirective.isNoStore()) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/ValidatorResourceFetcher.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/ValidatorResourceFetcher.java index 9255acd1496..df30c410d11 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/ValidatorResourceFetcher.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/ValidatorResourceFetcher.java @@ -32,13 +32,13 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.JsonParser; +import org.hl7.fhir.r5.model.CanonicalResource; import org.hl7.fhir.r5.utils.IResourceValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import javax.annotation.PostConstruct; -import java.io.IOException; import java.util.Locale; public class ValidatorResourceFetcher implements IResourceValidator.IValidatorResourceFetcher { @@ -61,7 +61,6 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe } - @SuppressWarnings("ConstantConditions") @Override public Element fetch(Object appContext, String theUrl) throws FHIRException { @@ -94,13 +93,13 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe } @Override - public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException { + public boolean resolveURL(Object appContext, String path, String url, String type) throws FHIRException { return true; } @Override - public byte[] fetchRaw(String url) throws IOException { - return new byte[0]; + public byte[] fetchRaw(String url) { + throw new UnsupportedOperationException(); } @Override @@ -108,4 +107,14 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe // ignore } + @Override + public CanonicalResource fetchCanonicalResource(String url) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean fetchesCanonicalResource(String url) { + return false; + } + } 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 cc6897acf1f..6b3ab511fe9 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 @@ -144,7 +144,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test { } catch (PreconditionFailedException e) { String ooString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()); ourLog.info(ooString); - assertThat(ooString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' could not be resolved, so has not been checked")); + assertThat(ooString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown")); } } 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 8b50cd2c2ed..ab04c07c46f 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 @@ -333,7 +333,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test { OperationOutcome oo = (OperationOutcome) e.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")); + assertThat(outputString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown")); } } 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 06e7d516992..72b16b4d25f 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 @@ -1138,7 +1138,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { org.hl7.fhir.r4.model.OperationOutcome oo = (org.hl7.fhir.r4.model.OperationOutcome) e.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")); + assertThat(outputString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown")); } } @@ -1174,7 +1174,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { org.hl7.fhir.r4.model.OperationOutcome oo = (org.hl7.fhir.r4.model.OperationOutcome) e.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")); + assertThat(outputString, containsString("Profile reference 'http://example.com/StructureDefinition/testValidateResourceContainingProfileDeclarationInvalid' has not been checked because it is unknown")); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/partition/PartitionManagementProviderTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/partition/PartitionManagementProviderTest.java index ab609103900..ad02f5fc22a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/partition/PartitionManagementProviderTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/partition/PartitionManagementProviderTest.java @@ -12,7 +12,6 @@ import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r4.model.IntegerType; import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.StringType; -import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,6 +27,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import javax.annotation.Nonnull; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; @@ -87,7 +88,7 @@ public class PartitionManagementProviderTest { assertEquals("a description", ((StringType) response.getParameter(ProviderConstants.PARTITION_MANAGEMENT_PARTITION_DESC)).getValue()); } - @NotNull + @Nonnull private Parameters createInputPartition() { Parameters input = new Parameters(); input.addParameter(ProviderConstants.PARTITION_MANAGEMENT_PARTITION_ID, new IntegerType(123)); @@ -248,7 +249,7 @@ public class PartitionManagementProviderTest { } - @NotNull + @Nonnull private static Answer createAnswer() { return t -> t.getArgument(0, PartitionEntity.class); } 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 cb2f52d307c..f4f6e2852eb 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 @@ -2403,7 +2403,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { String respString = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8); ourLog.info(respString); assertEquals(412, resp.getStatusLine().getStatusCode()); - assertThat(respString, containsString("Profile reference 'http://foo/structuredefinition/myprofile' could not be resolved, so has not been checked")); + assertThat(respString, containsString("Profile reference 'http://foo/structuredefinition/myprofile' has not been checked because it is unknown")); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/config/TestElasticsearchContainerHelper.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/config/TestElasticsearchContainerHelper.java index 6e5d708406c..ba85d2ee77f 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/config/TestElasticsearchContainerHelper.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/lastn/config/TestElasticsearchContainerHelper.java @@ -14,7 +14,7 @@ import static java.time.temporal.ChronoUnit.SECONDS; public class TestElasticsearchContainerHelper { - public static final String ELASTICSEARCH_VERSION = "7.10.0"; + public static final String ELASTICSEARCH_VERSION = "7.10.2"; public static final String ELASTICSEARCH_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch:" + ELASTICSEARCH_VERSION; public static ElasticsearchContainer getEmbeddedElasticSearch() { diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmControllerSvcImpl.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmControllerSvcImpl.java index 824e6ffd237..bc02474ac35 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmControllerSvcImpl.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmControllerSvcImpl.java @@ -20,23 +20,23 @@ package ca.uhn.fhir.jpa.mdm.svc; * #L% */ -import ca.uhn.fhir.mdm.api.MdmLinkJson; -import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; -import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; +import ca.uhn.fhir.mdm.api.IGoldenResourceMergerSvc; import ca.uhn.fhir.mdm.api.IMdmControllerSvc; import ca.uhn.fhir.mdm.api.IMdmLinkQuerySvc; import ca.uhn.fhir.mdm.api.IMdmLinkUpdaterSvc; -import ca.uhn.fhir.mdm.api.IGoldenResourceMergerSvc; +import ca.uhn.fhir.mdm.api.MdmLinkJson; +import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; +import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.provider.MdmControllerHelper; import ca.uhn.fhir.mdm.provider.MdmControllerUtil; import ca.uhn.fhir.rest.server.provider.ProviderConstants; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IIdType; -import org.jetbrains.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.annotation.Nullable; import java.util.stream.Stream; /** diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmResourceDaoSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmResourceDaoSvc.java index 8e0743ba846..9d3ea9e66d9 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmResourceDaoSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmResourceDaoSvc.java @@ -20,23 +20,23 @@ package ca.uhn.fhir.jpa.mdm.svc; * #L% */ -import ca.uhn.fhir.mdm.api.MdmConstants; -import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.model.entity.TagTypeEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.mdm.api.IMdmSettings; +import ca.uhn.fhir.mdm.api.MdmConstants; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; -import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.annotation.Nonnull; import java.util.List; import java.util.Optional; @@ -60,10 +60,11 @@ public class MdmResourceDaoSvc { } /** - * Given a resource, remove its Golden Resource tag. - * @param theGoldenResource the {@link IAnyResource} to remove the tag from. - * @param theResourcetype the type of that resource - */ + * Given a resource, remove its Golden Resource tag. + * + * @param theGoldenResource the {@link IAnyResource} to remove the tag from. + * @param theResourcetype the type of that resource + */ public void removeGoldenResourceTag(IAnyResource theGoldenResource, String theResourcetype) { IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourcetype); resourceDao.removeTag(theGoldenResource.getIdElement(), TagTypeEnum.TAG, MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD); @@ -99,7 +100,7 @@ public class MdmResourceDaoSvc { } } - @NotNull + @Nonnull private SearchParameterMap buildEidSearchParameterMap(String theTheEid) { SearchParameterMap map = new SearchParameterMap(); map.setLoadSynchronous(true); diff --git a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java index 4d3eb16ea80..4245c859123 100644 --- a/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java +++ b/hapi-fhir-jpaserver-mdm/src/test/java/ca/uhn/fhir/jpa/mdm/BaseMdmR4Test.java @@ -48,7 +48,6 @@ import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Reference; -import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; @@ -431,7 +430,7 @@ abstract public class BaseMdmR4Test extends BaseJpaR4Test { return getPatientsByTag(MdmConstants.CODE_GOLDEN_RECORD_REDIRECTED); } - @NotNull + @Nonnull private List getPatientsByTag(String theCode) { SearchParameterMap map = new SearchParameterMap(); map.setLoadSynchronous(true); diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java index 5b2c76f32fd..e693ad81e95 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java +++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/BaseTableColumnTypeTask.java @@ -23,7 +23,8 @@ package ca.uhn.fhir.jpa.migrate.taskdef; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nullable; public abstract class BaseTableColumnTypeTask extends BaseTableColumnTask { private ColumnTypeEnum myColumnType; diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/FhirPathFilterInterceptorTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/FhirPathFilterInterceptorTest.java index 07459ede46a..4f675fc6ac3 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/FhirPathFilterInterceptorTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/interceptor/FhirPathFilterInterceptorTest.java @@ -13,6 +13,7 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -95,6 +96,19 @@ public class FhirPathFilterInterceptorTest { } + @Test + public void testFilteredResponse_ExpressionReturnsExtension() throws IOException { + createPatient(); + + HttpGet request = new HttpGet(myPatientId + "?_fhirpath=Patient.extension('http://hl7.org/fhir/us/core/StructureDefinition/us-core-race')&_pretty=true"); + try (CloseableHttpResponse response = myHttpClient.execute(request)) { + String responseText = IOUtils.toString(response.getEntity().getContent(), Charsets.UTF_8); + ourLog.info("Response:\n{}", responseText); + assertThat(responseText, containsString("\"url\": \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-race\"")); + } + + } + @Test public void testFilteredResponse_ExpressionReturnsResource() throws IOException { createPatient(); @@ -159,6 +173,11 @@ public class FhirPathFilterInterceptorTest { private void createPatient() { Patient p = new Patient(); + p.addExtension() + .setUrl("http://hl7.org/fhir/us/core/StructureDefinition/us-core-race") + .addExtension() + .setUrl("ombCategory") + .setValue(new Coding("urn:oid:2.16.840.1.113883.6.238", "2106-3", "White")); p.setActive(true); p.addIdentifier().setSystem("http://identifiers/1").setValue("value-1"); p.addIdentifier().setSystem("http://identifiers/2").setValue("value-2"); diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index 845f4fe330f..8c25c08f45e 100644 --- a/hapi-fhir-structures-r5/pom.xml +++ b/hapi-fhir-structures-r5/pom.xml @@ -107,7 +107,7 @@ @@ -133,6 +133,11 @@ gson true + + org.jetbrains + annotations + true + @@ -181,12 +186,12 @@ thymeleaf test - - ca.uhn.hapi.fhir - hapi-fhir-test-utilities - ${project.version} - test - + + ca.uhn.hapi.fhir + hapi-fhir-test-utilities + ${project.version} + test + @@ -209,16 +214,6 @@ jaxb-api test - - - - - - - - - - org.glassfish.jaxb jaxb-runtime @@ -344,13 +339,13 @@ true - <_nouses>true - <_removeheaders>Built-By, Include-Resource, Private-Package, Require-Capability - + <_nouses>true + <_removeheaders>Built-By, Include-Resource, Private-Package, Require-Capability + 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 b0da9754b83..52fe6b9e482 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 @@ -287,6 +287,11 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext return myCtx.getVersion().getVersion().getFhirVersionString(); } + @Override + public String getSpecUrl() { + throw new UnsupportedOperationException(); + } + @Override public UcumService getUcumService() { throw new UnsupportedOperationException(); @@ -302,6 +307,11 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext return false; } + @Override + public Set getCodeSystemsUsed() { + throw new UnsupportedOperationException(); + } + @Override public TranslationServices translator() { throw new UnsupportedOperationException(); diff --git a/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/fhirpath/FhirPathR5.java b/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/fhirpath/FhirPathR5.java index d82be431bc1..1e8d3de7dc8 100644 --- a/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/fhirpath/FhirPathR5.java +++ b/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/fhirpath/FhirPathR5.java @@ -30,9 +30,9 @@ public class FhirPathR5 implements IFhirPath { result = myEngine.evaluate((Base) theInput, thePath); } catch (FHIRException e) { throw new FhirPathExecutionException(e); - } + } - for (Base next : result) { + for (Base next : result) { if (!theReturnType.isAssignableFrom(next.getClass())) { throw new FhirPathExecutionException("FluentPath expression \"" + thePath + "\" returned unexpected type " + next.getClass().getSimpleName() + " - Expected " + theReturnType.getName()); } diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java index 829b9977ad7..b6515f00d64 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/CachingValidationSupport.java @@ -6,14 +6,13 @@ import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.ValidationSupportContext; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -64,8 +63,8 @@ public class CachingValidationSupport extends BaseValidationSupportWrapper imple } @Override - public T fetchResource(Class theClass, String theUri) { - return loadFromCache(myCache, "fetchResource " + theClass.getName() + " " + theUri, + public T fetchResource(@Nullable Class theClass, String theUri) { + return loadFromCache(myCache, "fetchResource " + theClass + " " + theUri, t -> super.fetchResource(theClass, theUri)); } diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FhirInstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FhirInstanceValidator.java index 8b8175683d9..f673e2fda01 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FhirInstanceValidator.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/FhirInstanceValidator.java @@ -32,7 +32,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta private boolean noExtensibleWarnings = false; private boolean noBindingMsgSuppressed = false; private volatile VersionSpecificWorkerContextWrapper myWrappedWorkerContext; - private boolean errorForUnknownProfiles; + private boolean errorForUnknownProfiles = true; private boolean assumeValidRestReferences; private List myExtensionDomains = Collections.emptyList(); private IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher; diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/HapiToHl7OrgDstu2ValidatingSupportWrapper.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/HapiToHl7OrgDstu2ValidatingSupportWrapper.java index 743d3dfaf1c..922f1f4c328 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/HapiToHl7OrgDstu2ValidatingSupportWrapper.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/HapiToHl7OrgDstu2ValidatingSupportWrapper.java @@ -61,6 +61,9 @@ public class HapiToHl7OrgDstu2ValidatingSupportWrapper extends BaseValidationSup } private Class translateTypeToHapi(Class theCodeSystemType) { + if (theCodeSystemType == null) { + return null; + } String resName = getFhirContext().getResourceType(theCodeSystemType); return myHapiCtx.getResourceDefinition(resName).getImplementingClass(); } diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidatorWrapper.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidatorWrapper.java index 33817480b03..8c0614cab5b 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidatorWrapper.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/ValidatorWrapper.java @@ -17,6 +17,7 @@ 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.XVerExtensionManager; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.instance.InstanceValidator; import org.slf4j.Logger; @@ -103,8 +104,9 @@ class ValidatorWrapper { public List validate(IWorkerContext theWorkerContext, IValidationContext theValidationContext) { InstanceValidator v; FHIRPathEngine.IEvaluationContext evaluationCtx = new FhirInstanceValidator.NullEvaluationContext(); + XVerExtensionManager xverManager = new XVerExtensionManager(theWorkerContext); try { - v = new InstanceValidator(theWorkerContext, evaluationCtx); + v = new InstanceValidator(theWorkerContext, evaluationCtx, xverManager); } catch (Exception e) { throw new ConfigurationException(e); } @@ -193,7 +195,12 @@ class ValidatorWrapper { i--; } - if (message.endsWith("' could not be resolved, so has not been checked") && next.getLevel() == ValidationMessage.IssueSeverity.WARNING) { + if ( + myErrorForUnknownProfiles && + next.getLevel() == ValidationMessage.IssueSeverity.WARNING && + message.contains("Profile reference '") && + message.contains("' has not been checked because it is unknown") + ) { next.setLevel(ValidationMessage.IssueSeverity.ERROR); } diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java index 30d79928b53..72269d6e3da 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java @@ -81,13 +81,15 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo fetchResourceName = "ValueSet"; } } - Class fetchResourceType = myValidationSupportContext.getRootValidationSupport().getFhirContext().getResourceDefinition(fetchResourceName).getImplementingClass(); - IBaseResource fetched = myValidationSupportContext.getRootValidationSupport().fetchResource(fetchResourceType, key.getUri()); - if (fetched == null) { - return null; + Class fetchResourceType; + if (fetchResourceName.equals("Resource")) { + fetchResourceType = null; + } else { + fetchResourceType = myValidationSupportContext.getRootValidationSupport().getFhirContext().getResourceDefinition(fetchResourceName).getImplementingClass(); } + IBaseResource fetched = myValidationSupportContext.getRootValidationSupport().fetchResource(fetchResourceType, key.getUri()); Resource canonical = myModelConverter.toCanonical(fetched); @@ -425,6 +427,11 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo return myValidationSupportContext.getRootValidationSupport().getFhirContext().getVersion().getVersion().getFhirVersionString(); } + @Override + public String getSpecUrl() { + throw new UnsupportedOperationException(); + } + @Override public boolean hasCache() { throw new UnsupportedOperationException(); @@ -440,6 +447,11 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo return false; } + @Override + public Set getCodeSystemsUsed() { + throw new UnsupportedOperationException(); + } + @Override public List listTransforms() { throw new UnsupportedOperationException(); 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 f6f7fff31b7..e954e526591 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 @@ -664,6 +664,8 @@ public class FhirInstanceValidatorDstu3Test { } else if (t.getMessage().contains("ValueSet as a URI SHALL start with http:// or https:// or urn:")) { // Some DSTU3 structures have missing binding information return false; + } else if (t.getMessage().contains("The valueSet reference http://www.rfc-editor.org/bcp/bcp13.txt on element")) { + return false; } else { return true; } @@ -1135,7 +1137,7 @@ public class FhirInstanceValidatorDstu3Test { myInstanceVal.setValidationSupport(myValidationSupport); ValidationResult output = myVal.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); - assertThat(errors.toString(), containsString("Profile reference 'http://foo/structuredefinition/myprofile' could not be resolved, so has not been checked")); + assertThat(errors.toString(), containsString("Profile reference 'http://foo/structuredefinition/myprofile' has not been checked because it is unknown")); } @Test @@ -1314,7 +1316,7 @@ public class FhirInstanceValidatorDstu3Test { myInstanceVal.setValidatorResourceFetcher(resourceFetcher); myVal.validateWithResult(input); - verify(resourceFetcher, times(3)).resolveURL(any(), anyString(), anyString()); + verify(resourceFetcher, times(3)).resolveURL(any(), anyString(), anyString(), anyString()); verify(resourceFetcher, times(4)).validationPolicy(any(), anyString(), anyString()); verify(resourceFetcher, times(4)).fetch(any(), anyString()); } 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 b514e0c311f..19634f234e8 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 @@ -254,7 +254,7 @@ public class QuestionnaireResponseValidatorDstu3Test { errors = myVal.validateWithResult(qa); errors = stripBindingHasNoSourceMessage(errors); ourLog.info(errors.toString()); - assertThat(errors.toString(), containsString("Unknown code: http://codesystems.com/system / code1 - QuestionnaireResponse.item[0].answer[0].value.ofType(Coding)")); + assertThat(errors.toString(), containsString("Unknown code: http://codesystems.com/system / code1 for 'http://codesystems.com/system#code1'")); assertThat(errors.toString(), containsString("QuestionnaireResponse.item[0].answer[0]")); // Unhandled system 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 3d5c728fced..53f066dce92 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 @@ -1152,7 +1152,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { List errors = logResultsAndReturnNonInformationalOnes(output); assertEquals(1, errors.size()); - assertEquals("Profile reference 'http://foo/structuredefinition/myprofile' could not be resolved, so has not been checked", errors.get(0).getMessage()); + assertEquals("Profile reference 'http://foo/structuredefinition/myprofile' has not been checked because it is unknown", errors.get(0).getMessage()); assertEquals(ResultSeverityEnum.ERROR, errors.get(0).getSeverity()); } @@ -1402,7 +1402,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest { myInstanceVal.setValidatorResourceFetcher(resourceFetcher); myVal.validateWithResult(encoded); - verify(resourceFetcher, times(15)).resolveURL(any(), anyString(), anyString()); + verify(resourceFetcher, times(15)).resolveURL(any(), anyString(), anyString(), anyString()); verify(resourceFetcher, times(12)).validationPolicy(any(), anyString(), anyString()); verify(resourceFetcher, times(12)).fetch(any(), anyString()); } 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 6c58df50ffa..f6e17f0bf65 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 @@ -432,8 +432,8 @@ public class FhirInstanceValidatorR5Test { myInstanceVal.setValidatorResourceFetcher(resourceFetcher); myVal.validateWithResult(input); - verify(resourceFetcher, times(13)).resolveURL(any(), anyString(), anyString()); - verify(resourceFetcher, times(3)).validationPolicy(any(), anyString(), anyString()); + verify(resourceFetcher, times(13)).resolveURL(any(), anyString(), anyString(), anyString()); + verify(resourceFetcher, times(4)).validationPolicy(any(), anyString(), anyString()); verify(resourceFetcher, times(3)).fetch(any(), anyString()); } @@ -794,7 +794,7 @@ public class FhirInstanceValidatorR5Test { myInstanceVal.setValidationSupport(myValidationSupport); ValidationResult output = myVal.validateWithResult(input); List errors = logResultsAndReturnNonInformationalOnes(output); - assertThat(errors.toString(), containsString("Profile reference 'http://foo/structuredefinition/myprofile' could not be resolved, so has not been checked")); + assertThat(errors.toString(), containsString("Profile reference 'http://foo/structuredefinition/myprofile' has not been checked because it is unknown")); } @Test diff --git a/pom.xml b/pom.xml index 142adf8cf1f..fe1062d7e26 100644 --- a/pom.xml +++ b/pom.xml @@ -712,7 +712,7 @@ - 5.2.0 + 5.2.16 1.0.3 -Dfile.encoding=UTF-8 -Xmx2048m @@ -1462,7 +1462,7 @@ org.elasticsearch.client elasticsearch-rest-high-level-client - 7.10.0 + 7.10.2 org.hibernate.search