Skip to content

Commit 864250e

Browse files
authored
Add Bulk Patch and Bulk Patch Rewrite Jobs (#7186)
* Work on task * Work on reindex * Work on batch job * Add job * Work on feature * Job almost working * Tests passing * Compile fixes * Test fix * Build fix * Fix test issues * Formatting * Work on reindex * Test fixes * Disable bulk patch by default * Add xtensibility * Cleanup * Add changelog * Test fixes * Build fixes * Build fix * Add message code * Address review comments * Version bump * Add test utilities * Spotless
1 parent 08428f9 commit 864250e

File tree

159 files changed

+4938
-351
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+4938
-351
lines changed

hapi-deployable-pom/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>ca.uhn.hapi.fhir</groupId>
77
<artifactId>hapi-fhir</artifactId>
8-
<version>8.5.1-SNAPSHOT</version>
8+
<version>8.5.2-SNAPSHOT</version>
99

1010
<relativePath>../pom.xml</relativePath>
1111
</parent>

hapi-fhir-android/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>ca.uhn.hapi.fhir</groupId>
77
<artifactId>hapi-deployable-pom</artifactId>
8-
<version>8.5.1-SNAPSHOT</version>
8+
<version>8.5.2-SNAPSHOT</version>
99

1010
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
1111
</parent>

hapi-fhir-base/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>ca.uhn.hapi.fhir</groupId>
77
<artifactId>hapi-deployable-pom</artifactId>
8-
<version>8.5.1-SNAPSHOT</version>
8+
<version>8.5.2-SNAPSHOT</version>
99

1010
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
1111
</parent>

hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/ResourceGoneException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import org.hl7.fhir.instance.model.api.IIdType;
2828

2929
/**
30-
* Represents an <b>HTTP 410 Resource Gone</b> response, which geenerally
30+
* Represents an <b>HTTP 410 Resource Gone</b> response, which generally
3131
* indicates that the resource has been deleted
3232
*/
3333
@CoverageIgnore

hapi-fhir-base/src/main/java/ca/uhn/fhir/util/CanonicalBundleEntry.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import ca.uhn.fhir.context.FhirContext;
2525
import org.hl7.fhir.instance.model.api.IBase;
2626
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
27+
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
2728
import org.hl7.fhir.instance.model.api.IBaseResource;
2829
import org.hl7.fhir.instance.model.api.IPrimitiveType;
2930

@@ -61,6 +62,7 @@ public class CanonicalBundleEntry {
6162

6263
// Link fields (less common but part of spec)
6364
private List<Map<String, String>> myLinks;
65+
private IBaseOperationOutcome myResponseOutcome;
6466

6567
public CanonicalBundleEntry() {
6668
// Default constructor
@@ -186,6 +188,14 @@ public void setLinks(List<Map<String, String>> theLinks) {
186188
myLinks = theLinks;
187189
}
188190

191+
public void setResponseOutcome(IBaseOperationOutcome theResponseOutcome) {
192+
myResponseOutcome = theResponseOutcome;
193+
}
194+
195+
public IBaseOperationOutcome getResponseOutcome() {
196+
return myResponseOutcome;
197+
}
198+
189199
/**
190200
* Factory method to create a CanonicalBundleEntry from a Bundle Entry
191201
* @param theFhirContext The FHIR context
@@ -267,6 +277,12 @@ public static CanonicalBundleEntry fromBundleEntry(FhirContext theFhirContext, I
267277
if (lastModified != null) {
268278
retVal.setResponseLastModified(lastModified.getValueAsString());
269279
}
280+
281+
IBaseOperationOutcome outcome =
282+
terser.getSingleValueOrNull(response, "outcome", IBaseOperationOutcome.class);
283+
if (outcome != null) {
284+
retVal.setResponseOutcome(outcome);
285+
}
270286
}
271287

272288
// Extract search fields
@@ -453,6 +469,13 @@ public <T extends IBase> T toBundleEntry(FhirContext theFhirContext, Class<T> th
453469
lastModifiedChild.getMutator().setValue(response, lastModifiedValue);
454470
}
455471
}
472+
473+
if (myResponseOutcome != null) {
474+
BaseRuntimeChildDefinition outcomeChild = responseDef.getChildByName("outcome");
475+
if (outcomeChild != null) {
476+
outcomeChild.getMutator().setValue(response, myResponseOutcome);
477+
}
478+
}
456479
}
457480
}
458481

hapi-fhir-base/src/main/java/ca/uhn/fhir/util/OperationOutcomeUtil.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,28 @@ public class OperationOutcomeUtil {
5151
public static final String OO_SEVERITY_WARN = "warning";
5252
public static final String OO_ISSUE_CODE_INFORMATIONAL = "informational";
5353

54+
/**
55+
* Note: This code was added in FHIR R5, so the {@link #addIssue(FhirContext, IBaseOperationOutcome, String, String, String, String) addIssue}
56+
* methods here will automatically convert it to {@link #OO_ISSUE_CODE_INFORMATIONAL} for
57+
* previous versions of FHIR.
58+
*
59+
* @since 8.6.0
60+
*/
61+
public static final String OO_ISSUE_CODE_SUCCESS = "success";
62+
63+
/**
64+
* @since 8.6.0
65+
*/
66+
public static final String OO_ISSUE_CODE_PROCESSING = "processing";
67+
5468
/**
5569
* Add an issue to an OperationOutcome
5670
*
5771
* @param theCtx The fhir context
5872
* @param theOperationOutcome The OO resource to add to
5973
* @param theSeverity The severity (fatal | error | warning | information)
6074
* @param theDiagnostics The diagnostics string (this was called "details" in FHIR DSTU2 but was renamed to diagnostics in DSTU3)
61-
* @param theCode
75+
* @param theCode A code, such as {@link #OO_ISSUE_CODE_INFORMATIONAL} or {@link #OO_ISSUE_CODE_SUCCESS}
6276
* @return Returns the newly added issue
6377
*/
6478
public static IBase addIssue(
@@ -221,7 +235,13 @@ private static void populateDetails(
221235
BaseRuntimeChildDefinition codeChild = issueElement.getChildByName("code");
222236
IPrimitiveType<?> codeElem = (IPrimitiveType<?>)
223237
codeChild.getChildByName("code").newInstance(codeChild.getInstanceConstructorArguments());
224-
codeElem.setValueAsString(theCode);
238+
String code = theCode;
239+
if (theCtx.getVersion().getVersion().isOlderThan(FhirVersionEnum.R5) && "success".equals(code)) {
240+
// "success" was added in R5 so we switch back to "informational" for older versions
241+
code = "informational";
242+
}
243+
244+
codeElem.setValueAsString(code);
225245
codeChild.getMutator().addValue(theIssue, codeElem);
226246

227247
BaseRuntimeElementDefinition<?> stringDef = diagnosticsChild.getChildByName(diagnosticsChild.getElementName());

hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ParametersUtil.java

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import ca.uhn.fhir.i18n.Msg;
2828
import ca.uhn.fhir.model.api.annotation.Description;
2929
import ca.uhn.fhir.model.primitive.StringDt;
30+
import com.google.common.collect.Multimap;
31+
import com.google.common.collect.MultimapBuilder;
3032
import jakarta.annotation.Nullable;
3133
import org.apache.commons.lang3.Validate;
3234
import org.hl7.fhir.instance.model.api.IBase;
@@ -46,10 +48,11 @@
4648
import java.util.List;
4749
import java.util.Objects;
4850
import java.util.Optional;
51+
import java.util.function.BiConsumer;
4952
import java.util.function.Function;
50-
import java.util.stream.Collectors;
5153

5254
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
55+
import static org.apache.commons.lang3.StringUtils.defaultString;
5356
import static org.apache.commons.lang3.StringUtils.isBlank;
5457

5558
/**
@@ -137,27 +140,54 @@ public static Optional<IBase> getNamedParameter(
137140
.findFirst();
138141
}
139142

143+
/**
144+
* Returns a map containing all of the named parameters in a Parameters resource. The key will be the
145+
* <code>Parameters.parameter.name</code> value (or an empty string <code>""</code> if no name is present)
146+
* and the value will be the <code>Parameters.parameter</code> repetition.
147+
*
148+
* @param theCtx The FhirContext instance appropriate for the input
149+
* @param theParameters The Parameters resource to examine
150+
* @return A map containing named parameters
151+
* @since 8.4.0
152+
*/
153+
public static Multimap<String, IBase> getNamedParameters(FhirContext theCtx, IBaseResource theParameters) {
154+
Multimap<String, IBase> retVal =
155+
MultimapBuilder.hashKeys().arrayListValues().build();
156+
BiConsumer<String, IBase> consumer = (paramName, part) -> {
157+
paramName = defaultString(paramName);
158+
retVal.put(paramName, part);
159+
};
160+
161+
getNamedParameters(theCtx, theParameters, consumer);
162+
163+
return retVal;
164+
}
165+
140166
public static List<IBase> getNamedParameters(
141167
FhirContext theCtx, IBaseResource theParameters, String theParameterName) {
168+
List<IBase> retVal = new ArrayList<>();
169+
BiConsumer<String, IBase> consumer = (paramName, part) -> {
170+
if (theParameterName.equals(paramName)) {
171+
retVal.add(part);
172+
}
173+
};
174+
175+
getNamedParameters(theCtx, theParameters, consumer);
176+
177+
return retVal;
178+
}
179+
180+
private static void getNamedParameters(
181+
FhirContext theCtx, IBaseResource theParameters, BiConsumer<String, IBase> theConsumer) {
142182
Validate.notNull(theParameters, "theParameters must not be null");
143-
RuntimeResourceDefinition resDef = theCtx.getResourceDefinition(theParameters.getClass());
144-
BaseRuntimeChildDefinition parameterChild = resDef.getChildByName("parameter");
145-
List<IBase> parameterReps = parameterChild.getAccessor().getValues(theParameters);
146-
147-
return parameterReps.stream()
148-
.filter(param -> {
149-
BaseRuntimeElementCompositeDefinition<?> nextParameterDef =
150-
(BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(param.getClass());
151-
BaseRuntimeChildDefinition nameChild = nextParameterDef.getChildByName("name");
152-
List<IBase> nameValues = nameChild.getAccessor().getValues(param);
153-
Optional<? extends IPrimitiveType<?>> nameValue = nameValues.stream()
154-
.filter(t -> t instanceof IPrimitiveType<?>)
155-
.map(t -> ((IPrimitiveType<?>) t))
156-
.findFirst();
157-
return nameValue.isPresent()
158-
&& theParameterName.equals(nameValue.get().getValueAsString());
159-
})
160-
.collect(Collectors.toList());
183+
184+
FhirTerser terser = theCtx.newTerser();
185+
List<IBase> parameterReps = terser.getValues(theParameters, "parameter");
186+
187+
for (IBase parameter : parameterReps) {
188+
String name = terser.getSinglePrimitiveValueOrNull(parameter, "name");
189+
theConsumer.accept(name, parameter);
190+
}
161191
}
162192

163193
public static Optional<IBase> getParameterPart(FhirContext theCtx, IBase theParameter, String theParameterName) {

hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.cantUndeleteWithDeletesDisabled=Unable to re
9292
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request
9393
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlInvalidResourceType=Invalid match URL "{0}" - Unknown resource type: "{1}"
9494
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.resourceTypeAndFhirIdConflictAcrossPartitions=Failed to create/update resource [{0}/{1}] in partition {2} because a resource of the same type and ID is found in another partition
95+
ca.uhn.fhir.jpa.dao.BaseStorageDao.updateWithHistoryRewriteDisabled=Update with history rewrite is not supported on this server
9596
ca.uhn.fhir.jpa.dao.BaseStorageDao.invalidMatchUrlNoMatches=Invalid match URL "{0}" - No resources match this search
9697
ca.uhn.fhir.jpa.dao.BaseStorageDao.invalidMatchUrlCantUseForAutoCreatePlaceholder=Invalid match URL "{0}" - No resources match this search and the URL is not valid for automatic placeholder reference target creation
9798
ca.uhn.fhir.jpa.dao.BaseStorageDao.inlineMatchNotSupported=Inline match URLs are not supported on this server. Cannot process reference: "{0}"
@@ -165,6 +166,7 @@ ca.uhn.fhir.jpa.search.builder.QueryStack.cantSortOnCoordParamWithoutValues=Can
165166
ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder.invalidCodeMissingSystem=Invalid token specified for parameter {0} - No system specified: {1}|{2}
166167
ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder.invalidCodeMissingCode=Invalid token specified for parameter {0} - No code specified: {1}|{2}
167168

169+
168170
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.matchesFound=Matches found
169171
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.noMatchesFound=No Matches found
170172
ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl.onlyNegativeMatchesFound=Only negative matches found

hapi-fhir-bom/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>ca.uhn.hapi.fhir</groupId>
66
<artifactId>hapi-fhir-bom</artifactId>
7-
<version>8.5.1-SNAPSHOT</version>
7+
<version>8.5.2-SNAPSHOT</version>
88

99
<packaging>pom</packaging>
1010
<name>HAPI FHIR BOM</name>
1111

1212
<parent>
1313
<groupId>ca.uhn.hapi.fhir</groupId>
1414
<artifactId>hapi-deployable-pom</artifactId>
15-
<version>8.5.1-SNAPSHOT</version>
15+
<version>8.5.2-SNAPSHOT</version>
1616

1717
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
1818
</parent>

hapi-fhir-checkstyle/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>ca.uhn.hapi.fhir</groupId>
77
<artifactId>hapi-fhir</artifactId>
8-
<version>8.5.1-SNAPSHOT</version>
8+
<version>8.5.2-SNAPSHOT</version>
99

1010
<relativePath>../pom.xml</relativePath>
1111
</parent>

0 commit comments

Comments
 (0)