More work on multitenancy
This commit is contained in:
parent
219332e9e3
commit
8d8c657ce2
|
@ -8,6 +8,8 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
import ca.uhn.fhir.jpa.model.entity.PartitionId;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -30,8 +32,6 @@ public class RequestPartitionHelperService {
|
||||||
private FhirContext myFhirContext;
|
private FhirContext myFhirContext;
|
||||||
|
|
||||||
public RequestPartitionHelperService() {
|
public RequestPartitionHelperService() {
|
||||||
// FIXME: document this list
|
|
||||||
|
|
||||||
myPartitioningBlacklist = new HashSet<>();
|
myPartitioningBlacklist = new HashSet<>();
|
||||||
|
|
||||||
// Infrastructure
|
// Infrastructure
|
||||||
|
@ -77,10 +77,6 @@ public class RequestPartitionHelperService {
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public PartitionId determineCreatePartitionForRequest(@Nullable RequestDetails theRequest, @Nonnull IBaseResource theResource) {
|
public PartitionId determineCreatePartitionForRequest(@Nullable RequestDetails theRequest, @Nonnull IBaseResource theResource) {
|
||||||
String resourceType = myFhirContext.getResourceDefinition(theResource).getName();
|
|
||||||
if (myPartitioningBlacklist.contains(resourceType)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
PartitionId partitionId = null;
|
PartitionId partitionId = null;
|
||||||
if (myDaoConfig.isPartitioningEnabled()) {
|
if (myDaoConfig.isPartitioningEnabled()) {
|
||||||
|
@ -99,10 +95,10 @@ public class RequestPartitionHelperService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validatePartition(@Nullable PartitionId thePartitionId, @Nonnull String theResourceName) {
|
private void validatePartition(@Nullable PartitionId thePartitionId, @Nonnull String theResourceName) {
|
||||||
if (thePartitionId != null) {
|
if (thePartitionId != null && thePartitionId.getPartitionId() != null) {
|
||||||
if (myPartitioningBlacklist.contains(theResourceName)) {
|
if (myPartitioningBlacklist.contains(theResourceName)) {
|
||||||
String msg = myFhirContext.getLocalizer().getMessageSanitized(RequestPartitionHelperService.class, "blacklistedResourceTypeForPartitioning", theResourceName);
|
String msg = myFhirContext.getLocalizer().getMessageSanitized(RequestPartitionHelperService.class, "blacklistedResourceTypeForPartitioning", theResourceName);
|
||||||
throw new InvalidRequestException(msg);
|
throw new UnprocessableEntityException(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.model.entity.*;
|
import ca.uhn.fhir.jpa.model.entity.*;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
|
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
|
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.param.DateParam;
|
import ca.uhn.fhir.rest.param.DateParam;
|
||||||
|
@ -16,6 +15,7 @@ import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -33,7 +33,6 @@ import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
@ -53,11 +52,7 @@ import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
|
||||||
* This should be marked as DIRTIES_CONTEXT because it drops an index
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
|
|
||||||
public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PartitioningR4Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PartitioningR4Test.class);
|
||||||
|
@ -65,7 +60,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
private MyInterceptor myPartitionInterceptor;
|
private MyInterceptor myPartitionInterceptor;
|
||||||
private LocalDate myPartitionDate;
|
private LocalDate myPartitionDate;
|
||||||
private int myPartitionId;
|
private int myPartitionId;
|
||||||
private static boolean ourHaveDroppedForcedIdUniqueConstraint;
|
private boolean myHaveDroppedForcedIdUniqueConstraint;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void after() {
|
public void after() {
|
||||||
|
@ -75,6 +70,13 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
myInterceptorRegistry.unregisterInterceptorsIf(t -> t instanceof MyInterceptor);
|
myInterceptorRegistry.unregisterInterceptorsIf(t -> t instanceof MyInterceptor);
|
||||||
myInterceptor = null;
|
myInterceptor = null;
|
||||||
|
|
||||||
|
if (myHaveDroppedForcedIdUniqueConstraint) {
|
||||||
|
runInTransaction(() -> {
|
||||||
|
myEntityManager.createNativeQuery("delete from HFJ_FORCED_ID").executeUpdate();
|
||||||
|
myEntityManager.createNativeQuery("alter table HFJ_FORCED_ID add constraint IDX_FORCEDID_TYPE_FID unique (RESOURCE_TYPE, FORCED_ID)");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -91,14 +93,6 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
myPartitionInterceptor = new MyInterceptor();
|
myPartitionInterceptor = new MyInterceptor();
|
||||||
myInterceptorRegistry.registerInterceptor(myPartitionInterceptor);
|
myInterceptorRegistry.registerInterceptor(myPartitionInterceptor);
|
||||||
|
|
||||||
if (!ourHaveDroppedForcedIdUniqueConstraint) {
|
|
||||||
runInTransaction(() -> {
|
|
||||||
myEntityManager.createNativeQuery("alter table " + ForcedId.HFJ_FORCED_ID + " drop constraint " + ForcedId.IDX_FORCEDID_TYPE_FID).executeUpdate();
|
|
||||||
});
|
|
||||||
ourHaveDroppedForcedIdUniqueConstraint = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -136,7 +130,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
runInTransaction(() -> {
|
runInTransaction(() -> {
|
||||||
// HFJ_RESOURCE
|
// HFJ_RESOURCE
|
||||||
ResourceTable resourceTable = myResourceTableDao.findById(id).orElseThrow(IllegalArgumentException::new);
|
ResourceTable resourceTable = myResourceTableDao.findById(id).orElseThrow(IllegalArgumentException::new);
|
||||||
assertEquals(myPartitionId, resourceTable.getPartitionId().getPartitionId().intValue());
|
assertEquals(null, resourceTable.getPartitionId().getPartitionId());
|
||||||
assertEquals(myPartitionDate, resourceTable.getPartitionId().getPartitionDate());
|
assertEquals(myPartitionDate, resourceTable.getPartitionId().getPartitionDate());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -156,8 +150,8 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
try {
|
try {
|
||||||
mySearchParameterDao.create(sp);
|
mySearchParameterDao.create(sp);
|
||||||
fail();
|
fail();
|
||||||
} catch (PreconditionFailedException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals("", e.getMessage());
|
assertEquals("Resource type SearchParameter can not be partitioned", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,6 +677,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRead_ForcedId_AllPartition_WithDuplicate() {
|
public void testRead_ForcedId_AllPartition_WithDuplicate() {
|
||||||
|
dropForcedIdUniqueConstraint();
|
||||||
IIdType patientIdNull = createPatient(null, withActiveTrue(), withId("FOO"));
|
IIdType patientIdNull = createPatient(null, withActiveTrue(), withId("FOO"));
|
||||||
IIdType patientId1 = createPatient(1, withActiveTrue(), withId("FOO"));
|
IIdType patientId1 = createPatient(1, withActiveTrue(), withId("FOO"));
|
||||||
IIdType patientId2 = createPatient(2, withActiveTrue(), withId("FOO"));
|
IIdType patientId2 = createPatient(2, withActiveTrue(), withId("FOO"));
|
||||||
|
@ -1165,6 +1160,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createUniqueCompositeSp() {
|
private void createUniqueCompositeSp() {
|
||||||
|
addCreateNoPartition();
|
||||||
SearchParameter sp = new SearchParameter();
|
SearchParameter sp = new SearchParameter();
|
||||||
sp.setId("SearchParameter/patient-birthdate");
|
sp.setId("SearchParameter/patient-birthdate");
|
||||||
sp.setType(Enumerations.SearchParamType.DATE);
|
sp.setType(Enumerations.SearchParamType.DATE);
|
||||||
|
@ -1174,6 +1170,7 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
sp.addBase("Patient");
|
sp.addBase("Patient");
|
||||||
mySearchParameterDao.update(sp);
|
mySearchParameterDao.update(sp);
|
||||||
|
|
||||||
|
addCreateNoPartition();
|
||||||
sp = new SearchParameter();
|
sp = new SearchParameter();
|
||||||
sp.setId("SearchParameter/patient-birthdate-unique");
|
sp.setId("SearchParameter/patient-birthdate-unique");
|
||||||
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
sp.setType(Enumerations.SearchParamType.COMPOSITE);
|
||||||
|
@ -1191,6 +1188,13 @@ public class PartitioningR4Test extends BaseJpaR4SystemTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void dropForcedIdUniqueConstraint() {
|
||||||
|
runInTransaction(() -> {
|
||||||
|
myEntityManager.createNativeQuery("alter table " + ForcedId.HFJ_FORCED_ID + " drop constraint " + ForcedId.IDX_FORCEDID_TYPE_FID).executeUpdate();
|
||||||
|
});
|
||||||
|
myHaveDroppedForcedIdUniqueConstraint = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void addCreatePartition(Integer thePartitionId, LocalDate thePartitionDate) {
|
private void addCreatePartition(Integer thePartitionId, LocalDate thePartitionDate) {
|
||||||
Validate.notNull(thePartitionId);
|
Validate.notNull(thePartitionId);
|
||||||
PartitionId partitionId = new PartitionId(thePartitionId, thePartitionDate);
|
PartitionId partitionId = new PartitionId(thePartitionId, thePartitionDate);
|
||||||
|
|
Loading…
Reference in New Issue