diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml
index 13c42a4c169..98fce3781df 100644
--- a/hapi-deployable-pom/pom.xml
+++ b/hapi-deployable-pom/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml
index b608304bf75..3ee44897a36 100644
--- a/hapi-fhir-android/pom.xml
+++ b/hapi-fhir-android/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml
index 7efab562751..238de5c736e 100644
--- a/hapi-fhir-base/pom.xml
+++ b/hapi-fhir-base/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/system/HapiSystemProperties.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/system/HapiSystemProperties.java
index f2353c589cb..f6f964c5ab6 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/system/HapiSystemProperties.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/system/HapiSystemProperties.java
@@ -110,6 +110,9 @@ public final class HapiSystemProperties {
public static void enableUnitTestMode() {
System.setProperty(UNIT_TEST_MODE, Boolean.TRUE.toString());
}
+ public static void disableUnitTestMode() {
+ System.setProperty(UNIT_TEST_MODE, Boolean.FALSE.toString());
+ }
public static boolean isUnitTestModeEnabled() {
return Boolean.parseBoolean(System.getProperty(UNIT_TEST_MODE));
diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml
index 685f217a71d..11359cf12bd 100644
--- a/hapi-fhir-bom/pom.xml
+++ b/hapi-fhir-bom/pom.xml
@@ -4,14 +4,14 @@
4.0.0
ca.uhn.hapi.fhir
hapi-fhir-bom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
pom
HAPI FHIR BOM
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml
index 2d82b431677..e44d69c040b 100644
--- a/hapi-fhir-checkstyle/pom.xml
+++ b/hapi-fhir-checkstyle/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml
index e5134147557..b5fedea1476 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml
+++ b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml
index e022220fafc..09d207d0c43 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml
+++ b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-fhir-cli
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml
index 56d723b3627..5483d2a1eee 100644
--- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml
+++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../hapi-deployable-pom
diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml
index 383225ef44b..4f0881ba65b 100644
--- a/hapi-fhir-cli/pom.xml
+++ b/hapi-fhir-cli/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml
index 64accdc8a2b..dcd7b55a23d 100644
--- a/hapi-fhir-client-okhttp/pom.xml
+++ b/hapi-fhir-client-okhttp/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml
index d5fd74d63f0..28dedf1bae3 100644
--- a/hapi-fhir-client/pom.xml
+++ b/hapi-fhir-client/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml
index 785131e6e11..1c474cc4d90 100644
--- a/hapi-fhir-converter/pom.xml
+++ b/hapi-fhir-converter/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml
index 33ad5b4d949..6a6ff8d5029 100644
--- a/hapi-fhir-dist/pom.xml
+++ b/hapi-fhir-dist/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml
index 393d7c578d7..4aff8bf6685 100644
--- a/hapi-fhir-docs/pom.xml
+++ b/hapi-fhir-docs/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_4_0/4065-batch2-fasttracking-configurable.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_4_0/4065-batch2-fasttracking-configurable.yaml
new file mode 100644
index 00000000000..51de9aaa93f
--- /dev/null
+++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_4_0/4065-batch2-fasttracking-configurable.yaml
@@ -0,0 +1,8 @@
+---
+type: change
+issue: 4065
+title: "A new DaoConfig configuration setting has been added called JobFastTrackingEnabled, default false.
+If this setting is enabled, then gated batch jobs that produce only one chunk will immediately trigger a batch
+maintenance job. This may be useful for testing, but is not recommended for production use. Prior to this change,
+fasttracking was always enabled which meant if the server was not busy, small batch jobs would be processed quickly.
+However this lead do instability on high-volume servers, so this feature is now disabled by default."
diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml
index 3857bcec9ae..20dcdf60c48 100644
--- a/hapi-fhir-jacoco/pom.xml
+++ b/hapi-fhir-jacoco/pom.xml
@@ -11,7 +11,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml
index 6c9618eb577..35782cc514b 100644
--- a/hapi-fhir-jaxrsserver-base/pom.xml
+++ b/hapi-fhir-jaxrsserver-base/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml
index d289d26726e..39e79330c70 100644
--- a/hapi-fhir-jpa/pom.xml
+++ b/hapi-fhir-jpa/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
4.0.0
diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml
index a936a3b8d0f..83e456520dc 100644
--- a/hapi-fhir-jpaserver-base/pom.xml
+++ b/hapi-fhir-jpaserver-base/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/PackageLoaderConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/PackageLoaderConfig.java
index 8e9cd954006..fc1cea1bd77 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/PackageLoaderConfig.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/PackageLoaderConfig.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.config;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.packages.loader.PackageLoaderSvc;
import ca.uhn.fhir.jpa.packages.loader.PackageResourceParsingSvc;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/NpmPackageData.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/NpmPackageData.java
index 28862b48e8e..f0284f3250c 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/NpmPackageData.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/NpmPackageData.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.packages.loader;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import org.hl7.fhir.utilities.npm.NpmPackage;
import java.io.InputStream;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageLoaderSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageLoaderSvc.java
index 6e75efab79d..ac7b900ebec 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageLoaderSvc.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageLoaderSvc.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.packages.loader;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.packages.PackageInstallationSpec;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageResourceParsingSvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageResourceParsingSvc.java
index 03bcb6fd062..be1898a3a65 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageResourceParsingSvc.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/loader/PackageResourceParsingSvc.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.packages.loader;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/util/PackageUtils.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/util/PackageUtils.java
index d3abbd6e9ba..5fce8092bec 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/util/PackageUtils.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/util/PackageUtils.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.packages.util;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import com.google.common.collect.Lists;
import java.util.Collections;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/IMemberMatchConsentHook.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/IMemberMatchConsentHook.java
index 921296a951f..fa2e2bbc9ae 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/IMemberMatchConsentHook.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/IMemberMatchConsentHook.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.provider.r4;
+/*-
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.function.Consumer;
diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
index 392b1493eae..b2d12cc1f49 100644
--- a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
+++ b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml
index 102a96c0411..0b5779874c8 100644
--- a/hapi-fhir-jpaserver-mdm/pom.xml
+++ b/hapi-fhir-jpaserver-mdm/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml
index f5d868393df..5f4dd6f399d 100644
--- a/hapi-fhir-jpaserver-model/pom.xml
+++ b/hapi-fhir-jpaserver-model/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml
index 527ee877eb4..46d039ff753 100755
--- a/hapi-fhir-jpaserver-searchparam/pom.xml
+++ b/hapi-fhir-jpaserver-searchparam/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml
index a837f8426d2..35ba7c0c17e 100644
--- a/hapi-fhir-jpaserver-subscription/pom.xml
+++ b/hapi-fhir-jpaserver-subscription/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-dstu2/pom.xml b/hapi-fhir-jpaserver-test-dstu2/pom.xml
index 002e8a74496..a0616c421e5 100644
--- a/hapi-fhir-jpaserver-test-dstu2/pom.xml
+++ b/hapi-fhir-jpaserver-test-dstu2/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml
index 023665dc876..2c8b18941c3 100644
--- a/hapi-fhir-jpaserver-test-dstu3/pom.xml
+++ b/hapi-fhir-jpaserver-test-dstu3/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml
index 0609821f294..b8c8f24ab30 100644
--- a/hapi-fhir-jpaserver-test-r4/pom.xml
+++ b/hapi-fhir-jpaserver-test-r4/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java
index 976c633973e..372448608d6 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2CoordinatorIT.java
@@ -174,7 +174,7 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
IJobStepWorker firstStep = (step, sink) -> callLatch(myFirstStepLatch, step);
IJobStepWorker lastStep = (step, sink) -> fail();
- String jobId = "test-job-1";
+ String jobId = new Exception().getStackTrace()[0].getMethodName();
JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobId, firstStep, lastStep);
myJobDefinitionRegistry.addJobDefinition(definition);
@@ -326,12 +326,12 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
};
IJobStepWorker lastStep = (step, sink) -> callLatch(myLastStepLatch, step);
- String jobId = "test-job-5";
- JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobId, firstStep, lastStep);
+ String jobDefId = new Exception().getStackTrace()[0].getMethodName();
+ JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobDefId, firstStep, lastStep);
myJobDefinitionRegistry.addJobDefinition(definition);
- JobInstanceStartRequest request = buildRequest(jobId);
+ JobInstanceStartRequest request = buildRequest(jobDefId);
myFirstStepLatch.setExpectedCount(1);
Batch2JobStartResponse startResponse = myJobCoordinator.startInstance(request);
@@ -355,12 +355,12 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
};
IJobStepWorker lastStep = (step, sink) -> fail();
- String jobId = "test-job-3";
- JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobId, firstStep, lastStep);
+ String jobDefId = new Exception().getStackTrace()[0].getMethodName();
+ JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobDefId, firstStep, lastStep);
myJobDefinitionRegistry.addJobDefinition(definition);
- JobInstanceStartRequest request = buildRequest(jobId);
+ JobInstanceStartRequest request = buildRequest(jobDefId);
// execute
Batch2JobStartResponse startResponse = myJobCoordinator.startInstance(request);
@@ -379,12 +379,12 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
};
IJobStepWorker lastStep = (step, sink) -> fail();
- String jobId = "test-job-4";
- JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobId, firstStep, lastStep);
+ String jobDefId = new Exception().getStackTrace()[0].getMethodName();
+ JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobDefId, firstStep, lastStep);
myJobDefinitionRegistry.addJobDefinition(definition);
- JobInstanceStartRequest request = buildRequest(jobId);
+ JobInstanceStartRequest request = buildRequest(jobDefId);
// execute
myFirstStepLatch.setExpectedCount(1);
@@ -418,9 +418,9 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
return RunOutcome.SUCCESS;
};
// job definition
- String jobId = new Exception().getStackTrace()[0].getMethodName();
+ String jobDefId = new Exception().getStackTrace()[0].getMethodName();
JobDefinition extends IModelJson> jd = JobDefinition.newBuilder()
- .setJobDefinitionId(jobId)
+ .setJobDefinitionId(jobDefId)
.setJobDescription("test job")
.setJobDefinitionVersion(TEST_JOB_VERSION)
.setParametersType(TestJobParameters.class)
@@ -439,7 +439,7 @@ public class Batch2CoordinatorIT extends BaseJpaR4Test {
.build();
myJobDefinitionRegistry.addJobDefinition(jd);
// test
- JobInstanceStartRequest request = buildRequest(jobId);
+ JobInstanceStartRequest request = buildRequest(jobDefId);
myFirstStepLatch.setExpectedCount(1);
Batch2JobStartResponse response = myJobCoordinator.startInstance(request);
JobInstance instance = myBatch2JobHelper.awaitJobHasStatus(response.getJobId(),
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2JobMaintenanceIT.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2JobMaintenanceIT.java
new file mode 100644
index 00000000000..6d549b18cd2
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/batch2/Batch2JobMaintenanceIT.java
@@ -0,0 +1,253 @@
+package ca.uhn.fhir.jpa.batch2;
+
+import ca.uhn.fhir.batch2.api.IJobCompletionHandler;
+import ca.uhn.fhir.batch2.api.IJobCoordinator;
+import ca.uhn.fhir.batch2.api.IJobMaintenanceService;
+import ca.uhn.fhir.batch2.api.IJobPersistence;
+import ca.uhn.fhir.batch2.api.IJobStepWorker;
+import ca.uhn.fhir.batch2.api.RunOutcome;
+import ca.uhn.fhir.batch2.api.StepExecutionDetails;
+import ca.uhn.fhir.batch2.api.VoidModel;
+import ca.uhn.fhir.batch2.coordinator.JobDefinitionRegistry;
+import ca.uhn.fhir.batch2.maintenance.JobMaintenanceServiceImpl;
+import ca.uhn.fhir.batch2.model.JobDefinition;
+import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
+import ca.uhn.fhir.batch2.model.JobWorkNotificationJsonMessage;
+import ca.uhn.fhir.jpa.subscription.channel.api.ChannelConsumerSettings;
+import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory;
+import ca.uhn.fhir.jpa.subscription.channel.impl.LinkedBlockingChannel;
+import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
+import ca.uhn.fhir.jpa.test.Batch2JobHelper;
+import ca.uhn.fhir.model.api.IModelJson;
+import ca.uhn.fhir.test.utilities.UnregisterScheduledProcessor;
+import ca.uhn.test.concurrency.PointcutLatch;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+
+import javax.annotation.Nonnull;
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+
+import static ca.uhn.fhir.batch2.config.BaseBatch2Config.CHANNEL_NAME;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@TestPropertySource(properties = {
+ UnregisterScheduledProcessor.SCHEDULING_DISABLED_EQUALS_FALSE
+})
+@ContextConfiguration(classes = {Batch2JobMaintenanceIT.SpringConfig.class})
+public class Batch2JobMaintenanceIT extends BaseJpaR4Test {
+ private static final Logger ourLog = LoggerFactory.getLogger(Batch2JobMaintenanceIT.class);
+
+ public static final int TEST_JOB_VERSION = 1;
+ public static final String FIRST_STEP_ID = "first-step";
+ public static final String LAST_STEP_ID = "last-step";
+ @Autowired
+ JobDefinitionRegistry myJobDefinitionRegistry;
+ @Autowired
+ IJobCoordinator myJobCoordinator;
+ @Autowired
+ IJobMaintenanceService myJobMaintenanceService;
+ @Autowired
+ Batch2JobHelper myBatch2JobHelper;
+ @Autowired
+ private IChannelFactory myChannelFactory;
+
+ @Autowired
+ IJobPersistence myJobPersistence;
+
+ private final PointcutLatch myFirstStepLatch = new PointcutLatch("First Step");
+ private final PointcutLatch myLastStepLatch = new PointcutLatch("Last Step");
+ private IJobCompletionHandler myCompletionHandler;
+ private LinkedBlockingChannel myWorkChannel;
+ private final List myStackTraceElements = new ArrayList<>();
+
+ private static RunOutcome callLatch(PointcutLatch theLatch, StepExecutionDetails, ?> theStep) {
+ theLatch.call(theStep);
+ return RunOutcome.SUCCESS;
+ }
+
+ @BeforeEach
+ public void before() {
+ myCompletionHandler = details -> {};
+ myWorkChannel = (LinkedBlockingChannel) myChannelFactory.getOrCreateReceiver(CHANNEL_NAME, JobWorkNotificationJsonMessage.class, new ChannelConsumerSettings());
+ JobMaintenanceServiceImpl jobMaintenanceService = (JobMaintenanceServiceImpl) myJobMaintenanceService;
+ jobMaintenanceService.setMaintenanceJobStartedCallback(() -> {
+ ourLog.info("Batch maintenance job started");
+ myStackTraceElements.add(Thread.currentThread().getStackTrace());
+ });
+ }
+
+ @AfterEach
+ public void after() {
+ myWorkChannel.clearInterceptorsForUnitTest();
+ myDaoConfig.setJobFastTrackingEnabled(true);
+ JobMaintenanceServiceImpl jobMaintenanceService = (JobMaintenanceServiceImpl) myJobMaintenanceService;
+ jobMaintenanceService.setMaintenanceJobStartedCallback(() -> {});
+ }
+
+ @Test
+ public void testFirstStepToSecondStep_singleChunkFasttracks() throws InterruptedException {
+ IJobStepWorker firstStep = (step, sink) -> {
+ sink.accept(new FirstStepOutput());
+ callLatch(myFirstStepLatch, step);
+ return RunOutcome.SUCCESS;
+ };
+ IJobStepWorker lastStep = (step, sink) -> callLatch(myLastStepLatch, step);
+
+ String jobDefId = new Exception().getStackTrace()[0].getMethodName();
+ JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobDefId, firstStep, lastStep);
+
+ myJobDefinitionRegistry.addJobDefinition(definition);
+
+ JobInstanceStartRequest request = buildRequest(jobDefId);
+
+ myFirstStepLatch.setExpectedCount(1);
+ myLastStepLatch.setExpectedCount(1);
+ String batchJobId = myJobCoordinator.startInstance(request).getJobId();
+ myFirstStepLatch.awaitExpected();
+
+ myBatch2JobHelper.assertFastTracking(batchJobId);
+
+ // Since there was only one chunk, the job should proceed without requiring a maintenance pass
+ myBatch2JobHelper.awaitJobCompletion(batchJobId);
+ myBatch2JobHelper.assertFastTracking(batchJobId);
+ myLastStepLatch.awaitExpected();
+ myBatch2JobHelper.assertFastTracking(batchJobId);
+ assertJobMaintenanceCalledByQuartzThread();
+ assertJobMaintenanceCalledAtLeast(2);
+ }
+
+ private void assertJobMaintenanceCalledAtLeast(int theSize) {
+ assertTrue(myStackTraceElements.size() >= theSize, "Expected at least " + theSize + " calls to job maintenance but got " + myStackTraceElements.size());
+ }
+
+ private void assertJobMaintenanceCalledByQuartzThread() {
+ StackTraceElement[] stackTrace = myStackTraceElements.get(0);
+ boolean found = false;
+ for (StackTraceElement stackTraceElement : stackTrace) {
+ if (stackTraceElement.getClassName().equals("org.quartz.core.JobRunShell")) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found, "Job maintenance should be called by Quartz thread");
+ }
+
+ @Test
+ public void testFirstStepToSecondStepFasttrackingDisabled_singleChunkDoesNotFasttrack() throws InterruptedException {
+ myDaoConfig.setJobFastTrackingEnabled(false);
+
+ IJobStepWorker firstStep = (step, sink) -> {
+ sink.accept(new Batch2JobMaintenanceIT.FirstStepOutput());
+ callLatch(myFirstStepLatch, step);
+ return RunOutcome.SUCCESS;
+ };
+ IJobStepWorker lastStep = (step, sink) -> callLatch(myLastStepLatch, step);
+
+ String jobDefId = new Exception().getStackTrace()[0].getMethodName();
+
+ JobDefinition extends IModelJson> definition = buildGatedJobDefinition(jobDefId, firstStep, lastStep);
+
+ myJobDefinitionRegistry.addJobDefinition(definition);
+
+ JobInstanceStartRequest request = buildRequest(jobDefId);
+
+ myFirstStepLatch.setExpectedCount(1);
+ myLastStepLatch.setExpectedCount(1);
+ String batchJobId = myJobCoordinator.startInstance(request).getJobId();
+ myFirstStepLatch.awaitExpected();
+
+ myBatch2JobHelper.assertFastTracking(batchJobId);
+
+ // Since there was only one chunk, the job should request fasttracking
+ myBatch2JobHelper.awaitJobCompletionWithoutMaintenancePass(batchJobId);
+
+ // However since we disabled fasttracking, the job should not have fasttracked
+ myBatch2JobHelper.assertNotFastTracking(batchJobId);
+ myLastStepLatch.awaitExpected();
+ myBatch2JobHelper.assertNotFastTracking(batchJobId);
+ assertJobMaintenanceCalledByQuartzThread();
+ assertJobMaintenanceCalledAtLeast(2);
+ }
+
+ @Nonnull
+ private JobInstanceStartRequest buildRequest(String jobId) {
+ JobInstanceStartRequest request = new JobInstanceStartRequest();
+ request.setJobDefinitionId(jobId);
+ TestJobParameters parameters = new TestJobParameters();
+ request.setParameters(parameters);
+ return request;
+ }
+
+ @Nonnull
+ private JobDefinition extends IModelJson> buildGatedJobDefinition(String theJobId, IJobStepWorker theFirstStep, IJobStepWorker theLastStep) {
+ return JobDefinition.newBuilder()
+ .setJobDefinitionId(theJobId)
+ .setJobDescription("test job")
+ .setJobDefinitionVersion(TEST_JOB_VERSION)
+ .setParametersType(TestJobParameters.class)
+ .gatedExecution()
+ .addFirstStep(
+ FIRST_STEP_ID,
+ "Test first step",
+ FirstStepOutput.class,
+ theFirstStep
+ )
+ .addLastStep(
+ LAST_STEP_ID,
+ "Test last step",
+ theLastStep
+ )
+ .completionHandler(myCompletionHandler)
+ .build();
+ }
+
+ static class TestJobParameters implements IModelJson {
+ TestJobParameters() {
+ }
+ }
+
+ static class FirstStepOutput implements IModelJson {
+ FirstStepOutput() {
+ }
+ }
+
+ static class SecondStepOutput implements IModelJson {
+ @JsonProperty("test")
+ private String myTestValue;
+
+ SecondStepOutput() {
+ }
+
+ public void setValue(String theV) {
+ myTestValue = theV;
+ }
+ }
+
+ static class ReductionStepOutput implements IModelJson {
+ @JsonProperty("result")
+ private List> myResult;
+
+ ReductionStepOutput(List> theResult) {
+ myResult = theResult;
+ }
+ }
+
+ static class SpringConfig {
+ @Autowired
+ IJobMaintenanceService myJobMaintenanceService;
+
+ @PostConstruct
+ void fastScheduler() {
+ ((JobMaintenanceServiceImpl)myJobMaintenanceService).setScheduledJobFrequencyMillis(200);
+ }
+ }
+}
diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml
index 04e32dde80a..73c3bbc6774 100644
--- a/hapi-fhir-jpaserver-test-r4b/pom.xml
+++ b/hapi-fhir-jpaserver-test-r4b/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml
index d73b8b84ae5..f15ab301d16 100644
--- a/hapi-fhir-jpaserver-test-r5/pom.xml
+++ b/hapi-fhir-jpaserver-test-r5/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml
index a71773fad34..ef5fd382091 100644
--- a/hapi-fhir-jpaserver-test-utilities/pom.xml
+++ b/hapi-fhir-jpaserver-test-utilities/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Batch2JobHelper.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Batch2JobHelper.java
index f835aca435a..a1ac9bc6fb2 100644
--- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Batch2JobHelper.java
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/Batch2JobHelper.java
@@ -63,54 +63,82 @@ public class Batch2JobHelper {
return awaitJobCompletion(theStartResponse.getJobId());
}
- public JobInstance awaitJobCompletion(String theId) {
- return awaitJobHasStatus(theId, StatusEnum.COMPLETED);
+ public JobInstance awaitJobCompletion(String theBatchJobId) {
+ return awaitJobHasStatus(theBatchJobId, StatusEnum.COMPLETED);
}
- public JobInstance awaitJobCancelled(String theId) {
- return awaitJobHasStatus(theId, StatusEnum.CANCELLED);
+ public JobInstance awaitJobCompletionWithoutMaintenancePass(String theBatchJobId) {
+ return awaitJobHasStatusWithoutMaintenancePass(theBatchJobId, StatusEnum.COMPLETED);
}
- public JobInstance awaitJobCompletion(String theId, int theSecondsToWait) {
- return awaitJobHasStatus(theId, theSecondsToWait, StatusEnum.COMPLETED);
+
+ public JobInstance awaitJobCancelled(String theBatchJobId) {
+ return awaitJobHasStatus(theBatchJobId, StatusEnum.CANCELLED);
}
- public JobInstance awaitJobHasStatus(String theId, StatusEnum... theExpectedStatus) {
- return awaitJobHasStatus(theId, 10, theExpectedStatus);
+ public JobInstance awaitJobCompletion(String theBatchJobId, int theSecondsToWait) {
+ return awaitJobHasStatus(theBatchJobId, theSecondsToWait, StatusEnum.COMPLETED);
}
- public JobInstance awaitJobHasStatus(String theId, int theSecondsToWait, StatusEnum... theExpectedStatus) {
+ public JobInstance awaitJobHasStatus(String theBatchJobId, StatusEnum... theExpectedStatus) {
+ return awaitJobHasStatus(theBatchJobId, 10, theExpectedStatus);
+ }
+
+ public JobInstance awaitJobHasStatusWithoutMaintenancePass(String theBatchJobId, StatusEnum... theExpectedStatus) {
+ return awaitJobawaitJobHasStatusWithoutMaintenancePass(theBatchJobId, 10, theExpectedStatus);
+ }
+
+ public JobInstance awaitJobHasStatus(String theBatchJobId, int theSecondsToWait, StatusEnum... theExpectedStatus) {
assert !TransactionSynchronizationManager.isActualTransactionActive();
try {
await()
.atMost(theSecondsToWait, TimeUnit.SECONDS)
- .until(() -> checkStatusWithMaintenancePass(theId, theExpectedStatus));
+ .until(() -> checkStatusWithMaintenancePass(theBatchJobId, theExpectedStatus));
} catch (ConditionTimeoutException e) {
String statuses = myJobPersistence.fetchInstances(100, 0)
.stream()
.map(t -> t.getJobDefinitionId() + "/" + t.getStatus().name())
.collect(Collectors.joining("\n"));
- String currentStatus = myJobCoordinator.getInstance(theId).getStatus().name();
+ String currentStatus = myJobCoordinator.getInstance(theBatchJobId).getStatus().name();
fail("Job still has status " + currentStatus + " - All statuses:\n" + statuses);
}
- return myJobCoordinator.getInstance(theId);
+ return myJobCoordinator.getInstance(theBatchJobId);
}
- private boolean checkStatusWithMaintenancePass(String theId, StatusEnum... theExpectedStatuses) {
- if (hasStatus(theId, theExpectedStatuses)) {
+
+ public JobInstance awaitJobawaitJobHasStatusWithoutMaintenancePass(String theBatchJobId, int theSecondsToWait, StatusEnum... theExpectedStatus) {
+ assert !TransactionSynchronizationManager.isActualTransactionActive();
+
+ try {
+ await()
+ .atMost(theSecondsToWait, TimeUnit.SECONDS)
+ .until(() -> hasStatus(theBatchJobId, theExpectedStatus));
+ } catch (ConditionTimeoutException e) {
+ String statuses = myJobPersistence.fetchInstances(100, 0)
+ .stream()
+ .map(t -> t.getJobDefinitionId() + "/" + t.getStatus().name())
+ .collect(Collectors.joining("\n"));
+ String currentStatus = myJobCoordinator.getInstance(theBatchJobId).getStatus().name();
+ fail("Job still has status " + currentStatus + " - All statuses:\n" + statuses);
+ }
+ return myJobCoordinator.getInstance(theBatchJobId);
+ }
+
+ private boolean checkStatusWithMaintenancePass(String theBatchJobId, StatusEnum... theExpectedStatuses) {
+ if (hasStatus(theBatchJobId, theExpectedStatuses)) {
return true;
}
myJobMaintenanceService.runMaintenancePass();
- return hasStatus(theId, theExpectedStatuses);
+ return hasStatus(theBatchJobId, theExpectedStatuses);
}
- private boolean hasStatus(String theId, StatusEnum[] theExpectedStatuses) {
- return ArrayUtils.contains(theExpectedStatuses, getStatus(theId));
+ private boolean hasStatus(String theBatchJobId, StatusEnum[] theExpectedStatuses) {
+ return ArrayUtils.contains(theExpectedStatuses, getStatus(theBatchJobId));
}
- private StatusEnum getStatus(String theId) {
- return myJobCoordinator.getInstance(theId).getStatus();
+ private StatusEnum getStatus(String theBatchJobId) {
+ return myJobCoordinator.getInstance(theBatchJobId).getStatus();
}
public JobInstance awaitJobFailure(Batch2JobStartResponse theStartResponse) {
@@ -121,8 +149,8 @@ public class Batch2JobHelper {
return awaitJobHasStatus(theJobId, StatusEnum.ERRORED, StatusEnum.FAILED);
}
- public void awaitJobInProgress(String theId) {
- await().until(() -> checkStatusWithMaintenancePass(theId, StatusEnum.IN_PROGRESS));
+ public void awaitJobInProgress(String theBatchJobId) {
+ await().until(() -> checkStatusWithMaintenancePass(theBatchJobId, StatusEnum.IN_PROGRESS));
}
public void assertNotFastTracking(String theInstanceId) {
@@ -214,4 +242,5 @@ public class Batch2JobHelper {
public void runMaintenancePass() {
myJobMaintenanceService.runMaintenancePass();
}
+
}
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
index b6c1307c087..40c9f8d9474 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
+++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml
index 22674a7191c..6281f775627 100644
--- a/hapi-fhir-server-mdm/pom.xml
+++ b/hapi-fhir-server-mdm/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml
index 4df2ce6ec25..745e3383578 100644
--- a/hapi-fhir-server-openapi/pom.xml
+++ b/hapi-fhir-server-openapi/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml
index 93fa2478600..c31bc5b0cb6 100644
--- a/hapi-fhir-server/pom.xml
+++ b/hapi-fhir-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
index 4eb95474c53..c5d6191700d 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
index d69036e069a..4a518ebba4e 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
@@ -20,7 +20,7 @@
ca.uhn.hapi.fhir
hapi-fhir-caching-api
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
com.github.ben-manes.caffeine
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
index 65b68e1a27c..5b32bcfc77b 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir-serviceloaders
ca.uhn.hapi.fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
index 2282740d1cf..7e723f50d22 100644
--- a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
+++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml
@@ -7,7 +7,7 @@
hapi-fhir
ca.uhn.hapi.fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../pom.xml
diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml
index b6b079e47d7..40a02580640 100644
--- a/hapi-fhir-serviceloaders/pom.xml
+++ b/hapi-fhir-serviceloaders/pom.xml
@@ -5,7 +5,7 @@
hapi-fhir
ca.uhn.hapi.fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
index f4bac593db3..a2098096e98 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
index adac437c497..98ace25d353 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
hapi-fhir-spring-boot-sample-client-apache
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
index eabb96ba063..1e8eabdb8c7 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
hapi-fhir-spring-boot-sample-client-okhttp
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
index d419a41c0a7..0568c214cb8 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot-samples
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
hapi-fhir-spring-boot-sample-server-jersey
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
index 4789b64bb4c..6c811741608 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir-spring-boot
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
hapi-fhir-spring-boot-samples
diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
index 7be733fedd7..cc3401f4095 100644
--- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
+++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml
index 5e134884f85..e30a2a62050 100644
--- a/hapi-fhir-spring-boot/pom.xml
+++ b/hapi-fhir-spring-boot/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml
index 9b942cbe963..5106876c529 100644
--- a/hapi-fhir-sql-migrate/pom.xml
+++ b/hapi-fhir-sql-migrate/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForeignKeyContainer.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForeignKeyContainer.java
index 8c2d41c48d2..aaf0dfb8fdf 100644
--- a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForeignKeyContainer.java
+++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ForeignKeyContainer.java
@@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.migrate.taskdef;
+/*-
+ * #%L
+ * HAPI FHIR Server - SQL Migration
+ * %%
+ * Copyright (C) 2014 - 2023 Smile CDR, Inc.
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml
index 92cf06a0f63..b04c1751162 100644
--- a/hapi-fhir-storage-batch2-jobs/pom.xml
+++ b/hapi-fhir-storage-batch2-jobs/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
4.0.0
diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml
index f8944cfbc38..fdbd7790d39 100644
--- a/hapi-fhir-storage-batch2/pom.xml
+++ b/hapi-fhir-storage-batch2/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/config/BaseBatch2Config.java b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/config/BaseBatch2Config.java
index 0a45269b864..41bfa35d00f 100644
--- a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/config/BaseBatch2Config.java
+++ b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/config/BaseBatch2Config.java
@@ -29,6 +29,7 @@ import ca.uhn.fhir.batch2.coordinator.JobDefinitionRegistry;
import ca.uhn.fhir.batch2.coordinator.WorkChunkProcessor;
import ca.uhn.fhir.batch2.maintenance.JobMaintenanceServiceImpl;
import ca.uhn.fhir.batch2.model.JobWorkNotificationJsonMessage;
+import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
import ca.uhn.fhir.jpa.subscription.channel.api.ChannelConsumerSettings;
import ca.uhn.fhir.jpa.subscription.channel.api.ChannelProducerSettings;
@@ -81,11 +82,13 @@ public abstract class BaseBatch2Config {
@Bean
public IJobMaintenanceService batch2JobMaintenanceService(ISchedulerService theSchedulerService,
JobDefinitionRegistry theJobDefinitionRegistry,
+ DaoConfig theDaoConfig,
BatchJobSender theBatchJobSender,
WorkChunkProcessor theExecutor
) {
return new JobMaintenanceServiceImpl(theSchedulerService,
myPersistence,
+ theDaoConfig,
theJobDefinitionRegistry,
theBatchJobSender,
theExecutor
diff --git a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/JobStepExecutor.java b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/JobStepExecutor.java
index d7c3ff8f379..1b13b210251 100644
--- a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/JobStepExecutor.java
+++ b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/coordinator/JobStepExecutor.java
@@ -26,8 +26,6 @@ import ca.uhn.fhir.batch2.channel.BatchJobSender;
import ca.uhn.fhir.batch2.model.JobDefinition;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.JobWorkCursor;
-import ca.uhn.fhir.batch2.model.JobWorkNotification;
-import ca.uhn.fhir.batch2.model.StatusEnum;
import ca.uhn.fhir.batch2.model.WorkChunk;
import ca.uhn.fhir.batch2.progress.JobInstanceStatusUpdater;
import ca.uhn.fhir.jpa.batch.log.Logs;
@@ -36,8 +34,6 @@ import org.slf4j.Logger;
import javax.annotation.Nonnull;
import java.util.Date;
-import java.util.Optional;
-import java.util.Date;
public class JobStepExecutor {
private static final Logger ourLog = Logs.getBatchTroubleshootingLog();
@@ -98,7 +94,11 @@ public class JobStepExecutor theDataSink) {
if (theDataSink.getWorkChunkCount() <= 1) {
ourLog.debug("Gated job {} step {} produced exactly one chunk: Triggering a maintenance pass.", myDefinition.getJobDefinitionId(), myCursor.currentStep.getStepId());
- myJobMaintenanceService.triggerMaintenancePass();
+ boolean success = myJobMaintenanceService.triggerMaintenancePass();
+ if (!success) {
+ myInstance.setFastTracking(false);
+ myJobPersistence.updateInstance(myInstance);
+ }
} else {
ourLog.debug("Gated job {} step {} produced {} chunks: Disabling fast tracking.", myDefinition.getJobDefinitionId(), myCursor.currentStep.getStepId(), theDataSink.getWorkChunkCount());
myInstance.setFastTracking(false);
diff --git a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImpl.java b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImpl.java
index c553f6d7b3e..690ec3ca181 100644
--- a/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImpl.java
+++ b/hapi-fhir-storage-batch2/src/main/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImpl.java
@@ -27,6 +27,7 @@ import ca.uhn.fhir.batch2.coordinator.JobDefinitionRegistry;
import ca.uhn.fhir.batch2.coordinator.WorkChunkProcessor;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.i18n.Msg;
+import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.batch.log.Logs;
import ca.uhn.fhir.jpa.model.sched.HapiJob;
import ca.uhn.fhir.jpa.model.sched.IHasScheduledJobs;
@@ -84,21 +85,28 @@ public class JobMaintenanceServiceImpl implements IJobMaintenanceService, IHasSc
private final IJobPersistence myJobPersistence;
private final ISchedulerService mySchedulerService;
+ private final DaoConfig myDaoConfig;
private final JobDefinitionRegistry myJobDefinitionRegistry;
private final BatchJobSender myBatchJobSender;
private final WorkChunkProcessor myJobExecutorSvc;
private final Semaphore myRunMaintenanceSemaphore = new Semaphore(1);
+ private long myScheduledJobFrequencyMillis = DateUtils.MILLIS_PER_MINUTE;
+ private Runnable myMaintenanceJobStartedCallback = () -> {};
+ private Runnable myMaintenanceJobFinishedCallback = () -> {};
+
/**
* Constructor
*/
public JobMaintenanceServiceImpl(@Nonnull ISchedulerService theSchedulerService,
@Nonnull IJobPersistence theJobPersistence,
+ DaoConfig theDaoConfig,
@Nonnull JobDefinitionRegistry theJobDefinitionRegistry,
@Nonnull BatchJobSender theBatchJobSender,
@Nonnull WorkChunkProcessor theExecutor
) {
+ myDaoConfig = theDaoConfig;
Validate.notNull(theSchedulerService);
Validate.notNull(theJobPersistence);
Validate.notNull(theJobDefinitionRegistry);
@@ -113,7 +121,7 @@ public class JobMaintenanceServiceImpl implements IJobMaintenanceService, IHasSc
@Override
public void scheduleJobs(ISchedulerService theSchedulerService) {
- mySchedulerService.scheduleClusteredJob(DateUtils.MILLIS_PER_MINUTE, buildJobDefinition());
+ mySchedulerService.scheduleClusteredJob(myScheduledJobFrequencyMillis, buildJobDefinition());
}
@Nonnull
@@ -124,14 +132,21 @@ public class JobMaintenanceServiceImpl implements IJobMaintenanceService, IHasSc
return jobDefinition;
}
+ public void setScheduledJobFrequencyMillis(long theScheduledJobFrequencyMillis) {
+ myScheduledJobFrequencyMillis = theScheduledJobFrequencyMillis;
+ }
+
/**
* @return true if a request to run a maintance pass was submitted
*/
@Override
public boolean triggerMaintenancePass() {
+ if (!myDaoConfig.isJobFastTrackingEnabled()) {
+ return false;
+ }
if (mySchedulerService.isClusteredSchedulingEnabled()) {
- mySchedulerService.triggerClusteredJobImmediately(buildJobDefinition());
- return true;
+ mySchedulerService.triggerClusteredJobImmediately(buildJobDefinition());
+ return true;
} else {
// We are probably running a unit test
return runMaintenanceDirectlyWithTimeout();
@@ -178,6 +193,7 @@ public class JobMaintenanceServiceImpl implements IJobMaintenanceService, IHasSc
}
private void doMaintenancePass() {
+ myMaintenanceJobStartedCallback.run();
Set processedInstanceIds = new HashSet<>();
JobChunkProgressAccumulator progressAccumulator = new JobChunkProgressAccumulator();
for (int page = 0; ; page++) {
@@ -196,6 +212,15 @@ public class JobMaintenanceServiceImpl implements IJobMaintenanceService, IHasSc
break;
}
}
+ myMaintenanceJobFinishedCallback.run();
+ }
+
+ public void setMaintenanceJobStartedCallback(Runnable theMaintenanceJobStartedCallback) {
+ myMaintenanceJobStartedCallback = theMaintenanceJobStartedCallback;
+ }
+
+ public void setMaintenanceJobFinishedCallback(Runnable theMaintenanceJobFinishedCallback) {
+ myMaintenanceJobFinishedCallback = theMaintenanceJobFinishedCallback;
}
public static class JobMaintenanceScheduledJob implements HapiJob {
diff --git a/hapi-fhir-storage-batch2/src/test/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImplTest.java b/hapi-fhir-storage-batch2/src/test/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImplTest.java
index 76d771c316b..063a799c61d 100644
--- a/hapi-fhir-storage-batch2/src/test/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImplTest.java
+++ b/hapi-fhir-storage-batch2/src/test/java/ca/uhn/fhir/batch2/maintenance/JobMaintenanceServiceImplTest.java
@@ -14,6 +14,7 @@ import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.JobWorkNotification;
import ca.uhn.fhir.batch2.model.StatusEnum;
import ca.uhn.fhir.batch2.model.WorkChunk;
+import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
import ca.uhn.fhir.jpa.subscription.channel.api.IChannelProducer;
import com.google.common.collect.Lists;
@@ -25,6 +26,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.messaging.Message;
@@ -68,6 +70,8 @@ public class JobMaintenanceServiceImplTest extends BaseBatch2Test {
private IJobPersistence myJobPersistence;
@Mock
private WorkChunkProcessor myJobExecutorSvc;
+ @Spy
+ private DaoConfig myDaoConfig = new DaoConfig();
private JobMaintenanceServiceImpl mySvc;
@Captor
private ArgumentCaptor myInstanceCaptor;
@@ -87,10 +91,12 @@ public class JobMaintenanceServiceImplTest extends BaseBatch2Test {
BatchJobSender batchJobSender = new BatchJobSender(myWorkChannelProducer);
mySvc = new JobMaintenanceServiceImpl(mySchedulerService,
myJobPersistence,
+ myDaoConfig,
myJobDefinitionRegistry,
batchJobSender,
myJobExecutorSvc
);
+ myDaoConfig.setJobFastTrackingEnabled(true);
}
@Test
@@ -183,10 +189,13 @@ public class JobMaintenanceServiceImplTest extends BaseBatch2Test {
);
when (myJobPersistence.canAdvanceInstanceToNextStep(any(), any())).thenReturn(true);
myJobDefinitionRegistry.addJobDefinition(createJobDefinition(JobDefinition.Builder::gatedExecution));
+
when(myJobPersistence.fetchAllWorkChunksIterator(eq(INSTANCE_ID), eq(false)))
.thenReturn(chunks.iterator());
+
when(myJobPersistence.fetchallchunkidsforstepWithStatus(eq(INSTANCE_ID), eq(STEP_2), eq(StatusEnum.QUEUED)))
.thenReturn(chunks.stream().map(chunk -> chunk.getId()).collect(Collectors.toList()));
+
JobInstance instance1 = createInstance();
instance1.setCurrentGatedStepId(STEP_1);
when(myJobPersistence.fetchInstances(anyInt(), eq(0))).thenReturn(Lists.newArrayList(instance1));
@@ -196,6 +205,7 @@ public class JobMaintenanceServiceImplTest extends BaseBatch2Test {
// Verify
verify(myWorkChannelProducer, times(2)).send(myMessageCaptor.capture());
+ verify(myJobPersistence, times(2)).updateInstance(myInstanceCaptor.capture());
JobWorkNotification payload0 = myMessageCaptor.getAllValues().get(0).getPayload();
assertEquals(STEP_2, payload0.getTargetStepId());
assertEquals(CHUNK_ID, payload0.getChunkId());
@@ -347,6 +357,7 @@ public class JobMaintenanceServiceImplTest extends BaseBatch2Test {
mySvc.runMaintenancePass();
// Verify
+ verify(myJobPersistence, times(2)).updateInstance(myInstanceCaptor.capture());
assertEquals(StatusEnum.CANCELLED, instance1.getStatus());
assertTrue(instance1.getErrorMessage().startsWith("Job instance cancelled"));
}
@@ -392,6 +403,12 @@ public class JobMaintenanceServiceImplTest extends BaseBatch2Test {
verify(myJobPersistence, times(1)).fetchInstances(anyInt(), eq(0));
}
+ @Test
+ void triggerMaintenancePassDisabled_noneInProgress_doesNotRunMaintenace() {
+ myDaoConfig.setJobFastTrackingEnabled(false);
+ mySvc.triggerMaintenancePass();
+ verifyNoMoreInteractions(myJobPersistence);
+ }
@Test
void triggerMaintenancePass_twoSimultaneousRequests_onlyCallOnce() throws InterruptedException, ExecutionException {
diff --git a/hapi-fhir-storage-cr/pom.xml b/hapi-fhir-storage-cr/pom.xml
index c2fc78e2802..170ecac7dcb 100644
--- a/hapi-fhir-storage-cr/pom.xml
+++ b/hapi-fhir-storage-cr/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml
index 4a90adfa481..b5202ff661d 100644
--- a/hapi-fhir-storage-mdm/pom.xml
+++ b/hapi-fhir-storage-mdm/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
4.0.0
diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml
index 0fadcbf00a8..2543992030b 100644
--- a/hapi-fhir-storage-test-utilities/pom.xml
+++ b/hapi-fhir-storage-test-utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
4.0.0
diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml
index 59bf5edc099..101748fb648 100644
--- a/hapi-fhir-storage/pom.xml
+++ b/hapi-fhir-storage/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java
index 0787075a780..043a3ab1941 100644
--- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/config/DaoConfig.java
@@ -334,6 +334,10 @@ public class DaoConfig {
* Since 6.2.0
*/
private int myBulkExportFileMaximumCapacity = 1_000;
+ /**
+ * Since 6.4.0
+ */
+ private boolean myJobFastTrackingEnabled = false;
/**
* Constructor
@@ -355,6 +359,10 @@ public class DaoConfig {
ourLog.info("Status based reindexing is DISABLED");
setStatusBasedReindexingDisabled(true);
}
+ if (HapiSystemProperties.isUnitTestModeEnabled()) {
+ setJobFastTrackingEnabled(true);
+ }
+
}
/**
@@ -2985,6 +2993,26 @@ public class DaoConfig {
myBulkExportFileMaximumCapacity = theBulkExportFileMaximumCapacity;
}
+ /**
+ * If this setting is enabled, then gated batch jobs that produce only one chunk will immediately trigger a batch
+ * maintenance job. This may be useful for testing, but is not recommended for production use.
+ *
+ * @since 6.4.0
+ */
+ public boolean isJobFastTrackingEnabled() {
+ return myJobFastTrackingEnabled;
+ }
+
+ /**
+ * If this setting is enabled, then gated batch jobs that produce only one chunk will immediately trigger a batch
+ * maintenance job. This may be useful for testing, but is not recommended for production use.
+ *
+ * @since 6.4.0
+ */
+ public void setJobFastTrackingEnabled(boolean theJobFastTrackingEnabled) {
+ myJobFastTrackingEnabled = theJobFastTrackingEnabled;
+ }
+
public enum StoreMetaSourceInformationEnum {
NONE(false, false),
SOURCE_URI(true, false),
diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml
index 50729fa86fd..45aef6d8ace 100644
--- a/hapi-fhir-structures-dstu2.1/pom.xml
+++ b/hapi-fhir-structures-dstu2.1/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml
index e5fb8f10fe3..0ec1b7a2a30 100644
--- a/hapi-fhir-structures-dstu2/pom.xml
+++ b/hapi-fhir-structures-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml
index d5e8887eec8..6f6dda320fe 100644
--- a/hapi-fhir-structures-dstu3/pom.xml
+++ b/hapi-fhir-structures-dstu3/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml
index 97ba23e6fec..df77c61d797 100644
--- a/hapi-fhir-structures-hl7org-dstu2/pom.xml
+++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml
index 3b9eed36c98..604da5cf298 100644
--- a/hapi-fhir-structures-r4/pom.xml
+++ b/hapi-fhir-structures-r4/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml
index 784e5776ba4..1c40cfa62ce 100644
--- a/hapi-fhir-structures-r4b/pom.xml
+++ b/hapi-fhir-structures-r4b/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml
index e7850b9d638..953a87dbb25 100644
--- a/hapi-fhir-structures-r5/pom.xml
+++ b/hapi-fhir-structures-r5/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml
index 3184f08b98d..46e0c2046c3 100644
--- a/hapi-fhir-test-utilities/pom.xml
+++ b/hapi-fhir-test-utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/UnregisterScheduledProcessor.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/UnregisterScheduledProcessor.java
index ee86215d728..0a7b11a373a 100644
--- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/UnregisterScheduledProcessor.java
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/UnregisterScheduledProcessor.java
@@ -37,6 +37,7 @@ public class UnregisterScheduledProcessor implements BeanFactoryPostProcessor {
public static final String SCHEDULING_DISABLED = "scheduling_disabled";
public static final String SCHEDULING_DISABLED_EQUALS_TRUE = "scheduling_disabled=true";
+ public static final String SCHEDULING_DISABLED_EQUALS_FALSE = "scheduling_disabled=false";
private final Environment myEnvironment;
diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml
index db44aa988cc..b6ed312ccb2 100644
--- a/hapi-fhir-testpage-overlay/pom.xml
+++ b/hapi-fhir-testpage-overlay/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml
index 9c2b774813a..69799b9b6d0 100644
--- a/hapi-fhir-validation-resources-dstu2.1/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml
index 94918713f1d..6935871c449 100644
--- a/hapi-fhir-validation-resources-dstu2/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml
index 37b32bf2193..d1db4500a47 100644
--- a/hapi-fhir-validation-resources-dstu3/pom.xml
+++ b/hapi-fhir-validation-resources-dstu3/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml
index 265f1d88dc7..3b0f4882715 100644
--- a/hapi-fhir-validation-resources-r4/pom.xml
+++ b/hapi-fhir-validation-resources-r4/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml
index 9a63d1dd021..7a9e8b1b910 100644
--- a/hapi-fhir-validation-resources-r5/pom.xml
+++ b/hapi-fhir-validation-resources-r5/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index f9da27989b0..6867b0a1c0f 100644
--- a/hapi-fhir-validation/pom.xml
+++ b/hapi-fhir-validation/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml
index 434886ae612..40febdbcb6b 100644
--- a/hapi-tinder-plugin/pom.xml
+++ b/hapi-tinder-plugin/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml
index 8ff67da6347..ef2e2337210 100644
--- a/hapi-tinder-test/pom.xml
+++ b/hapi-tinder-test/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index 8aee622d591..80dc65eed9d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-fhir
pom
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
HAPI-FHIR
An open-source implementation of the FHIR specification in Java.
https://hapifhir.io
@@ -2128,7 +2128,7 @@
ca.uhn.hapi.fhir
hapi-fhir-checkstyle
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
index 10f594ebc7d..d93af36b8e9 100644
--- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
+++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
index c7e6166b35f..136ce7ab531 100644
--- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../pom.xml
diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
index 99feb416e38..c49e28c4009 100644
--- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml
+++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 6.3.10-SNAPSHOT
+ 6.3.11-SNAPSHOT
../../pom.xml