diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml
index f5a45ad66136..67e76f525de5 100644
--- a/hapi-deployable-pom/pom.xml
+++ b/hapi-deployable-pom/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml
index 93ef46249d43..7e036b9bb934 100644
--- a/hapi-fhir-android/pom.xml
+++ b/hapi-fhir-android/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml
index 66fde1eac1a9..ee58dc5b285a 100644
--- a/hapi-fhir-base/pom.xml
+++ b/hapi-fhir-base/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java
index d03df725fc12..3310e7a71fc0 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/support/IValidationSupport.java
@@ -45,6 +45,7 @@
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@@ -192,6 +193,14 @@ default IBaseResource fetchCodeSystem(String theSystem) {
return null;
}
+ default Stream fetchResources(Class theClazz, String theUrl) {
+ return Stream.empty();
+ }
+
+ default Stream fetchAllResourcesOfType(@Nonnull Class theClazz) {
+ return Stream.empty();
+ }
+
/**
* Loads a resource needed by the validation (a StructureDefinition, or a
* ValueSet)
diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml
index 10afb0b09b4e..c24b5e5ea4e5 100644
--- a/hapi-fhir-bom/pom.xml
+++ b/hapi-fhir-bom/pom.xml
@@ -4,7 +4,7 @@
4.0.0
ca.uhn.hapi.fhir
hapi-fhir-bom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
pom
HAPI FHIR BOM
@@ -12,7 +12,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml
index d79de111925a..36873ef8a77d 100644
--- a/hapi-fhir-checkstyle/pom.xml
+++ b/hapi-fhir-checkstyle/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-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 ecf17562e062..7f0063c3f5a0 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 ad6bb69f5cf4..7b2e3ed7c92b 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml
index c3b8a50a8fdc..a7013e0413b2 100644
--- a/hapi-fhir-cli/pom.xml
+++ b/hapi-fhir-cli/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-client-apache-http5/pom.xml b/hapi-fhir-client-apache-http5/pom.xml
index 5dd8e79fd9b9..2c288cf1054d 100644
--- a/hapi-fhir-client-apache-http5/pom.xml
+++ b/hapi-fhir-client-apache-http5/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml
index a53934d738e7..d9fd49e71245 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml
index cfa2400f292a..52cbf472c60b 100644
--- a/hapi-fhir-client/pom.xml
+++ b/hapi-fhir-client/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml
index 65c6a24fd9e1..6d46f95dcfa1 100644
--- a/hapi-fhir-converter/pom.xml
+++ b/hapi-fhir-converter/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml
index 1f11c4bb8d71..7dca996c0853 100644
--- a/hapi-fhir-dist/pom.xml
+++ b/hapi-fhir-dist/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml
index 93815f083541..ff2327d62817 100644
--- a/hapi-fhir-docs/pom.xml
+++ b/hapi-fhir-docs/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml
index f46ba71aa9ba..30409babe3de 100644
--- a/hapi-fhir-jacoco/pom.xml
+++ b/hapi-fhir-jacoco/pom.xml
@@ -11,7 +11,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml
index ec3bca24c1f9..bd1994aaf2f2 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpa-hibernate-services/pom.xml b/hapi-fhir-jpa-hibernate-services/pom.xml
index 428c086a6639..2a70c100669e 100644
--- a/hapi-fhir-jpa-hibernate-services/pom.xml
+++ b/hapi-fhir-jpa-hibernate-services/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml
index 513e2aea020b..891c7b586a5f 100644
--- a/hapi-fhir-jpa/pom.xml
+++ b/hapi-fhir-jpa/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-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 3af3588e90dc..9f2c05103528 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaConfig.java
index 81778c0bc247..ee6562c8aed1 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaConfig.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/config/JpaConfig.java
@@ -36,6 +36,7 @@
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
+import ca.uhn.fhir.jpa.api.svc.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.api.svc.ISearchUrlJobMaintenanceSvc;
import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor;
import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider;
@@ -101,7 +102,6 @@
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
import ca.uhn.fhir.jpa.packages.IHapiPackageCacheManager;
-import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.packages.JpaPackageCache;
import ca.uhn.fhir.jpa.packages.NpmJpaValidationSupport;
import ca.uhn.fhir.jpa.packages.PackageInstallerSvcImpl;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java
index 7c525708244d..4fb3fe9fe591 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/JpaPackageCache.java
@@ -428,7 +428,11 @@ private NpmPackage addPackageToCacheInternal(NpmPackageData thePackageData) {
}
getProcessingMessages(npmPackage)
- .add("Successfully added package " + npmPackage.id() + "#" + npmPackage.version() + " to registry");
+ .add(String.format(
+ NpmPackageUtils.SUCCESSFULLY_INSTALLED_MSG_TEMPLATE,
+ npmPackage.id(),
+ npmPackage.version()));
+ // .add("Successfully added package " + npmPackage.id() + "#" + npmPackage.version() + " to registry");
return npmPackage;
});
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/NpmJpaValidationSupport.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/NpmJpaValidationSupport.java
index a6a761f0a794..4c799744044f 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/NpmJpaValidationSupport.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/NpmJpaValidationSupport.java
@@ -22,11 +22,18 @@
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.IValidationSupport;
+import ca.uhn.fhir.model.api.PagingIterator;
+import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
import java.util.List;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
public class NpmJpaValidationSupport implements IValidationSupport {
@@ -56,6 +63,55 @@ public IBaseResource fetchStructureDefinition(String theUri) {
return fetchResource("StructureDefinition", theUri);
}
+ @SuppressWarnings("unchecked")
+ @Override
+ public T fetchResource(@Nullable Class theClass, String theUri) {
+ if (theClass != null) {
+ String resourceType = myFhirContext.getResourceType(theClass);
+ // we can cast safely because the resource type must match what we're passing in.
+ // we aren't loading different versions of FHIR after all (since what we
+ // load is dependent on the fhir context too)
+ return (T) fetchResource(resourceType, theUri);
+ }
+
+ // no class
+ return null;
+ }
+
+ public static int batchSize() {
+ return 100;
+ }
+
+ @Override
+ public Stream fetchResources(Class theClazz, String theUrl) {
+ FhirVersionEnum fhirVersion = myFhirContext.getVersion().getVersion();
+ PagingIterator pagingIterator = new PagingIterator<>(
+ batchSize(),
+ (pageSize, batchSize, theConsumer) ->
+ myHapiPackageCacheManager
+ .loadPackageAssetsByUrl(fhirVersion, theUrl, PageRequest.of(pageSize, batchSize))
+ .stream()
+ .filter(r -> {
+ if (theClazz != null) {
+ return r.getClass().isAssignableFrom(theClazz);
+ }
+ return true;
+ })
+ .forEach(r -> theConsumer.accept((T) r)));
+
+ return StreamSupport.stream(
+ Spliterators.spliteratorUnknownSize(pagingIterator, Spliterator.ORDERED), false); // sequential
+ }
+
+ @Override
+ public Stream fetchAllResourcesOfType(@Nonnull Class theClazz) {
+ FhirVersionEnum fhirVersion = myFhirContext.getVersion().getVersion();
+ return myHapiPackageCacheManager.loadPackageAssetsByType(fhirVersion, theClazz.getSimpleName()).stream()
+ .map(r -> (T) r)
+ .toList()
+ .stream();
+ }
+
@Nullable
public IBaseResource fetchResource(String theResourceType, String theUri) {
FhirVersionEnum fhirVersion = myFhirContext.getVersion().getVersion();
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java
index 5b4b7d65c10b..9c07629dcab9 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java
@@ -32,6 +32,7 @@
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
+import ca.uhn.fhir.jpa.api.svc.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao;
import ca.uhn.fhir.jpa.dao.tx.IHapiTransactionService;
import ca.uhn.fhir.jpa.dao.validation.SearchParameterDaoValidator;
@@ -199,6 +200,8 @@ public PackageInstallOutcomeJson install(PackageInstallationSpec theInstallation
"Package {}#{} is already installed",
theInstallationSpec.getName(),
theInstallationSpec.getVersion());
+ // add a property to specify whether we keep going or not.
+ // use quartz to schedule a batch job on one instance to install the packages
}
NpmPackage npmPackage = myPackageCacheManager.installPackage(theInstallationSpec);
diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml
index fa89d228c901..b04880220908 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-hfql/pom.xml b/hapi-fhir-jpaserver-hfql/pom.xml
index 472f2fe508a5..ed58c0f76fb1 100644
--- a/hapi-fhir-jpaserver-hfql/pom.xml
+++ b/hapi-fhir-jpaserver-hfql/pom.xml
@@ -3,7 +3,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml
index 4e143c8ce717..d8c1f3ec8617 100644
--- a/hapi-fhir-jpaserver-ips/pom.xml
+++ b/hapi-fhir-jpaserver-ips/pom.xml
@@ -3,7 +3,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml
index 32fce796d1d5..e231c06159f1 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml
index e58ff9af7f8e..948fdb867786 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml
index 6a3fa73c9b9b..7f14c6886502 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml
index 84f32710a2d0..50bd22a6524d 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 eb714f37966d..17d553edefc5 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 d6569eebd097..4d0ad737edfb 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 bcdd2d22e273..d80ea67de958 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheSearchR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheSearchR4Test.java
index fd3a21e3a48c..f245e899e6af 100644
--- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheSearchR4Test.java
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/packages/JpaPackageCacheSearchR4Test.java
@@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.packages;
+import ca.uhn.fhir.jpa.api.svc.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.test.utilities.ProxyUtil;
import ca.uhn.fhir.util.ClasspathUtil;
diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/packages/NpmJpaValidationSupportIT.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/packages/NpmJpaValidationSupportIT.java
new file mode 100644
index 000000000000..1c0c5409e7c7
--- /dev/null
+++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/packages/NpmJpaValidationSupportIT.java
@@ -0,0 +1,317 @@
+package ca.uhn.fhir.jpa.packages;
+
+import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.context.support.IValidationSupport;
+import ca.uhn.fhir.implementationguide.ImplementationGuideCreator;
+import ca.uhn.fhir.jpa.api.svc.IPackageInstallerSvc;
+import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
+import ca.uhn.fhir.util.FhirTerser;
+import ca.uhn.test.util.LogbackTestExtension;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.r4.model.Enumerations;
+import org.hl7.fhir.r4.model.Questionnaire;
+import org.hl7.fhir.r4.model.SearchParameter;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.MockedStatic;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.mockStatic;
+
+public class NpmJpaValidationSupportIT extends BaseJpaR4Test {
+ @Autowired
+ private NpmJpaValidationSupport mySvc;
+
+ @Autowired
+ private IPackageInstallerSvc myPackageInstallerSvc;
+
+ @RegisterExtension
+ public final LogbackTestExtension myLogbackTestExtension = new LogbackTestExtension(NpmJpaValidationSupport.class);
+
+ private IValidationSupport myValidationSupport;
+
+ @BeforeEach
+ public void before() throws Exception {
+ super.before();
+ myValidationSupport = mySvc;
+ }
+
+ @Test
+ public void loadIGAndFetchSpecificResource_throughGenericIValidationsupport(@TempDir Path theTempDirPath) throws IOException {
+ // create an IG
+ ImplementationGuideCreator igCreator = new ImplementationGuideCreator(myFhirContext);
+ igCreator.setDirectory(theTempDirPath);
+
+ // create some resources
+ String spUrl = "http://localhost/ig-test-dir/sp";
+ String qUrl = "http://localhost/ig-test-dir/q";
+ for (int i = 0; i < 2; i++) {
+ SearchParameter sp = new SearchParameter();
+ sp.setUrl(spUrl + i);
+ sp.setCode("helloWorld" + i);
+ sp.setName(sp.getCode());
+ sp.setDescription("description");
+ sp.setType(Enumerations.SearchParamType.STRING);
+ sp.addBase("Patient");
+ sp.setExpression("Patient.name.given");
+ sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ igCreator.addResourceToIG(sp.getName(), sp);
+
+ Questionnaire questionnaire = new Questionnaire();
+ questionnaire.setUrl(qUrl + i);
+ questionnaire.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ questionnaire.setName("questionnaire" + i);
+ igCreator.addResourceToIG(questionnaire.getName(), questionnaire);
+ }
+
+ PackageInstallationSpec installationSpec = createAndInstallPackageSpec(igCreator, PackageInstallationSpec.InstallModeEnum.STORE_ONLY);
+
+ SearchParameter sp = myValidationSupport.fetchResource(SearchParameter.class, spUrl + "1");
+ assertNotNull(sp);
+ assertEquals(spUrl + "1", sp.getUrl());
+ Questionnaire q = myValidationSupport.fetchResource(Questionnaire.class, qUrl + "1");
+ assertNotNull(q);
+ assertEquals(qUrl + "1", q.getUrl());
+ }
+
+ @Test
+ public void loadIGAndFetchSpecificResource(@TempDir Path theTempDirPath) throws IOException {
+ // create an IG
+ ImplementationGuideCreator igCreator = new ImplementationGuideCreator(myFhirContext);
+ igCreator.setDirectory(theTempDirPath);
+
+ // create some resources
+ String spUrl = "http://localhost/ig-test-dir/sp";
+ String qUrl = "http://localhost/ig-test-dir/q";
+ for (int i = 0; i < 2; i++) {
+ SearchParameter sp = new SearchParameter();
+ sp.setUrl(spUrl + i);
+ sp.setCode("helloWorld" + i);
+ sp.setName(sp.getCode());
+ sp.setDescription("description");
+ sp.setType(Enumerations.SearchParamType.STRING);
+ sp.addBase("Patient");
+ sp.setExpression("Patient.name.given");
+ sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ igCreator.addResourceToIG(sp.getName(), sp);
+
+ Questionnaire questionnaire = new Questionnaire();
+ questionnaire.setUrl(qUrl + i);
+ questionnaire.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ questionnaire.setName("questionnaire" + i);
+ igCreator.addResourceToIG(questionnaire.getName(), questionnaire);
+ }
+
+ PackageInstallationSpec installationSpec = createAndInstallPackageSpec(igCreator, PackageInstallationSpec.InstallModeEnum.STORE_ONLY);
+
+ // test
+ IBaseResource sp = mySvc.fetchResource("SearchParameter", spUrl + "1");
+
+ // validation
+ assertNotNull(sp);
+ assertTrue(sp instanceof SearchParameter);
+ assertEquals(spUrl + "1", ((SearchParameter)sp).getUrl());
+ IBaseResource q = mySvc.fetchResource("Questionnaire", qUrl + "1");
+ assertNotNull(q);
+ assertTrue(q instanceof Questionnaire);
+ assertEquals(qUrl + "1", ((Questionnaire)q).getUrl());
+ }
+
+ @Test
+ public void loadIGAndFetchResource_usingWrongFhirVersion_throws(@TempDir Path theTempDirPath) throws IOException {
+ // create an IG
+ ImplementationGuideCreator igCreator = new ImplementationGuideCreator(myFhirContext);
+ igCreator.setDirectory(theTempDirPath);
+
+ String spUrl = "http://localhost/ig-test-dir/sp-1";
+ {
+ SearchParameter sp = new SearchParameter();
+ sp.setUrl(spUrl);
+ sp.setCode("helloWorld");
+ sp.setName(sp.getCode());
+ sp.setDescription("description");
+ sp.setType(Enumerations.SearchParamType.STRING);
+ sp.addBase("Patient");
+ sp.setExpression("Patient.name.given");
+ sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ igCreator.addResourceToIG(sp.getName(), sp);
+ }
+
+ PackageInstallationSpec installationSpec = createAndInstallPackageSpec(igCreator, PackageInstallationSpec.InstallModeEnum.STORE_ONLY);
+
+ // test
+ try {
+ ca.uhn.fhir.model.dstu2.resource.SearchParameter sp = myValidationSupport.fetchResource(ca.uhn.fhir.model.dstu2.resource.SearchParameter.class, spUrl);
+ fail();
+ } catch (ConfigurationException ex) {
+ assertTrue(ex.getLocalizedMessage().contains("This context is for FHIR version \"R4\""));
+ }
+ }
+
+ @Test
+ public void loadIGAndFetchResource_wrongUrl_returnsNull(@TempDir Path theTempDirPath) throws IOException {
+ // create an IG
+ ImplementationGuideCreator igCreator = new ImplementationGuideCreator(myFhirContext);
+ igCreator.setDirectory(theTempDirPath);
+
+ String spUrl = "http://localhost/ig-test-dir/sp-1";
+ {
+ SearchParameter sp = new SearchParameter();
+ sp.setUrl(spUrl);
+ sp.setCode("helloWorld");
+ sp.setName(sp.getCode());
+ sp.setDescription("description");
+ sp.setType(Enumerations.SearchParamType.STRING);
+ sp.addBase("Patient");
+ sp.setExpression("Patient.name.given");
+ sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ igCreator.addResourceToIG(sp.getName(), sp);
+ }
+
+ PackageInstallationSpec installationSpec = createAndInstallPackageSpec(igCreator, PackageInstallationSpec.InstallModeEnum.STORE_ONLY);
+
+ // test
+ SearchParameter sp = myValidationSupport.fetchResource(SearchParameter.class, spUrl + "2");
+
+ // validate
+ assertNull(sp);
+ }
+
+ @ParameterizedTest
+ @ValueSource(booleans = { true, false })
+ public void fetchResources_specifiedResourceType_works(boolean theRequestSpecificTypes, @TempDir Path theTempDirPath) throws IOException {
+
+ int versionCount = 5;
+ String spUrl = "http://localhost/ig-test-dir/url";
+ String qUrl = "http://localhost/ig-test-dir/qurl";
+ for (int i = 0; i < versionCount; i++) {
+ ImplementationGuideCreator igCreator = new ImplementationGuideCreator(myFhirContext, "test.ig.com", "1." + i);
+ Path subpath = Path.of(theTempDirPath.toString(), igCreator.getPackageName() + "_" + igCreator.getPackageVersion());
+ Files.createDirectory(subpath);
+ igCreator.setDirectory(subpath);
+
+ SearchParameter sp = new SearchParameter();
+ sp.setUrl(spUrl);
+ sp.setCode("helloWorld" + i);
+ sp.setName(sp.getCode());
+ sp.setDescription("description");
+ sp.setType(Enumerations.SearchParamType.STRING);
+ sp.addBase("Patient");
+ sp.setExpression("Patient.name.given");
+ sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ igCreator.addResourceToIG(sp.getName(), sp);
+
+ Questionnaire questionnaire = new Questionnaire();
+ questionnaire.setUrl(qUrl);
+ questionnaire.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ questionnaire.setName("questionnaire" + i);
+ igCreator.addResourceToIG(questionnaire.getName(), questionnaire);
+
+ PackageInstallationSpec installationSpec1 = createAndInstallPackageSpec(igCreator, PackageInstallationSpec.InstallModeEnum.STORE_ONLY);
+ }
+
+ // test
+ try (MockedStatic staticMock = mockStatic(NpmJpaValidationSupport.class)) {
+ // we use a small number to ensure batching works
+ staticMock.when(NpmJpaValidationSupport::batchSize).thenReturn(2);
+
+ if (theRequestSpecificTypes) {
+ Stream sps = myValidationSupport.fetchResources(SearchParameter.class, spUrl);
+ assertNotNull(sps);
+ List spList = sps.toList();
+ assertEquals(versionCount, spList.size());
+ spList.forEach(sp -> {
+ assertEquals(spUrl, sp.getUrl());
+ });
+ } else {
+ Stream resourceStream = myValidationSupport.fetchResources(null, qUrl);
+ assertNotNull(resourceStream);
+ List resources = resourceStream.toList();
+ assertEquals(versionCount, resources.size());
+ FhirTerser terser = myFhirContext.newTerser();
+ resources.forEach(r -> {
+ assertTrue(r instanceof Questionnaire);
+ Optional urlOp = terser.getSinglePrimitiveValue(r, "url");
+ assertTrue(urlOp.isPresent());
+ assertEquals(qUrl, urlOp.get());
+ });
+ }
+ }
+ }
+
+ @Test
+ public void fetchAllResourcesOfType_works(@TempDir Path theTempDirPath) throws IOException {
+ // create an IG
+ ImplementationGuideCreator igCreator = new ImplementationGuideCreator(myFhirContext);
+ igCreator.setDirectory(theTempDirPath);
+
+ int resourceCount = 50;
+ String spUrl = "http://localhost/ig-test-dir/sp";
+ String qUrl = "http://localhost/ig-test-dir/quest";
+ for (int i = 0; i < resourceCount; i++) {
+ SearchParameter sp = new SearchParameter();
+ sp.setUrl(spUrl);
+ sp.setCode("helloWorld" + i);
+ sp.setName(sp.getCode());
+ sp.setDescription("description");
+ sp.setType(Enumerations.SearchParamType.STRING);
+ sp.addBase("Patient");
+ sp.setExpression("Patient.name.given");
+ sp.setVersion("1." + i);
+ sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ igCreator.addResourceToIG(sp.getName(), sp);
+
+ Questionnaire questionnaire = new Questionnaire();
+ questionnaire.setUrl(qUrl + i);
+ questionnaire.setStatus(Enumerations.PublicationStatus.ACTIVE);
+ questionnaire.setName("questionnaire" + i);
+ igCreator.addResourceToIG(questionnaire.getName(), questionnaire);
+ }
+
+ PackageInstallationSpec installationSpec = createAndInstallPackageSpec(igCreator, PackageInstallationSpec.InstallModeEnum.STORE_ONLY);
+
+ // test
+ Stream questionnaireStream = myValidationSupport.fetchAllResourcesOfType(Questionnaire.class);
+
+ // verify
+ List questionnaireList = questionnaireStream.toList();
+ assertEquals(resourceCount, questionnaireList.size());
+ }
+
+ private PackageInstallationSpec createAndInstallPackageSpec(ImplementationGuideCreator theIgCreator,
+ PackageInstallationSpec.InstallModeEnum theInstallModeEnum) throws IOException {
+ // create a source directory
+ Path outputFileName = theIgCreator.createTestIG();
+
+ // add some NPM package
+ PackageInstallationSpec spec = new PackageInstallationSpec()
+ .setName(theIgCreator.getPackageName())
+ .setVersion(theIgCreator.getPackageVersion())
+ .setInstallMode(theInstallModeEnum)
+ .setPackageContents(Files.readAllBytes(outputFileName))
+ ;
+ PackageInstallOutcomeJson outcome = myPackageInstallerSvc.install(spec);
+
+ assertNotNull(outcome);
+ assertTrue(outcome.getMessage()
+ .stream().anyMatch(m -> m.contains("Successfully added package")),
+ String.join(", ", outcome.getMessage()));
+ return spec;
+ }
+}
diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml
index f8cb7ce3d777..706e6ea6df14 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 9ae03f275917..fa77cf5a5f75 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 45078b4240eb..5b726fe91de0 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java
index 9215ebebeaa4..aa8cf6fc3296 100644
--- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java
+++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/test/BaseJpaR4Test.java
@@ -89,7 +89,7 @@
import ca.uhn.fhir.jpa.model.dao.JpaPid;
import ca.uhn.fhir.jpa.model.dao.JpaPidFk;
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
-import ca.uhn.fhir.jpa.packages.IPackageInstallerSvc;
+import ca.uhn.fhir.jpa.api.svc.IPackageInstallerSvc;
import ca.uhn.fhir.jpa.partition.IPartitionLookupSvc;
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
index cba336de8be8..fc1616c0e5df 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-repositories/pom.xml b/hapi-fhir-repositories/pom.xml
index 959c45a68970..96daedb22be0 100644
--- a/hapi-fhir-repositories/pom.xml
+++ b/hapi-fhir-repositories/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-cds-hooks/pom.xml b/hapi-fhir-server-cds-hooks/pom.xml
index 97cccb06f8a4..dc26359fe83f 100644
--- a/hapi-fhir-server-cds-hooks/pom.xml
+++ b/hapi-fhir-server-cds-hooks/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml
index b1b0c1a1170f..ee2f7093cb16 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml
index e4e5470cc5ff..3ab3d4f8d176 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml
index 2079aeec9647..be96e7b44ac2 100644
--- a/hapi-fhir-server/pom.xml
+++ b/hapi-fhir-server/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-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 5d008be3f9a2..5c6f27119a85 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 af0bb8f9907d..15e75143f177 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
@@ -21,7 +21,7 @@
ca.uhn.hapi.fhir
hapi-fhir-caching-api
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml
index 6c65c7e0a199..789d4c984fb7 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 61e76650189e..f5edd3b93856 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../../pom.xml
diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml
index f2346f70e2a5..421f1a49d1da 100644
--- a/hapi-fhir-serviceloaders/pom.xml
+++ b/hapi-fhir-serviceloaders/pom.xml
@@ -5,7 +5,7 @@
hapi-deployable-pom
ca.uhn.hapi.fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/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 138626715b75..5343f47de5a6 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 1c877f93e80a..aa9d2c864d56 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 c5e613bf8290..f68ad304f527 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
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 464d47421c0b..e44f814a2f88 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
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 fe94f0e981fa..6dfb41568601 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
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 0fcd5de97b0b..70766bb5d1ba 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml
index 7e3f23c21445..9033ea9987f4 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml
index 23925be7a831..9d382ba609bb 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml
index 5ff8a1b2d355..4b041007dd23 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2-test-utilities/pom.xml b/hapi-fhir-storage-batch2-test-utilities/pom.xml
index a7172a814bf7..6c6b14a55332 100644
--- a/hapi-fhir-storage-batch2-test-utilities/pom.xml
+++ b/hapi-fhir-storage-batch2-test-utilities/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml
index 8b0ae50d53f9..c2586f3c8328 100644
--- a/hapi-fhir-storage-batch2/pom.xml
+++ b/hapi-fhir-storage-batch2/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml
index 22cda489c8e4..1cad32fc4dbd 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml
index f465302f5d02..8b68bbd6e4bd 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml
index 253ba7a36af7..b6fe97b14a01 100644
--- a/hapi-fhir-storage/pom.xml
+++ b/hapi-fhir-storage/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
@@ -136,6 +136,12 @@
jakarta.annotation-api
+
+ io.swagger.core.v3
+ swagger-annotations-jakarta
+ ${swagger_jakarta_version}
+
+
jakarta.servlet
jakarta.servlet-api
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/IPackageInstallerSvc.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/svc/IPackageInstallerSvc.java
similarity index 77%
rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/IPackageInstallerSvc.java
rename to hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/svc/IPackageInstallerSvc.java
index 64587a6f1e52..f610abc052b7 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/IPackageInstallerSvc.java
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/api/svc/IPackageInstallerSvc.java
@@ -1,6 +1,6 @@
/*-
* #%L
- * HAPI FHIR JPA Server
+ * HAPI FHIR Storage api
* %%
* Copyright (C) 2014 - 2025 Smile CDR, Inc.
* %%
@@ -17,7 +17,11 @@
* limitations under the License.
* #L%
*/
-package ca.uhn.fhir.jpa.packages;
+package ca.uhn.fhir.jpa.api.svc;
+
+import ca.uhn.fhir.jpa.packages.PackageDeleteOutcomeJson;
+import ca.uhn.fhir.jpa.packages.PackageInstallOutcomeJson;
+import ca.uhn.fhir.jpa.packages.PackageInstallationSpec;
public interface IPackageInstallerSvc {
diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/NpmPackageUtils.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/NpmPackageUtils.java
new file mode 100644
index 000000000000..26361f450dd0
--- /dev/null
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/NpmPackageUtils.java
@@ -0,0 +1,15 @@
+package ca.uhn.fhir.jpa.packages;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+
+public class NpmPackageUtils {
+
+ /**
+ * Msg structure when an npm package has successfully been added to the cache
+ */
+ public static String SUCCESSFULLY_INSTALLED_MSG_TEMPLATE = "Successfully added package %s#%s to registry";
+
+ public static boolean isSuccessfulMsg(String theMsg) {
+ return isNotBlank(theMsg) && theMsg.contains("Successfully added package");
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageDeleteOutcomeJson.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageDeleteOutcomeJson.java
similarity index 98%
rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageDeleteOutcomeJson.java
rename to hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageDeleteOutcomeJson.java
index 476a71a91103..48385d09db22 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageDeleteOutcomeJson.java
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageDeleteOutcomeJson.java
@@ -1,6 +1,6 @@
/*
* #%L
- * HAPI FHIR JPA Server
+ * HAPI FHIR Storage api
* %%
* Copyright (C) 2014 - 2025 Smile CDR, Inc.
* %%
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallOutcomeJson.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallOutcomeJson.java
similarity index 99%
rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallOutcomeJson.java
rename to hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallOutcomeJson.java
index d4f7d1ffeda1..0176400e237b 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallOutcomeJson.java
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallOutcomeJson.java
@@ -1,6 +1,6 @@
/*
* #%L
- * HAPI FHIR JPA Server
+ * HAPI FHIR Storage api
* %%
* Copyright (C) 2014 - 2025 Smile CDR, Inc.
* %%
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallationSpec.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallationSpec.java
similarity index 99%
rename from hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallationSpec.java
rename to hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallationSpec.java
index 062e40aa634b..307ba6ac245f 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallationSpec.java
+++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallationSpec.java
@@ -1,6 +1,6 @@
/*-
* #%L
- * HAPI FHIR JPA Server
+ * HAPI FHIR Storage api
* %%
* Copyright (C) 2014 - 2025 Smile CDR, Inc.
* %%
diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml
index 9c5e9ba44afa..7b65adf492cf 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml
index d96c71a63e4f..62ae64754e5e 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml
index 892becf18def..aaf95b1d4373 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 f45a0838f896..284e41d99a71 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml
index d1da43c310bf..f201fb82b1b6 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml
index da05da6eed2b..0aef3a270766 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml
index 6284c54e945c..2ea02908f255 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml
index 76bcf64c13de..882eb0220953 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
@@ -209,6 +209,13 @@
org.assertj
assertj-core
+
+
+
+ org.apache.commons
+ commons-compress
+ 1.28.0
+
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/implementationguide/GZipCreatorUtil.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/implementationguide/GZipCreatorUtil.java
new file mode 100644
index 000000000000..fa7f677dac55
--- /dev/null
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/implementationguide/GZipCreatorUtil.java
@@ -0,0 +1,58 @@
+package ca.uhn.fhir.implementationguide;
+
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class GZipCreatorUtil {
+
+ /**
+ * Create a tarball of the provided input and saves it to the provided output.
+ *
+ * @param theSource - the input path to the directory containing all source files to be zipped
+ * @param theOutput - the output path to the gzip file.
+ */
+ public static void createTarGz(Path theSource, Path theOutput) throws IOException {
+ try (OutputStream fos = Files.newOutputStream(theOutput);
+ BufferedOutputStream bos = new BufferedOutputStream(fos);
+ GzipCompressorOutputStream gzos = new GzipCompressorOutputStream(bos);
+ TarArchiveOutputStream taos = new TarArchiveOutputStream(gzos)) {
+ addFilesToTarGz(theSource, "", taos);
+ }
+ }
+
+ private static void addFilesToTarGz(Path thePath, String theParent, TarArchiveOutputStream theTarballOutputStream)
+ throws IOException {
+ String entryName = theParent + thePath.getFileName().toString();
+ TarArchiveEntry entry = new TarArchiveEntry(thePath.toFile(), entryName);
+ theTarballOutputStream.putArchiveEntry(entry);
+
+ if (Files.isRegularFile(thePath)) {
+ // add file
+ try (InputStream fis = Files.newInputStream(thePath)) {
+ byte[] buffer = new byte[1024];
+ int len;
+ while ((len = fis.read(buffer)) > 0) {
+ theTarballOutputStream.write(buffer, 0, len);
+ }
+ }
+ theTarballOutputStream.closeArchiveEntry();
+ } else {
+ theTarballOutputStream.closeArchiveEntry();
+ // walk directory
+ try (DirectoryStream stream = Files.newDirectoryStream(thePath)) {
+ for (Path child : stream) {
+ addFilesToTarGz(child, entryName + "/", theTarballOutputStream);
+ }
+ }
+ }
+ }
+}
diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/implementationguide/ImplementationGuideCreator.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/implementationguide/ImplementationGuideCreator.java
new file mode 100644
index 000000000000..8dc5c9a74411
--- /dev/null
+++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/implementationguide/ImplementationGuideCreator.java
@@ -0,0 +1,202 @@
+package ca.uhn.fhir.implementationguide;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.util.FhirTerser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import jakarta.annotation.Nonnull;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.intellij.lang.annotations.Language;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ImplementationGuideCreator {
+
+ private static final Logger ourLog = LoggerFactory.getLogger(ImplementationGuideCreator.class);
+
+ @Language("JSON")
+ private static final String PACKAGE_JSON_BASE =
+ """
+ {
+ "name": "test.fhir.ca.com",
+ "version": "1.2.3",
+ "tools-version": 3,
+ "type": "fhir.ig",
+ "date": "20200831134427",
+ "license": "not-open-source",
+ "canonical": "http://test-ig.com/fhir/us/providerdataexchange",
+ "url": "file://C:\\\\dev\\\\test-exchange\\\\fsh\\\\build\\\\output",
+ "title": "Test Implementation Guide",
+ "description": "Test Implementation Guide",
+ "fhirVersions": [
+ "4.0.1"
+ ],
+ "dependencies": {
+ },
+ "author": "SmileCDR",
+ "maintainers": [
+ {
+ "name": "Smile",
+ "email": "smilecdr@smiledigitalhealth.com",
+ "url": "https://www.smilecdr.com"
+ }
+ ],
+ "directories": {
+ "lib": "package",
+ "example": "example"
+ }
+ }
+""";
+
+ private Path myDir;
+ private final FhirContext myFhirContext;
+
+ private final FhirTerser myTerser;
+ private final IParser myParser;
+
+ private final String myPackageJson;
+
+ private final String myPackageName;
+ private final String myPackageVersion;
+
+ private final Map myResourcesToInclude = new HashMap<>();
+
+ public ImplementationGuideCreator(@Nonnull FhirContext theFhirContext) throws JsonProcessingException {
+ this(theFhirContext, "test.fhir.ca.com", "1.2.3");
+ }
+
+ public ImplementationGuideCreator(
+ @Nonnull FhirContext theFhirContext, String thePackageName, String thePackageVersion)
+ throws JsonProcessingException {
+ this(
+ theFhirContext,
+ theFhirContext.getVersion().getVersion().getFhirVersionString(),
+ thePackageName,
+ thePackageVersion);
+ }
+
+ /**
+ * Constructor
+ * @param theFhirContext - FhirContext to use
+ * @param theFhirVersion - fhir version to use (provided to allow setting a custom value different form the FhirContext)
+ * @param theName - name to set in package.json's name field
+ * @param theVersion - version to set in package.json's version field
+ */
+ @SuppressWarnings("unchecked")
+ public ImplementationGuideCreator(
+ @Nonnull FhirContext theFhirContext, String theFhirVersion, String theName, String theVersion)
+ throws JsonProcessingException {
+ myFhirContext = theFhirContext;
+ myTerser = myFhirContext.newTerser();
+ myParser = myFhirContext.newJsonParser();
+ myPackageName = theName;
+ myPackageVersion = theVersion;
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.enable(SerializationFeature.INDENT_OUTPUT);
+
+ Map mapJson = mapper.readValue(PACKAGE_JSON_BASE, Map.class);
+
+ // update provided values
+ List versions = (List) mapJson.get("fhirVersions");
+ versions.clear();
+ versions.add(theFhirVersion);
+ mapJson.replace("name", myPackageName);
+ mapJson.replace("version", myPackageVersion);
+
+ myPackageJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapJson);
+
+ ourLog.info(myPackageJson);
+ }
+
+ /**
+ * Sets the directory where files will be created.
+ * Should be a temp dir for tests.
+ */
+ public ImplementationGuideCreator setDirectory(Path thePath) {
+ myDir = thePath;
+ return this;
+ }
+
+ public String getPackageName() {
+ return myPackageName;
+ }
+
+ public String getPackageVersion() {
+ return myPackageVersion;
+ }
+
+ /**
+ * Adds a Resource to the ImplementationGuide.
+ * No validation is done
+ */
+ public void addResourceToIG(String theFileName, IBaseResource theResource) {
+ myResourcesToInclude.put(theFileName, theResource);
+ }
+
+ private void verifyDir() {
+ String msg = "Directory must be set first.";
+
+ assertNotNull(myDir, msg);
+ assertTrue(isNotBlank(myDir.toString()), msg);
+ }
+
+ /**
+ * Creates an the IG from all the provided SearchParameters,
+ * zips them up, and provides the path to the newly created gzip file.
+ */
+ public Path createTestIG() throws IOException {
+ verifyDir();
+
+ Path sourceDir = Files.createDirectory(Path.of(myDir.toString(), "package"));
+
+ // add the package.json
+ addFileToDir(myPackageJson, "package.json", sourceDir);
+
+ // add search parameters
+ int index = 0;
+ for (Map.Entry nameAndResource : myResourcesToInclude.entrySet()) {
+ addFileToDir(
+ myParser.encodeResourceToString(nameAndResource.getValue()),
+ nameAndResource.getKey() + ".json",
+ sourceDir);
+ index++;
+ }
+
+ // we can add other resources here (not req'd for now)
+
+ Path outputFileName = Files.createFile(Path.of(myDir.toString(), myPackageName + ".gz.tar"));
+ GZipCreatorUtil.createTarGz(sourceDir, outputFileName);
+ return outputFileName;
+ }
+
+ private void addFileToDir(String theContent, String theFileName, Path theOutputPath) throws IOException {
+ byte[] bytes = new byte[1024];
+ int length = 0;
+
+ try (FileOutputStream outputStream = new FileOutputStream(theOutputPath.toString() + "/" + theFileName)) {
+ try (InputStream stream = new ByteArrayInputStream(theContent.getBytes(StandardCharsets.UTF_8))) {
+ while ((length = stream.read(bytes)) >= 0) {
+ outputStream.write(bytes, 0, length);
+ }
+ }
+ }
+ }
+}
diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml
index 9ea51c6148c7..ad5f4d1b3b28 100644
--- a/hapi-fhir-testpage-overlay/pom.xml
+++ b/hapi-fhir-testpage-overlay/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml
index 6a34b6f99b5a..68524e60d870 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 db3793f45f94..5583b14a1076 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 39ba4d6566d0..7f5491af0eb1 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 6e17f5ea8897..002664fc2187 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation-resources-r4b/pom.xml b/hapi-fhir-validation-resources-r4b/pom.xml
index 2ad667edad8d..40a594ec1ad7 100644
--- a/hapi-fhir-validation-resources-r4b/pom.xml
+++ b/hapi-fhir-validation-resources-r4b/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-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 9340821d28c6..91cc4e0efff0 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index 1732a39bc4db..64247b33c7b4 100644
--- a/hapi-fhir-validation/pom.xml
+++ b/hapi-fhir-validation/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml
index 1948548c7350..c54f9da44688 100644
--- a/hapi-tinder-plugin/pom.xml
+++ b/hapi-tinder-plugin/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml
index f927837f4a33..71db820a74cf 100644
--- a/hapi-tinder-test/pom.xml
+++ b/hapi-tinder-test/pom.xml
@@ -4,7 +4,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../pom.xml
diff --git a/osgi/hapi-fhir-karaf-features/pom.xml b/osgi/hapi-fhir-karaf-features/pom.xml
index 0b7e5ba52da1..95f6a3c0e745 100644
--- a/osgi/hapi-fhir-karaf-features/pom.xml
+++ b/osgi/hapi-fhir-karaf-features/pom.xml
@@ -6,7 +6,7 @@
ca.uhn.hapi.fhir
hapi-fhir-karaf
- 4.0.0-SNAPSHOT
+ 4.0.1-SNAPSHOT
../pom.xml
diff --git a/osgi/hapi-fhir-karaf-integration-tests/pom.xml b/osgi/hapi-fhir-karaf-integration-tests/pom.xml
index cfc45cc7a10f..1dacc68d0ebd 100644
--- a/osgi/hapi-fhir-karaf-integration-tests/pom.xml
+++ b/osgi/hapi-fhir-karaf-integration-tests/pom.xml
@@ -20,7 +20,7 @@
ca.uhn.hapi.fhir
hapi-fhir-karaf
- 4.0.0-SNAPSHOT
+ 4.0.1-SNAPSHOT
../pom.xml
diff --git a/osgi/pom.xml b/osgi/pom.xml
index 0597d8537a5c..84820ef59078 100644
--- a/osgi/pom.xml
+++ b/osgi/pom.xml
@@ -20,7 +20,7 @@
ca.uhn.hapi.fhir
hapi-deployable-pom
- 4.0.0-SNAPSHOT
+ 4.0.1-SNAPSHOT
../hapi-deployable-pom/pom.xml
diff --git a/pom.xml b/pom.xml
index f5858a17d999..084f4ae5fb22 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-fhir
pom
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
HAPI-FHIR
An open-source implementation of the FHIR specification in Java.
diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
index 9da7c662cbfe..21219df3051f 100644
--- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
+++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml
@@ -7,7 +7,7 @@
ca.uhn.hapi.fhir
hapi-fhir
- 8.7.0-SNAPSHOT
+ 8.7.1-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 20f46c957cd7..08de24cc6543 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
- 8.7.0-SNAPSHOT
+ 8.7.1-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 cd20fcec18ed..9606788266e2 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
- 8.7.0-SNAPSHOT
+ 8.7.1-SNAPSHOT
../../pom.xml