Merge branch 'rel_6_4' into nd-4123-bulk-export-stuck-in-finalize-state

This commit is contained in:
nathaniel.doef 2023-02-09 10:49:29 -05:00
commit 1da5e02b92
6 changed files with 85 additions and 4 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 4523
title: "Previously, meta source field in subscription messages was inconsistently populated regarding different requests.
Now, this has been fixed and meta source will be included in all subscription messages."

View File

@ -54,8 +54,8 @@ Note that these templates expect a few specific CSS definitions to be present in
To use your own templates for narrative generation, simply create one or more templates, using the Thymeleaf HTML based syntax.
```java
{{snippet:classpath:/ca/uhn/fhir/narrative/OperationOutcome.html}}
```html
{{snippet:classpath:/ca/uhn/hapi/fhir/docs/snippet/OperationOutcome.html}}
```
Then create a properties file which describes your templates. In this properties file, each resource to be defined has a pair or properties.

View File

@ -0,0 +1,23 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="narrative.css"/>
</head>
<body>
<!--*/-->
<div>
<h1>Operation Outcome</h1>
<table border="0">
<tr th:each="issue : ${resource.issue}">
<td th:text="${issue.severityElement.value}" style="font-weight: bold;"></td>
<td th:text="${issue.location}"></td>
<td th:narrative="${issue.diagnostics}"></td>
</tr>
</table>
</div>
<!--*/-->
</body>
</html>

View File

@ -34,7 +34,9 @@ import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.util.BundleBuilder;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.text.StringSubstitutor;
@ -139,6 +141,14 @@ public abstract class BaseSubscriptionDeliverySubscriber implements MessageHandl
return builder.getBundle();
}
protected IBaseResource updateDeliveryResourceWithMetaSource(IBaseResource thePayloadResource) {
String resType = thePayloadResource.fhirType();
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(resType);
IBaseResource resourceWithMetaSource = dao.read(thePayloadResource.getIdElement(), new SystemRequestDetails());
return resourceWithMetaSource;
}
@VisibleForTesting
public void setFhirContextForUnitTest(FhirContext theCtx) {
myFhirContext = theCtx;

View File

@ -32,6 +32,7 @@ import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.util.HapiExtensions;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -59,8 +60,14 @@ public class SubscriptionDeliveringMessageSubscriber extends BaseSubscriptionDel
protected void doDelivery(ResourceDeliveryMessage theSourceMessage, CanonicalSubscription theSubscription, IChannelProducer theChannelProducer, ResourceModifiedJsonMessage theWrappedMessageToSend) {
String payloadId = theSourceMessage.getPayloadId();
IBaseResource payloadResource = null;
if (isNotBlank(theSubscription.getPayloadSearchCriteria())) {
IBaseResource payloadResource = createDeliveryBundleForPayloadSearchCriteria(theSubscription, theWrappedMessageToSend.getPayload().getPayload(myFhirContext));
payloadResource = createDeliveryBundleForPayloadSearchCriteria(theSubscription, theWrappedMessageToSend.getPayload().getPayload(myFhirContext));
} else if (! theWrappedMessageToSend.getPayload().getPayloadString().contains(HapiExtensions.EXT_META_SOURCE)){
payloadResource = updateDeliveryResourceWithMetaSource(theWrappedMessageToSend.getPayload().getPayload(myFhirContext));
}
if (payloadResource != null) {
ResourceModifiedJsonMessage newWrappedMessageToSend = convertDeliveryMessageToResourceModifiedMessage(theSourceMessage, payloadResource);
theWrappedMessageToSend.setPayload(newWrappedMessageToSend.getPayload());
payloadId = payloadResource.getIdElement().toUnqualifiedVersionless().getValue();

View File

@ -27,7 +27,6 @@ import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Patient;
@ -59,6 +58,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.eq;
@ -208,6 +208,7 @@ public class BaseSubscriptionDeliverySubscriberTest {
});
when(myInterceptorBroadcaster.callHooks(eq(Pointcut.SUBSCRIPTION_AFTER_MESSAGE_DELIVERY), any())).thenReturn(false);
when(myChannelFactory.getOrCreateProducer(any(), any(), any())).thenReturn(myChannelProducer);
when(myDaoRegistry.getResourceDao(anyString())).thenReturn(myResourceDao);
CanonicalSubscription subscription = generateSubscription();
Patient patient = generatePatient();
@ -345,6 +346,7 @@ public class BaseSubscriptionDeliverySubscriberTest {
when(myInterceptorBroadcaster.callHooks(eq(Pointcut.SUBSCRIPTION_BEFORE_MESSAGE_DELIVERY), any())).thenReturn(true);
when(myInterceptorBroadcaster.callHooks(eq(Pointcut.SUBSCRIPTION_AFTER_MESSAGE_DELIVERY), any())).thenReturn(false);
when(myChannelFactory.getOrCreateProducer(any(), any(), any())).thenReturn(myChannelProducer);
when(myDaoRegistry.getResourceDao(anyString())).thenReturn(myResourceDao);
CanonicalSubscription subscription = generateSubscription();
Patient patient = generatePatient();
@ -401,6 +403,40 @@ public class BaseSubscriptionDeliverySubscriberTest {
}
}
@Test
public void testSubscriptionMessageContainsMetaSourceField() throws URISyntaxException {
//Given: we have a subscription message that contains a patient resource
Patient p1 = generatePatient();
p1.addName().setFamily("p1-family");
CanonicalSubscription subscription = generateSubscription();
subscription.setCriteriaString("[*]");
ResourceDeliveryMessage payload = new ResourceDeliveryMessage();
payload.setSubscription(subscription);
payload.setPayload(myCtx, p1, EncodingEnum.JSON);
payload.setOperationType(ResourceModifiedMessage.OperationTypeEnum.CREATE);
//When
when(myInterceptorBroadcaster.callHooks(eq(Pointcut.SUBSCRIPTION_BEFORE_MESSAGE_DELIVERY), ArgumentMatchers.any(HookParams.class))).thenReturn(true);
when(myInterceptorBroadcaster.callHooks(eq(Pointcut.SUBSCRIPTION_AFTER_MESSAGE_DELIVERY), any())).thenReturn(false);
when(myChannelFactory.getOrCreateProducer(any(), any(), any())).thenReturn(myChannelProducer);
when(myDaoRegistry.getResourceDao(anyString())).thenReturn(myResourceDao);
p1.getMeta().setSource("#example-source");
when(myResourceDao.read(any(), any())).thenReturn(p1);
//Then: meta.source field will be included in the message
myMessageSubscriber.handleMessage(payload);
ArgumentCaptor<ResourceModifiedJsonMessage> captor = ArgumentCaptor.forClass(ResourceModifiedJsonMessage.class);
verify(myChannelProducer).send(captor.capture());
List<ResourceModifiedJsonMessage> messages = captor.getAllValues();
ResourceModifiedMessage receivedMessage = messages.get(0).getPayload();
assertTrue(receivedMessage.getPayloadString().contains("\"source\":\"#example-source\""));
}
@Nonnull
private Patient generatePatient() {
Patient patient = new Patient();