Fix #129 - Resources in JPA server could not be undeleted

This commit is contained in:
James Agnew 2015-03-19 13:40:40 +01:00
parent 1c46989d00
commit 1598e7ec5a
3 changed files with 99 additions and 51 deletions

View File

@ -187,7 +187,8 @@ public abstract class BaseFhirDao implements IDao {
String typeString = nextValue.getReference().getResourceType(); String typeString = nextValue.getReference().getResourceType();
if (isBlank(typeString)) { if (isBlank(typeString)) {
throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue()); throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - "
+ nextValue.getReference().getValue());
} }
Class<? extends IBaseResource> type = getContext().getResourceDefinition(typeString).getImplementingClass(); Class<? extends IBaseResource> type = getContext().getResourceDefinition(typeString).getImplementingClass();
String id = nextValue.getReference().getIdPart(); String id = nextValue.getReference().getIdPart();
@ -212,7 +213,8 @@ public abstract class BaseFhirDao implements IDao {
valueOf = translateForcedIdToPid(nextValue.getReference()); valueOf = translateForcedIdToPid(nextValue.getReference());
} catch (Exception e) { } catch (Exception e) {
String resName = getContext().getResourceDefinition(type).getName(); String resName = getContext().getResourceDefinition(type).getName();
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit + " (this is an invalid ID, must be numeric on this server)"); throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit
+ " (this is an invalid ID, must be numeric on this server)");
} }
ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf); ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf);
if (target == null) { if (target == null) {
@ -892,7 +894,8 @@ public abstract class BaseFhirDao implements IDao {
return updateEntity(theResource, entity, theUpdateHistory, theDeletedTimestampOrNull, true, true); return updateEntity(theResource, entity, theUpdateHistory, theDeletedTimestampOrNull, true, true);
} }
protected ResourceTable updateEntity(final IResource theResource, ResourceTable entity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing, boolean theUpdateVersion) { protected ResourceTable updateEntity(final IResource theResource, ResourceTable entity, boolean theUpdateHistory, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion) {
if (entity.getPublished() == null) { if (entity.getPublished() == null) {
entity.setPublished(new Date()); entity.setPublished(new Date());
} }
@ -900,7 +903,8 @@ public abstract class BaseFhirDao implements IDao {
if (theResource != null) { if (theResource != null) {
String resourceType = myContext.getResourceDefinition(theResource).getName(); String resourceType = myContext.getResourceDefinition(theResource).getName();
if (isNotBlank(entity.getResourceType()) && !entity.getResourceType().equals(resourceType)) { if (isNotBlank(entity.getResourceType()) && !entity.getResourceType().equals(resourceType)) {
throw new UnprocessableEntityException("Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]"); throw new UnprocessableEntityException("Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with ["
+ resourceType + "]");
} }
} }
@ -938,7 +942,11 @@ public abstract class BaseFhirDao implements IDao {
entity.setDeleted(theDeletedTimestampOrNull); entity.setDeleted(theDeletedTimestampOrNull);
entity.setUpdated(theDeletedTimestampOrNull); entity.setUpdated(theDeletedTimestampOrNull);
} else if (thePerformIndexing) { } else {
entity.setDeleted(null);
if (thePerformIndexing) {
stringParams = extractSearchParamStrings(entity, theResource); stringParams = extractSearchParamStrings(entity, theResource);
numberParams = extractSearchParamNumber(entity, theResource); numberParams = extractSearchParamNumber(entity, theResource);
@ -979,6 +987,8 @@ public abstract class BaseFhirDao implements IDao {
} }
}
if (entity.getId() == null) { if (entity.getId() == null) {
myEntityManager.persist(entity); myEntityManager.persist(entity);

View File

@ -395,7 +395,7 @@ public class FhirResourceDaoDstu2Test {
} }
@Test @Test
public void testDelete() { public void testDeleteResource() {
int initialHistory = ourPatientDao.history(null).size(); int initialHistory = ourPatientDao.history(null).size();
IdDt id1; IdDt id1;
@ -404,13 +404,13 @@ public class FhirResourceDaoDstu2Test {
{ {
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001"); patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester_testDelete").addGiven("Joe"); patient.addName().addFamily("Tester_testDeleteResource").addGiven("Joe");
id1 = ourPatientDao.create(patient).getId(); id1 = ourPatientDao.create(patient).getId();
} }
{ {
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("002"); patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().addFamily("Tester_testDelete").addGiven("John"); patient.addName().addFamily("Tester_testDeleteResource").addGiven("John");
id2 = ourPatientDao.create(patient).getId(); id2 = ourPatientDao.create(patient).getId();
} }
{ {
@ -421,7 +421,7 @@ public class FhirResourceDaoDstu2Test {
ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[] { id1, id2, id2b }); ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[] { id1, id2, id2b });
Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>(); Map<String, IQueryParameterType> params = new HashMap<String, IQueryParameterType>();
params.put(Patient.SP_FAMILY, new StringDt("Tester_testDelete")); params.put(Patient.SP_FAMILY, new StringDt("Tester_testDeleteResource"));
List<Patient> patients = toList(ourPatientDao.search(params)); List<Patient> patients = toList(ourPatientDao.search(params));
assertEquals(2, patients.size()); assertEquals(2, patients.size());
@ -457,6 +457,39 @@ public class FhirResourceDaoDstu2Test {
} }
@Test
public void testDeleteThenUndelete() {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
IdDt id = ourPatientDao.create(patient).getId();
assertThat(id.getValue(), endsWith("/_history/1"));
// should be ok
ourPatientDao.read(id.toUnqualifiedVersionless());
// Delete it
ourPatientDao.delete(id.toUnqualifiedVersionless());
try {
ourPatientDao.read(id.toUnqualifiedVersionless());
fail();
} catch (ResourceGoneException e) {
// expected
}
patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
patient.setId(id.toUnqualifiedVersionless());
IdDt id2 = ourPatientDao.update(patient).getId();
assertThat(id2.getValue(), endsWith("/_history/3"));
IdDt gotId = ourPatientDao.read(id.toUnqualifiedVersionless()).getId();
assertEquals(id2, gotId);
}
@Test @Test
public void testDeleteWithMatchUrl() { public void testDeleteWithMatchUrl() {
String methodName = "testDeleteWithMatchUrl"; String methodName = "testDeleteWithMatchUrl";

View File

@ -30,6 +30,11 @@
oretty print behaviour in the Fluent Client. Thanks to Stackoverflow oretty print behaviour in the Fluent Client. Thanks to Stackoverflow
user ewall for the idea. user ewall for the idea.
</action> </action>
<action type="fix" issue="129">
JPA Server did not mark a resource as "no longer deleted" if it
was updated after being deleted. Thanks to Elliott Lavy and Lloyd
McKenzie for reporting!
</action>
</release> </release>
<release version="0.9" date="2015-Mar-14"> <release version="0.9" date="2015-Mar-14">
<action type="add"> <action type="add">