Fixed package loading to enable loading of binary package files into the default partition when partitioning is enabled.
This commit is contained in:
parent
86f254cd66
commit
446dd5c782
|
@ -29,6 +29,7 @@ import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
|
|||
import ca.uhn.fhir.jpa.dao.data.INpmPackageDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionResourceDao;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.entity.NpmPackageEntity;
|
||||
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity;
|
||||
import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionResourceEntity;
|
||||
|
@ -54,6 +55,7 @@ import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
|
@ -115,6 +117,8 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
|
|||
private FhirContext myCtx;
|
||||
@Autowired
|
||||
private PlatformTransactionManager myTxManager;
|
||||
@Autowired
|
||||
private PartitionSettings myPartitionSettings;
|
||||
|
||||
@Override
|
||||
public NpmPackage loadPackageFromCacheOnly(String theId, @Nullable String theVersion) {
|
||||
|
@ -205,7 +209,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
|
|||
|
||||
return newTxTemplate().execute(tx -> {
|
||||
|
||||
ResourceTable persistedPackage = (ResourceTable) getBinaryDao().create(binary).getEntity();
|
||||
ResourceTable persistedPackage = createResourceBinary(binary);
|
||||
NpmPackageEntity pkg = myPackageDao.findByPackageId(thePackageId).orElseGet(() -> createPackage(npmPackage));
|
||||
NpmPackageVersionEntity packageVersion = myPackageVersionDao.findByPackageIdAndVersion(thePackageId, packageVersionId).orElse(null);
|
||||
if (packageVersion != null) {
|
||||
|
@ -282,7 +286,7 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
|
|||
byte[] minimizedContents = packageContext.newJsonParser().encodeResourceToString(resource).getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
IBaseBinary resourceBinary = createPackageResourceBinary(nextFile, minimizedContents, contentType);
|
||||
ResourceTable persistedResource = (ResourceTable) getBinaryDao().create(resourceBinary).getEntity();
|
||||
ResourceTable persistedResource = createResourceBinary(resourceBinary);
|
||||
|
||||
NpmPackageVersionResourceEntity resourceEntity = new NpmPackageVersionResourceEntity();
|
||||
resourceEntity.setPackageVersion(packageVersion);
|
||||
|
@ -319,6 +323,16 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
|
|||
|
||||
}
|
||||
|
||||
private ResourceTable createResourceBinary(IBaseBinary theResourceBinary) {
|
||||
|
||||
if (myPartitionSettings.isPartitioningEnabled()) {
|
||||
PackageBinaryRequestDetails myRequestDetails = new PackageBinaryRequestDetails();
|
||||
return (ResourceTable) getBinaryDao().create(theResourceBinary, myRequestDetails).getEntity();
|
||||
} else {
|
||||
return (ResourceTable) getBinaryDao().create(theResourceBinary).getEntity();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean updateCurrentVersionFlagForAllPackagesBasedOnNewIncomingVersion(String thePackageId, String thePackageVersion) {
|
||||
Collection<NpmPackageVersionEntity> existingVersions = myPackageVersionDao.findByPackageId(thePackageId);
|
||||
boolean retVal = true;
|
||||
|
@ -578,16 +592,14 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
|
|||
|
||||
ExpungeOptions options = new ExpungeOptions();
|
||||
options.setExpungeDeletedResources(true).setExpungeOldVersions(true);
|
||||
getBinaryDao().delete(next.getResourceBinary().getIdDt().toVersionless());
|
||||
getBinaryDao().forceExpungeInExistingTransaction(next.getResourceBinary().getIdDt().toVersionless(), options, null);
|
||||
deleteAndExpungeResourceBinary(next.getResourceBinary().getIdDt().toVersionless(), options);
|
||||
}
|
||||
|
||||
myPackageVersionDao.delete(packageVersion.get());
|
||||
|
||||
ExpungeOptions options = new ExpungeOptions();
|
||||
options.setExpungeDeletedResources(true).setExpungeOldVersions(true);
|
||||
getBinaryDao().delete(packageVersion.get().getPackageBinary().getIdDt().toVersionless());
|
||||
getBinaryDao().forceExpungeInExistingTransaction(packageVersion.get().getPackageBinary().getIdDt().toVersionless(), options, null);
|
||||
deleteAndExpungeResourceBinary(packageVersion.get().getPackageBinary().getIdDt().toVersionless(), options);
|
||||
|
||||
Collection<NpmPackageVersionEntity> remainingVersions = myPackageVersionDao.findByPackageId(thePackageId);
|
||||
if (remainingVersions.size() == 0) {
|
||||
|
@ -622,6 +634,19 @@ public class JpaPackageCache extends BasePackageCacheManager implements IHapiPac
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private void deleteAndExpungeResourceBinary(IIdType theResourceBinaryId, ExpungeOptions theOptions) {
|
||||
|
||||
if (myPartitionSettings.isPartitioningEnabled()) {
|
||||
PackageBinaryRequestDetails myRequestDetails = new PackageBinaryRequestDetails();
|
||||
getBinaryDao().delete(theResourceBinaryId, myRequestDetails).getEntity();
|
||||
getBinaryDao().forceExpungeInExistingTransaction(theResourceBinaryId, theOptions, myRequestDetails);
|
||||
} else {
|
||||
getBinaryDao().delete(theResourceBinaryId).getEntity();
|
||||
getBinaryDao().forceExpungeInExistingTransaction(theResourceBinaryId, theOptions, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nonnull
|
||||
public List<Predicate> createSearchPredicates(PackageSearchSpec thePackageSearchSpec, CriteriaBuilder theCb, Root<NpmPackageVersionEntity> theRoot) {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package ca.uhn.fhir.jpa.packages;
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
||||
|
||||
public class PackageBinaryRequestDetails extends SystemRequestDetails {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
public PackageBinaryRequestDetails() {
|
||||
super(new MyInterceptorBroadcaster());
|
||||
}
|
||||
|
||||
private static class MyInterceptorBroadcaster implements IInterceptorBroadcaster {
|
||||
|
||||
@Override
|
||||
public boolean callHooks(Pointcut thePointcut, HookParams theParams) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object callHooksAndReturnObject(Pointcut thePointcut, HookParams theParams) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHooks(Pointcut thePointcut) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -28,6 +28,7 @@ import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
|||
import ca.uhn.fhir.jpa.entity.PartitionEntity;
|
||||
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.packages.PackageBinaryRequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
|
@ -68,14 +69,20 @@ public class RequestPartitionHelperSvc implements IRequestPartitionHelperSvc {
|
|||
myPartitioningBlacklist.add("Subscription");
|
||||
myPartitioningBlacklist.add("SearchParameter");
|
||||
|
||||
// Validation
|
||||
// Validation and Conformance
|
||||
myPartitioningBlacklist.add("StructureDefinition");
|
||||
myPartitioningBlacklist.add("Questionnaire");
|
||||
myPartitioningBlacklist.add("CapabilityStatement");
|
||||
myPartitioningBlacklist.add("CompartmentDefinition");
|
||||
myPartitioningBlacklist.add("OperationDefinition");
|
||||
|
||||
// Terminology
|
||||
myPartitioningBlacklist.add("ConceptMap");
|
||||
myPartitioningBlacklist.add("CodeSystem");
|
||||
myPartitioningBlacklist.add("ValueSet");
|
||||
myPartitioningBlacklist.add("NamingSystem");
|
||||
myPartitioningBlacklist.add("StructureMap");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,7 +98,7 @@ public class RequestPartitionHelperSvc implements IRequestPartitionHelperSvc {
|
|||
|
||||
if (myPartitionSettings.isPartitioningEnabled()) {
|
||||
// Handle system requests
|
||||
if (theRequest == null && myPartitioningBlacklist.contains(theResourceType)) {
|
||||
if ((theRequest == null && myPartitioningBlacklist.contains(theResourceType)) || theRequest instanceof SystemRequestDetails) {
|
||||
return RequestPartitionId.defaultPartition();
|
||||
}
|
||||
|
||||
|
@ -123,7 +130,7 @@ public class RequestPartitionHelperSvc implements IRequestPartitionHelperSvc {
|
|||
|
||||
if (myPartitionSettings.isPartitioningEnabled()) {
|
||||
// Handle system requests
|
||||
if (theRequest == null && myPartitioningBlacklist.contains(theResourceType)) {
|
||||
if ((theRequest == null && myPartitioningBlacklist.contains(theResourceType)) || theRequest instanceof SystemRequestDetails) {
|
||||
return RequestPartitionId.defaultPartition();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package ca.uhn.fhir.jpa.partition;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.IRestfulServerDefaults;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
public class SystemRequestDetails extends RequestDetails {
|
||||
public SystemRequestDetails(IInterceptorBroadcaster theInterceptorBroadcaster) {
|
||||
super(theInterceptorBroadcaster);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] getByteStreamRequestContents() {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Charset getCharset() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirContext getFhirContext() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getHeaders(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String theAttributeName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String theAttributeName, Object theAttributeValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getReader() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRestfulServerDefaults getServer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerBaseForRequest() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,21 +1,20 @@
|
|||
package ca.uhn.fhir.jpa.packages;
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||
import ca.uhn.fhir.jpa.dao.data.INpmPackageDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.INpmPackageVersionDao;
|
||||
import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.util.JsonUtil;
|
||||
import org.hl7.fhir.utilities.npm.IPackageCacheManager;
|
||||
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
|
@ -28,6 +27,16 @@ public class JpaPackageCacheTest extends BaseJpaR4Test {
|
|||
private INpmPackageDao myPackageDao;
|
||||
@Autowired
|
||||
private INpmPackageVersionDao myPackageVersionDao;
|
||||
@Autowired
|
||||
private IInterceptorService myInterceptorService;
|
||||
@Autowired
|
||||
private RequestTenantPartitionInterceptor myRequestTenantPartitionInterceptor;
|
||||
|
||||
@AfterEach
|
||||
public void disablePartitioning() {
|
||||
myPartitionSettings.setPartitioningEnabled(false);
|
||||
myInterceptorService.unregisterInterceptor(myRequestTenantPartitionInterceptor);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
|
@ -53,6 +62,36 @@ public class JpaPackageCacheTest extends BaseJpaR4Test {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSaveAndDeletePackagePartitionsEnabled() throws IOException {
|
||||
myPartitionSettings.setPartitioningEnabled(true);
|
||||
myInterceptorService.registerInterceptor(myRequestTenantPartitionInterceptor);
|
||||
|
||||
try (InputStream stream = IgInstallerDstu3Test.class.getResourceAsStream("/packages/basisprofil.de.tar.gz")) {
|
||||
myPackageCacheManager.addPackageToCache("basisprofil.de", "0.2.40", stream, "basisprofil.de");
|
||||
}
|
||||
|
||||
NpmPackage pkg;
|
||||
|
||||
pkg = myPackageCacheManager.loadPackage("basisprofil.de", null);
|
||||
assertEquals("0.2.40", pkg.version());
|
||||
|
||||
pkg = myPackageCacheManager.loadPackage("basisprofil.de", "0.2.40");
|
||||
assertEquals("0.2.40", pkg.version());
|
||||
|
||||
try {
|
||||
myPackageCacheManager.loadPackage("basisprofil.de", "99");
|
||||
fail();
|
||||
} catch (ResourceNotFoundException e) {
|
||||
assertEquals("Unable to locate package basisprofil.de#99", e.getMessage());
|
||||
}
|
||||
|
||||
PackageDeleteOutcomeJson deleteOutcomeJson = myPackageCacheManager.uninstallPackage("basisprofil.de", "0.2.40");
|
||||
List<String> deleteOutcomeMsgs = deleteOutcomeJson.getMessage();
|
||||
assertEquals("Deleting package basisprofil.de#0.2.40", deleteOutcomeMsgs.get(0));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSavePackageWithLongDescription() throws IOException {
|
||||
try (InputStream stream = IgInstallerDstu3Test.class.getResourceAsStream("/packages/package-davinci-cdex-0.2.0.tgz")) {
|
||||
|
|
Loading…
Reference in New Issue