Move PATCH to hapi-fhir-storage (#3763)

* Not the final version

* Support PATCH operation

* minor modifications

* minor modifications

* Final version

* Final version
This commit is contained in:
Qingyixia 2022-07-11 10:56:22 -04:00 committed by GitHub
parent 0526da080b
commit 3d4556b70b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 24 additions and 10 deletions

View File

@ -80,9 +80,9 @@ ca.uhn.fhir.jpa.config.HapiFhirHibernateJpaDialect.forcedIdConstraintFailure=The
ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor.externalizedBinaryStorageExtensionFoundInRequestBody=Illegal extension found in request payload - URL "{0}" and value "{1}" ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor.externalizedBinaryStorageExtensionFoundInRequestBody=Illegal extension found in request payload - URL "{0}" and value "{1}"
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlInvalidResourceType=Invalid match URL "{0}" - Unknown resource type: "{1}" ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlInvalidResourceType=Invalid match URL "{0}" - Unknown resource type: "{1}"
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlNoMatches=Invalid match URL "{0}" - No resources match this search ca.uhn.fhir.jpa.dao.BaseStorageDao.invalidMatchUrlNoMatches=Invalid match URL "{0}" - No resources match this search
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlMultipleMatches=Invalid match URL "{0}" - Multiple resources match this search ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlMultipleMatches=Invalid match URL "{0}" - Multiple resources match this search
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationWithMultipleMatchFailure=Failed to {0} resource with match URL "{1}" because this search matched {2} resources ca.uhn.fhir.jpa.dao.BaseStorageDao.transactionOperationWithMultipleMatchFailure=Failed to {0} resource with match URL "{1}" because this search matched {2} resources
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedNoId=Failed to {0} resource in transaction because no ID was provided ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedNoId=Failed to {0} resource in transaction because no ID was provided
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedUnknownId=Failed to {0} resource in transaction because no resource could be found with ID {1} ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.transactionOperationFailedUnknownId=Failed to {0} resource in transaction because no resource could be found with ID {1}
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.uniqueIndexConflictFailure=Can not create resource of type {0} as it would create a duplicate unique index matching query: {1} (existing index belongs to {2}, new unique index created by {3}) ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.uniqueIndexConflictFailure=Can not create resource of type {0} as it would create a duplicate unique index matching query: {1} (existing index belongs to {2}, new unique index created by {3})

View File

@ -0,0 +1,5 @@
---
type: add
issue: 3762
jira: SMILE-4451
title: "JPA server patch operation has been moved to the hapi-fhir-storage project, for reuse in other backends."

View File

@ -266,7 +266,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (isNotBlank(theIfNoneExist)) { if (isNotBlank(theIfNoneExist)) {
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theIfNoneExist, myResourceType, theTransactionDetails, theRequest); Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theIfNoneExist, myResourceType, theTransactionDetails, theRequest);
if (match.size() > 1) { if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "CREATE", theIfNoneExist, match.size()); String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "CREATE", theIfNoneExist, match.size());
throw new PreconditionFailedException(Msg.code(958) + msg); throw new PreconditionFailedException(Msg.code(958) + msg);
} else if (match.size() == 1) { } else if (match.size() == 1) {
ResourcePersistentId pid = match.iterator().next(); ResourcePersistentId pid = match.iterator().next();
@ -650,7 +650,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (resourceIds.size() > 1) { if (resourceIds.size() > 1) {
if (!getConfig().isAllowMultipleDelete()) { if (!getConfig().isAllowMultipleDelete()) {
throw new PreconditionFailedException(Msg.code(962) + getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "DELETE", theUrl, resourceIds.size())); throw new PreconditionFailedException(Msg.code(962) + getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "DELETE", theUrl, resourceIds.size()));
} }
} }
@ -1124,13 +1124,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theConditionalUrl, myResourceType, theTransactionDetails, theRequest); Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theConditionalUrl, myResourceType, theTransactionDetails, theRequest);
if (match.size() > 1) { if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "PATCH", theConditionalUrl, match.size()); String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "PATCH", theConditionalUrl, match.size());
throw new PreconditionFailedException(Msg.code(972) + msg); throw new PreconditionFailedException(Msg.code(972) + msg);
} else if (match.size() == 1) { } else if (match.size() == 1) {
ResourcePersistentId pid = match.iterator().next(); ResourcePersistentId pid = match.iterator().next();
entityToUpdate = myEntityManager.find(ResourceTable.class, pid.getId()); entityToUpdate = myEntityManager.find(ResourceTable.class, pid.getId());
} else { } else {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "invalidMatchUrlNoMatches", theConditionalUrl); String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "invalidMatchUrlNoMatches", theConditionalUrl);
throw new ResourceNotFoundException(Msg.code(973) + msg); throw new ResourceNotFoundException(Msg.code(973) + msg);
} }
@ -1731,7 +1731,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (isNotBlank(theMatchUrl)) { if (isNotBlank(theMatchUrl)) {
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theTransactionDetails, theRequest, theResource); Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theTransactionDetails, theRequest, theResource);
if (match.size() > 1) { if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size()); String msg = getContext().getLocalizer().getMessageSanitized(BaseStorageDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size());
throw new PreconditionFailedException(Msg.code(988) + msg); throw new PreconditionFailedException(Msg.code(988) + msg);
} else if (match.size() == 1) { } else if (match.size() == 1) {
ResourcePersistentId pid = match.iterator().next(); ResourcePersistentId pid = match.iterator().next();

View File

@ -29,6 +29,7 @@ import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService; import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.BaseStorageDao;
import ca.uhn.fhir.jpa.dao.MatchResourceUrlService; import ca.uhn.fhir.jpa.dao.MatchResourceUrlService;
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboStringUniqueDao; import ca.uhn.fhir.jpa.dao.data.IResourceIndexedComboStringUniqueDao;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
@ -342,7 +343,7 @@ public class SearchParamWithInlineReferencesExtractor {
String resourceTypeString = nextIdText.substring(0, nextIdText.indexOf('?')).replace("/", ""); String resourceTypeString = nextIdText.substring(0, nextIdText.indexOf('?')).replace("/", "");
RuntimeResourceDefinition matchResourceDef = myContext.getResourceDefinition(resourceTypeString); RuntimeResourceDefinition matchResourceDef = myContext.getResourceDefinition(resourceTypeString);
if (matchResourceDef == null) { if (matchResourceDef == null) {
String msg = myContext.getLocalizer().getMessage(BaseHapiFhirDao.class, "invalidMatchUrlInvalidResourceType", nextId.getValue(), resourceTypeString); String msg = myContext.getLocalizer().getMessage(BaseStorageDao.class, "invalidMatchUrlInvalidResourceType", nextId.getValue(), resourceTypeString);
throw new InvalidRequestException(Msg.code(1090) + msg); throw new InvalidRequestException(Msg.code(1090) + msg);
} }
Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass(); Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass();
@ -360,7 +361,7 @@ public class SearchParamWithInlineReferencesExtractor {
theTransactionDetails.addResolvedMatchUrl(nextIdText, match); theTransactionDetails.addResolvedMatchUrl(nextIdText, match);
myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.MATCH_URL, nextIdText, match); myMemoryCacheService.putAfterCommit(MemoryCacheService.CacheEnum.MATCH_URL, nextIdText, match);
} else { } else {
String msg = myContext.getLocalizer().getMessage(BaseHapiFhirDao.class, "invalidMatchUrlNoMatches", nextId.getValue()); String msg = myContext.getLocalizer().getMessage(BaseStorageDao.class, "invalidMatchUrlNoMatches", nextId.getValue());
throw new ResourceNotFoundException(Msg.code(1091) + msg); throw new ResourceNotFoundException(Msg.code(1091) + msg);
} }

View File

@ -143,6 +143,14 @@
<artifactId>spring-test</artifactId> <artifactId>spring-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.github.dnault</groupId>
<artifactId>xml-patch</artifactId>
</dependency>
<dependency>
<groupId>io.dogote</groupId>
<artifactId>json-patch</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -50,7 +50,7 @@ public class JsonPatchUtils {
final JsonPatch patch; final JsonPatch patch;
try { try {
com.fasterxml.jackson.core.JsonParser parser = factory.createParser(thePatchBody); JsonParser parser = factory.createParser(thePatchBody);
JsonNode jsonPatchNode = mapper.readTree(parser); JsonNode jsonPatchNode = mapper.readTree(parser);
patch = JsonPatch.fromJson(jsonPatchNode); patch = JsonPatch.fromJson(jsonPatchNode);