Skip to content

Commit

Permalink
7.6.0 Mergeback (#6494)
Browse files Browse the repository at this point in the history
* 6323 resource creation deadlock (#6324)

* make map reads concurrent

* change log

* CUstom version number for guaranteed build determinism

* licenses

* Expand translation cache (#6341)

* Expand translation cache

* Add changelog

* Correction to #6341 (#6342)

* Contained bug (#6402)

* Contained bug

* more tests

* changelog, tests, implementation

* code review

* backwards logic

* Fix Questionnaire doc (#6400)

* fix reindex optimizeStorage=ALL_VERSIONS (#6421)

* fixing broken rename of last step of reindex (#6429)

* Fixes for the translation of parameter issues as part of the output for $validate-code operation. (#6438)

* Move the validation providers to the test utilities package such that they can be reused.

* Update IValidationSupport.CodeValidationIssue structure such that it meets the FHIR specification. Update RemoteTerminologyServiceValidationSupport and VersionSpecificWorkerContextWrapper translation for issues.

* New tests for issue translation. Move test class to a different package so that we can add another test class.

* Some simplification in the issue API to simplify building of issues.

* Fix compilation errors.

* Update providers to allow multiple responses and add  support for the fetchCodeSystem call through method find.

* Setup the first test for resource validation with remote terminology providers.

* Fix NullPointerException

* avoid calling validateCode for CodeSystem where system is null

* Keep old public API methods (and class name) in IValidationSupport and mark them as deprecated to avoid breaking dependencies.

* Revert local change to debug for duplicate errors.

* Add more test cases for resource validation. Throw exception to signal missing test setup to make it obvious.

* Simplify test setup.

* Add some more javadoc

* Add javadoc for the new test class

* Add more tests

* Address code review comments in IValidationSupport.

* Add changelog

* Change Repository search interface from Map to Multimap (#6445)

Change Map to Multimap to support multiple and clauses.

* licenses

* fix interceptor hooks from requestDetails not getting called for STORAGE_PRECHECK_FOR_CACHED_SEARCH (#6436)

* fix interceptor hooks from requestDetails not getting called for STORAGE_PRECHECK_FOR_CACHED_SEARCH

* added unit tests and updated changelog

* added one more test case

* Add Adapter api (#6450)

Lightweight implementation of the adapter pattern.

* Bulk Import job status not changed after activation - failing test, fix, changelog (#6452)

* Update CR to 3.13.1 (#6433)

* Automated Migration Testing (HAPI-FHIR) - updated test migration scripts for 7_4_0 (#6439)

* Rel 7 6 CVE (#6446)

* Bump commons io

* Bump HS and Lucene, and hibernate

* Jetty bump for CVE

* Resolve CVES

* Bump with mismatch lucene

* Bump velocity template engine

* Revert bom bump

* wip

* Version bump

* move changelog, fix cve

* Bump commons-lang

* Replace imports

* wip

* fix HQL break

* remove dead code

* Fix changelog entry

* Bump org.hl7.fhir.core to 6.4.0 (#6454)

* Bump HAPI version + org.hl7.fhir.core to 6.4.0

* Apply spotless

* Correct a bug with duplicate parser IDs being assigned.  (#6456)

* Fix changelog entry

* wip

* compilation problem

* Correct tests

* changelog

* Update hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/parser/JsonParserR4Test.java

Co-authored-by: volodymyr-korzh <[email protected]>

* Correct a bug with duplicate parser IDs being assigned - test fixes

* Correct a bug with duplicate parser IDs being assigned - spotless

* Correct a bug with duplicate parser IDs being assigned - added test-utilities dependency to fhir-structures poms

* Correct a bug with duplicate parser IDs being assigned - test fixes

* Contained resources without assigned IDs are now assigned GUIDs - address comments

---------

Co-authored-by: volodymyr-korzh <[email protected]>
Co-authored-by: volodymyr <[email protected]>

* licenses

* ValueSet expansion fails if Hibernate Search configured to use Lucene - fixed incompatibility between Hibernate Search and Lucene versions (#6468)

* Change the migrator to avoid table locks when adding an index. (#6489)

* version bump

* Updating version to: 7.6.1 post release.

* Bump to 7.7.7.

* deadsapce

* Profile reference param (#6501)

* updated QueryStack to not throw error with _profile as a ReferenceParam

* update QueryStack

* remove warnings

* cleanup cast

* cleanup test

* add changelog

* cleanup imports

* updates per review feedback

* updates per review feedback

---------

Co-authored-by: [email protected] <[email protected]>

* move changelog

---------

Co-authored-by: JasonRoberts-smile <[email protected]>
Co-authored-by: James Agnew <[email protected]>
Co-authored-by: Brenin Rhodes <[email protected]>
Co-authored-by: Emre Dincturk <[email protected]>
Co-authored-by: TipzCM <[email protected]>
Co-authored-by: Martha Mitran <[email protected]>
Co-authored-by: Michael Buckley <[email protected]>
Co-authored-by: volodymyr-korzh <[email protected]>
Co-authored-by: dotasek <[email protected]>
Co-authored-by: volodymyr <[email protected]>
Co-authored-by: markiantorno <[email protected]>
Co-authored-by: Gary Graham <[email protected]>
Co-authored-by: Taha <[email protected]>
Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
15 people authored Nov 24, 2024
1 parent d4f1766 commit 86c2c13
Show file tree
Hide file tree
Showing 135 changed files with 3,794 additions and 1,041 deletions.

Large diffs are not rendered by default.

46 changes: 31 additions & 15 deletions hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/BaseParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ public abstract class BaseParser implements IParser {
private static final Set<String> notEncodeForContainedResource =
new HashSet<>(Arrays.asList("security", "versionId", "lastUpdated"));

private FhirTerser.ContainedResources myContainedResources;
private boolean myEncodeElementsAppliesToChildResourcesOnly;
private final FhirContext myContext;
private Collection<String> myDontEncodeElements;
Expand Down Expand Up @@ -183,12 +182,15 @@ protected Iterable<CompositeChildElement> compositeChildIterator(
}

private String determineReferenceText(
IBaseReference theRef, CompositeChildElement theCompositeChildElement, IBaseResource theResource) {
IBaseReference theRef,
CompositeChildElement theCompositeChildElement,
IBaseResource theResource,
EncodeContext theContext) {
IIdType ref = theRef.getReferenceElement();
if (isBlank(ref.getIdPart())) {
String reference = ref.getValue();
if (theRef.getResource() != null) {
IIdType containedId = getContainedResources().getResourceId(theRef.getResource());
IIdType containedId = theContext.getContainedResources().getResourceId(theRef.getResource());
if (containedId != null && !containedId.isEmpty()) {
if (containedId.isLocal()) {
reference = containedId.getValue();
Expand Down Expand Up @@ -262,7 +264,8 @@ public String encodeResourceToString(IBaseResource theResource) throws DataForma
@Override
public final void encodeResourceToWriter(IBaseResource theResource, Writer theWriter)
throws IOException, DataFormatException {
EncodeContext encodeContext = new EncodeContext(this, myContext.getParserOptions());
EncodeContext encodeContext =
new EncodeContext(this, myContext.getParserOptions(), new FhirTerser.ContainedResources());
encodeResourceToWriter(theResource, theWriter, encodeContext);
}

Expand All @@ -285,7 +288,8 @@ public void encodeToWriter(IBase theElement, Writer theWriter) throws DataFormat
} else if (theElement instanceof IPrimitiveType) {
theWriter.write(((IPrimitiveType<?>) theElement).getValueAsString());
} else {
EncodeContext encodeContext = new EncodeContext(this, myContext.getParserOptions());
EncodeContext encodeContext =
new EncodeContext(this, myContext.getParserOptions(), new FhirTerser.ContainedResources());
encodeToWriter(theElement, theWriter, encodeContext);
}
}
Expand Down Expand Up @@ -404,10 +408,6 @@ protected String getCompositeElementId(IBase theElement) {
return elementId;
}

FhirTerser.ContainedResources getContainedResources() {
return myContainedResources;
}

@Override
public Set<String> getDontStripVersionsFromReferencesAtPaths() {
return myDontStripVersionsFromReferencesAtPaths;
Expand Down Expand Up @@ -539,10 +539,11 @@ public boolean getSuppressNarratives() {
return mySuppressNarratives;
}

protected boolean isChildContained(BaseRuntimeElementDefinition<?> childDef, boolean theIncludedResource) {
protected boolean isChildContained(
BaseRuntimeElementDefinition<?> childDef, boolean theIncludedResource, EncodeContext theContext) {
return (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES
|| childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCE_LIST)
&& getContainedResources().isEmpty() == false
&& theContext.getContainedResources().isEmpty() == false
&& theIncludedResource == false;
}

Expand Down Expand Up @@ -788,7 +789,8 @@ protected List<? extends IBase> preProcessValues(
*/
if (next instanceof IBaseReference) {
IBaseReference nextRef = (IBaseReference) next;
String refText = determineReferenceText(nextRef, theCompositeChildElement, theResource);
String refText =
determineReferenceText(nextRef, theCompositeChildElement, theResource, theEncodeContext);
if (!StringUtils.equals(refText, nextRef.getReferenceElement().getValue())) {

if (retVal == theValues) {
Expand Down Expand Up @@ -980,7 +982,7 @@ protected boolean shouldEncodeResource(String theName, EncodeContext theEncodeCo
return true;
}

protected void containResourcesInReferences(IBaseResource theResource) {
protected void containResourcesInReferences(IBaseResource theResource, EncodeContext theContext) {

/*
* If a UUID is present in Bundle.entry.fullUrl but no value is present
Expand All @@ -1003,7 +1005,7 @@ protected void containResourcesInReferences(IBaseResource theResource) {
}
}

myContainedResources = getContext().newTerser().containResources(theResource);
theContext.setContainedResources(getContext().newTerser().containResources(theResource));
}

static class ChildNameAndDef {
Expand Down Expand Up @@ -1034,8 +1036,12 @@ class EncodeContext extends EncodeContextPath {
private final List<EncodeContextPath> myEncodeElementPaths;
private final Set<String> myEncodeElementsAppliesToResourceTypes;
private final List<EncodeContextPath> myDontEncodeElementPaths;
private FhirTerser.ContainedResources myContainedResources;

public EncodeContext(BaseParser theParser, ParserOptions theParserOptions) {
public EncodeContext(
BaseParser theParser,
ParserOptions theParserOptions,
FhirTerser.ContainedResources theContainedResources) {
Collection<String> encodeElements = theParser.myEncodeElements;
Collection<String> dontEncodeElements = theParser.myDontEncodeElements;
if (isSummaryMode()) {
Expand All @@ -1058,13 +1064,23 @@ public EncodeContext(BaseParser theParser, ParserOptions theParserOptions) {
dontEncodeElements.stream().map(EncodeContextPath::new).collect(Collectors.toList());
}

myContainedResources = theContainedResources;

myEncodeElementsAppliesToResourceTypes =
ParserUtil.determineApplicableResourceTypesForTerserPaths(myEncodeElementPaths);
}

private Map<Key, List<BaseParser.CompositeChildElement>> getCompositeChildrenCache() {
return myCompositeChildrenCache;
}

public FhirTerser.ContainedResources getContainedResources() {
return myContainedResources;
}

public void setContainedResources(FhirTerser.ContainedResources theContainedResources) {
myContainedResources = theContainedResources;
}
}

protected class CompositeChildElement {
Expand Down
15 changes: 10 additions & 5 deletions hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/JsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import ca.uhn.fhir.parser.json.jackson.JacksonStructure;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.FhirTerser;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.text.WordUtils;
Expand Down Expand Up @@ -386,12 +387,14 @@ public String toString() {
}
case CONTAINED_RESOURCE_LIST:
case CONTAINED_RESOURCES: {
List<IBaseResource> containedResources = getContainedResources().getContainedResources();
List<IBaseResource> containedResources =
theEncodeContext.getContainedResources().getContainedResources();
if (containedResources.size() > 0) {
beginArray(theEventWriter, theChildName);

for (IBaseResource next : containedResources) {
IIdType resourceId = getContainedResources().getResourceId(next);
IIdType resourceId =
theEncodeContext.getContainedResources().getResourceId(next);
String value = resourceId.getValue();
encodeResourceToJsonStreamWriter(
theResDef,
Expand Down Expand Up @@ -554,7 +557,8 @@ private void encodeCompositeElementChildrenToStreamWriter(

if (nextValue == null || nextValue.isEmpty()) {
if (nextValue instanceof BaseContainedDt) {
if (theContainedResource || getContainedResources().isEmpty()) {
if (theContainedResource
|| theEncodeContext.getContainedResources().isEmpty()) {
continue;
}
} else {
Expand Down Expand Up @@ -838,7 +842,8 @@ public void encodeResourceToJsonLikeWriter(IBaseResource theResource, BaseJsonLi
+ theResource.getStructureFhirVersionEnum());
}

EncodeContext encodeContext = new EncodeContext(this, getContext().getParserOptions());
EncodeContext encodeContext =
new EncodeContext(this, getContext().getParserOptions(), new FhirTerser.ContainedResources());
String resourceName = getContext().getResourceType(theResource);
encodeContext.pushPath(resourceName, true);
doEncodeResourceToJsonLikeWriter(theResource, theJsonLikeWriter, encodeContext);
Expand Down Expand Up @@ -894,7 +899,7 @@ private void encodeResourceToJsonStreamWriter(
}

if (!theContainedResource) {
containResourcesInReferences(theResource);
containResourcesInReferences(theResource, theEncodeContext);
}

RuntimeResourceDefinition resDef = getContext().getResourceDefinition(theResource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private Resource encodeResourceToRDFStreamWriter(
}

if (!containedResource) {
containResourcesInReferences(resource);
containResourcesInReferences(resource, encodeContext);
}

if (!(resource instanceof IAnyResource)) {
Expand Down Expand Up @@ -354,7 +354,7 @@ private Model encodeChildElementToStreamWriter(
try {

if (element == null || element.isEmpty()) {
if (!isChildContained(childDef, includedResource)) {
if (!isChildContained(childDef, includedResource, theEncodeContext)) {
return rdfModel;
}
}
Expand Down
10 changes: 6 additions & 4 deletions hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ private void encodeChildElementToStreamWriter(
try {

if (theElement == null || theElement.isEmpty()) {
if (isChildContained(childDef, theIncludedResource)) {
if (isChildContained(childDef, theIncludedResource, theEncodeContext)) {
// We still want to go in..
} else {
return;
Expand Down Expand Up @@ -359,8 +359,10 @@ private void encodeChildElementToStreamWriter(
* theEventWriter.writeStartElement("contained"); encodeResourceToXmlStreamWriter(next, theEventWriter, true, fixContainedResourceId(next.getId().getValue()));
* theEventWriter.writeEndElement(); }
*/
for (IBaseResource next : getContainedResources().getContainedResources()) {
IIdType resourceId = getContainedResources().getResourceId(next);
for (IBaseResource next :
theEncodeContext.getContainedResources().getContainedResources()) {
IIdType resourceId =
theEncodeContext.getContainedResources().getResourceId(next);
theEventWriter.writeStartElement("contained");
String value = resourceId.getValue();
encodeResourceToXmlStreamWriter(
Expand Down Expand Up @@ -682,7 +684,7 @@ private void encodeResourceToXmlStreamWriter(
}

if (!theContainedResource) {
containResourcesInReferences(theResource);
containResourcesInReferences(theResource, theEncodeContext);
}

theEventWriter.writeStartElement(resDef.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
import com.google.common.annotations.Beta;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseParameters;
Expand Down Expand Up @@ -231,6 +233,23 @@ <T extends IBaseResource, I extends IIdType> MethodOutcome delete(

// Querying starts here

/**
* Searches this repository
*
* @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a>
*
* @param <B> a Bundle type
* @param <T> a Resource type
* @param bundleType the class of the Bundle type to return
* @param resourceType the class of the Resource type to search
* @param searchParameters the searchParameters for this search
* @return a Bundle with the results of the search
*/
default <B extends IBaseBundle, T extends IBaseResource> B search(
Class<B> bundleType, Class<T> resourceType, Multimap<String, List<IQueryParameterType>> searchParameters) {
return this.search(bundleType, resourceType, searchParameters, Collections.emptyMap());
}

/**
* Searches this repository
*
Expand Down Expand Up @@ -264,9 +283,32 @@ default <B extends IBaseBundle, T extends IBaseResource> B search(
<B extends IBaseBundle, T extends IBaseResource> B search(
Class<B> bundleType,
Class<T> resourceType,
Map<String, List<IQueryParameterType>> searchParameters,
Multimap<String, List<IQueryParameterType>> searchParameters,
Map<String, String> headers);

/**
* Searches this repository
*
* @see <a href="https://www.hl7.org/fhir/http.html#search">FHIR search</a>
*
* @param <B> a Bundle type
* @param <T> a Resource type
* @param bundleType the class of the Bundle type to return
* @param resourceType the class of the Resource type to search
* @param searchParameters the searchParameters for this search
* @param headers headers for this request, typically key-value pairs of HTTP headers
* @return a Bundle with the results of the search
*/
default <B extends IBaseBundle, T extends IBaseResource> B search(
Class<B> bundleType,
Class<T> resourceType,
Map<String, List<IQueryParameterType>> searchParameters,
Map<String, String> headers) {
ArrayListMultimap<String, List<IQueryParameterType>> multimap = ArrayListMultimap.create();
searchParameters.forEach(multimap::put);
return this.search(bundleType, resourceType, multimap, headers);
}

// Paging starts here

/**
Expand Down
Loading

0 comments on commit 86c2c13

Please sign in to comment.