Empty, id-only content Payload types are not supported for Topic based Subscriptions (#5499)
* added support of Empty, id-only content Payload types for Topic based Subscriptions
This commit is contained in:
parent
78a50f92bc
commit
4d0670b0ad
|
@ -196,11 +196,7 @@ public class BundleBuilder {
|
|||
public UpdateBuilder addTransactionUpdateEntry(IBaseResource theResource) {
|
||||
Validate.notNull(theResource, "theResource must not be null");
|
||||
|
||||
IIdType id = theResource.getIdElement();
|
||||
if (id.hasIdPart() && !id.hasResourceType()) {
|
||||
String resourceType = myContext.getResourceType(theResource);
|
||||
id = id.withResourceType(resourceType);
|
||||
}
|
||||
IIdType id = getIdTypeForUpdate(theResource);
|
||||
|
||||
String requestUrl = id.toUnqualifiedVersionless().getValue();
|
||||
String fullUrl = id.getValue();
|
||||
|
@ -225,13 +221,29 @@ public class BundleBuilder {
|
|||
myEntryRequestUrlChild.getMutator().setValue(request, url);
|
||||
|
||||
// Bundle.entry.request.method
|
||||
IPrimitiveType<?> method = (IPrimitiveType<?>)
|
||||
myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments());
|
||||
method.setValueAsString(theHttpVerb);
|
||||
myEntryRequestMethodChild.getMutator().setValue(request, method);
|
||||
addRequestMethod(request, theHttpVerb);
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry containing an update (UPDATE) request without the body of the resource.
|
||||
* Also sets the Bundle.type value to "transaction" if it is not already set.
|
||||
*
|
||||
* @param theResource The resource to update.
|
||||
*/
|
||||
public void addTransactionUpdateIdOnlyEntry(IBaseResource theResource) {
|
||||
setBundleField("type", "transaction");
|
||||
|
||||
Validate.notNull(theResource, "theResource must not be null");
|
||||
|
||||
IIdType id = getIdTypeForUpdate(theResource);
|
||||
String requestUrl = id.toUnqualifiedVersionless().getValue();
|
||||
String fullUrl = id.getValue();
|
||||
String httpMethod = "PUT";
|
||||
|
||||
addIdOnlyEntry(requestUrl, httpMethod, fullUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry containing an create (POST) request.
|
||||
* Also sets the Bundle.type value to "transaction" if it is not already set.
|
||||
|
@ -247,20 +259,47 @@ public class BundleBuilder {
|
|||
String resourceType = myContext.getResourceType(theResource);
|
||||
|
||||
// Bundle.entry.request.url
|
||||
IPrimitiveType<?> url =
|
||||
(IPrimitiveType<?>) myContext.getElementDefinition("uri").newInstance();
|
||||
url.setValueAsString(resourceType);
|
||||
myEntryRequestUrlChild.getMutator().setValue(request, url);
|
||||
addRequestUrl(request, resourceType);
|
||||
|
||||
// Bundle.entry.request.url
|
||||
IPrimitiveType<?> method = (IPrimitiveType<?>)
|
||||
myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments());
|
||||
method.setValueAsString("POST");
|
||||
myEntryRequestMethodChild.getMutator().setValue(request, method);
|
||||
// Bundle.entry.request.method
|
||||
addRequestMethod(request, "POST");
|
||||
|
||||
return new CreateBuilder(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry containing a create (POST) request without the body of the resource.
|
||||
* Also sets the Bundle.type value to "transaction" if it is not already set.
|
||||
*
|
||||
* @param theResource The resource to create
|
||||
*/
|
||||
public void addTransactionCreateEntryIdOnly(IBaseResource theResource) {
|
||||
setBundleField("type", "transaction");
|
||||
|
||||
String requestUrl = myContext.getResourceType(theResource);
|
||||
String fullUrl = theResource.getIdElement().getValue();
|
||||
String httpMethod = "POST";
|
||||
|
||||
addIdOnlyEntry(requestUrl, httpMethod, fullUrl);
|
||||
}
|
||||
|
||||
private void addIdOnlyEntry(String theRequestUrl, String theHttpMethod, String theFullUrl) {
|
||||
IBase entry = addEntry();
|
||||
|
||||
// Bundle.entry.request
|
||||
IBase request = myEntryRequestDef.newInstance();
|
||||
myEntryRequestChild.getMutator().setValue(entry, request);
|
||||
|
||||
// Bundle.entry.request.url
|
||||
addRequestUrl(request, theRequestUrl);
|
||||
|
||||
// Bundle.entry.request.method
|
||||
addRequestMethod(request, theHttpMethod);
|
||||
|
||||
// Bundle.entry.fullUrl
|
||||
addFullUrl(entry, theFullUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry containing a delete (DELETE) request.
|
||||
* Also sets the Bundle.type value to "transaction" if it is not already set.
|
||||
|
@ -341,20 +380,44 @@ public class BundleBuilder {
|
|||
IBase request = addEntryAndReturnRequest();
|
||||
|
||||
// Bundle.entry.request.url
|
||||
IPrimitiveType<?> url =
|
||||
(IPrimitiveType<?>) myContext.getElementDefinition("uri").newInstance();
|
||||
url.setValueAsString(theDeleteUrl);
|
||||
myEntryRequestUrlChild.getMutator().setValue(request, url);
|
||||
addRequestUrl(request, theDeleteUrl);
|
||||
|
||||
// Bundle.entry.request.method
|
||||
IPrimitiveType<?> method = (IPrimitiveType<?>)
|
||||
myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments());
|
||||
method.setValueAsString("DELETE");
|
||||
myEntryRequestMethodChild.getMutator().setValue(request, method);
|
||||
addRequestMethod(request, "DELETE");
|
||||
|
||||
return new DeleteBuilder();
|
||||
}
|
||||
|
||||
private IIdType getIdTypeForUpdate(IBaseResource theResource) {
|
||||
IIdType id = theResource.getIdElement();
|
||||
if (id.hasIdPart() && !id.hasResourceType()) {
|
||||
String resourceType = myContext.getResourceType(theResource);
|
||||
id = id.withResourceType(resourceType);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
private void addFullUrl(IBase theEntry, String theFullUrl) {
|
||||
IPrimitiveType<?> fullUrl =
|
||||
(IPrimitiveType<?>) myContext.getElementDefinition("uri").newInstance();
|
||||
fullUrl.setValueAsString(theFullUrl);
|
||||
myEntryFullUrlChild.getMutator().setValue(theEntry, fullUrl);
|
||||
}
|
||||
|
||||
private void addRequestUrl(IBase request, String theRequestUrl) {
|
||||
IPrimitiveType<?> url =
|
||||
(IPrimitiveType<?>) myContext.getElementDefinition("uri").newInstance();
|
||||
url.setValueAsString(theRequestUrl);
|
||||
myEntryRequestUrlChild.getMutator().setValue(request, url);
|
||||
}
|
||||
|
||||
private void addRequestMethod(IBase theRequest, String theMethod) {
|
||||
IPrimitiveType<?> method = (IPrimitiveType<?>)
|
||||
myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments());
|
||||
method.setValueAsString(theMethod);
|
||||
myEntryRequestMethodChild.getMutator().setValue(theRequest, method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry for a Collection bundle type
|
||||
*/
|
||||
|
@ -406,10 +469,7 @@ public class BundleBuilder {
|
|||
IBase entry = addEntry();
|
||||
|
||||
// Bundle.entry.fullUrl
|
||||
IPrimitiveType<?> fullUrl =
|
||||
(IPrimitiveType<?>) myContext.getElementDefinition("uri").newInstance();
|
||||
fullUrl.setValueAsString(theFullUrl);
|
||||
myEntryFullUrlChild.getMutator().setValue(entry, fullUrl);
|
||||
addFullUrl(entry, theFullUrl);
|
||||
|
||||
// Bundle.entry.resource
|
||||
myEntryResourceChild.getMutator().setValue(entry, theResource);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: add
|
||||
issue: 5498
|
||||
title: "Added support for `id-only` and `empty` payload content types for notifications
|
||||
triggered by R5, R4B, and R4 back-ported topic subscriptions."
|
|
@ -23,12 +23,14 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.topic.status.INotificationStatusBuilder;
|
||||
import ca.uhn.fhir.jpa.topic.status.R4BNotificationStatusBuilder;
|
||||
import ca.uhn.fhir.jpa.topic.status.R4NotificationStatusBuilder;
|
||||
import ca.uhn.fhir.jpa.topic.status.R5NotificationStatusBuilder;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.util.BundleBuilder;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
|
@ -37,6 +39,8 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE;
|
||||
|
||||
public class SubscriptionTopicPayloadBuilder {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionTopicPayloadBuilder.class);
|
||||
private final FhirContext myFhirContext;
|
||||
|
@ -73,7 +77,7 @@ public class SubscriptionTopicPayloadBuilder {
|
|||
myNotificationStatusBuilder.buildNotificationStatus(theResources, theActiveSubscription, theTopicUrl);
|
||||
bundleBuilder.addCollectionEntry(notificationStatus);
|
||||
|
||||
addResources(bundleBuilder, theResources, theRestOperationType);
|
||||
addResources(theResources, theActiveSubscription.getSubscription(), theRestOperationType, bundleBuilder);
|
||||
// WIP STR5 add support for notificationShape include, revinclude
|
||||
|
||||
// Note we need to set the bundle type after we add the resources since adding the resources automatically sets
|
||||
|
@ -87,7 +91,46 @@ public class SubscriptionTopicPayloadBuilder {
|
|||
return retval;
|
||||
}
|
||||
|
||||
private static void addResources(
|
||||
private void addResources(
|
||||
List<IBaseResource> theResources,
|
||||
CanonicalSubscription theCanonicalSubscription,
|
||||
RestOperationTypeEnum theRestOperationType,
|
||||
BundleBuilder theBundleBuilder) {
|
||||
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent content =
|
||||
ObjectUtils.defaultIfNull(theCanonicalSubscription.getContent(), FULLRESOURCE);
|
||||
|
||||
switch (content) {
|
||||
case EMPTY:
|
||||
// skip adding resource to the Bundle
|
||||
break;
|
||||
case IDONLY:
|
||||
addIdOnly(theBundleBuilder, theResources, theRestOperationType);
|
||||
break;
|
||||
case FULLRESOURCE:
|
||||
addFullResources(theBundleBuilder, theResources, theRestOperationType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void addIdOnly(
|
||||
BundleBuilder bundleBuilder, List<IBaseResource> theResources, RestOperationTypeEnum theRestOperationType) {
|
||||
for (IBaseResource resource : theResources) {
|
||||
switch (theRestOperationType) {
|
||||
case CREATE:
|
||||
bundleBuilder.addTransactionCreateEntryIdOnly(resource);
|
||||
break;
|
||||
case UPDATE:
|
||||
bundleBuilder.addTransactionUpdateIdOnlyEntry(resource);
|
||||
break;
|
||||
case DELETE:
|
||||
bundleBuilder.addTransactionDeleteEntry(resource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addFullResources(
|
||||
BundleBuilder bundleBuilder, List<IBaseResource> theResources, RestOperationTypeEnum theRestOperationType) {
|
||||
for (IBaseResource resource : theResources) {
|
||||
switch (theRestOperationType) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package ca.uhn.fhir.jpa.topic;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
|
||||
import ca.uhn.fhir.rest.server.messaging.BaseResourceMessage;
|
||||
import ca.uhn.fhir.util.BundleUtil;
|
||||
|
@ -72,4 +73,14 @@ public class SubscriptionTopicUtil {
|
|||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if {@link CanonicalSubscription} has EMPTY {@link org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent}
|
||||
* Used for R5/R4B/R4 Notification Status object building.
|
||||
*/
|
||||
public static boolean isEmptyContentTopicSubscription(CanonicalSubscription theCanonicalSubscription) {
|
||||
return theCanonicalSubscription.isTopicSubscription()
|
||||
&& org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.EMPTY
|
||||
== theCanonicalSubscription.getTopicSubscription().getContent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ package ca.uhn.fhir.jpa.topic.status;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.topic.SubscriptionTopicUtil;
|
||||
import ca.uhn.fhir.subscription.SubscriptionConstants;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.CanonicalType;
|
||||
|
@ -46,6 +48,7 @@ public class R4NotificationStatusBuilder implements INotificationStatusBuilder<P
|
|||
public Parameters buildNotificationStatus(
|
||||
List<IBaseResource> theResources, ActiveSubscription theActiveSubscription, String theTopicUrl) {
|
||||
Long eventNumber = theActiveSubscription.getDeliveriesCount();
|
||||
CanonicalSubscription canonicalSubscription = theActiveSubscription.getSubscription();
|
||||
|
||||
// See http://build.fhir.org/ig/HL7/fhir-subscription-backport-ig/Parameters-r4-notification-status.json.html
|
||||
// and
|
||||
|
@ -66,12 +69,12 @@ public class R4NotificationStatusBuilder implements INotificationStatusBuilder<P
|
|||
notificationEvent.setName("notification-event");
|
||||
notificationEvent.addPart().setName("event-number").setValue(new StringType(eventNumber.toString()));
|
||||
notificationEvent.addPart().setName("timestamp").setValue(new DateType(new Date()));
|
||||
if (theResources.size() > 0) {
|
||||
if (!theResources.isEmpty() && !SubscriptionTopicUtil.isEmptyContentTopicSubscription(canonicalSubscription)) {
|
||||
IBaseResource firstResource = theResources.get(0);
|
||||
notificationEvent
|
||||
.addPart()
|
||||
.setName("focus")
|
||||
.setValue(new Reference(firstResource.getIdElement().toUnqualifiedVersionless()));
|
||||
Reference resourceReference =
|
||||
new Reference(firstResource.getIdElement().toUnqualifiedVersionless());
|
||||
|
||||
notificationEvent.addPart().setName("focus").setValue(resourceReference);
|
||||
}
|
||||
|
||||
return parameters;
|
||||
|
|
|
@ -21,6 +21,8 @@ package ca.uhn.fhir.jpa.topic.status;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.topic.SubscriptionTopicUtil;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r5.model.Enumerations;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
|
@ -40,6 +42,7 @@ public class R5NotificationStatusBuilder implements INotificationStatusBuilder<S
|
|||
public SubscriptionStatus buildNotificationStatus(
|
||||
List<IBaseResource> theResources, ActiveSubscription theActiveSubscription, String theTopicUrl) {
|
||||
long eventNumber = theActiveSubscription.getDeliveriesCount();
|
||||
CanonicalSubscription canonicalSubscription = theActiveSubscription.getSubscription();
|
||||
|
||||
SubscriptionStatus subscriptionStatus = new SubscriptionStatus();
|
||||
subscriptionStatus.setId(UUID.randomUUID().toString());
|
||||
|
@ -50,7 +53,7 @@ public class R5NotificationStatusBuilder implements INotificationStatusBuilder<S
|
|||
SubscriptionStatus.SubscriptionStatusNotificationEventComponent event =
|
||||
subscriptionStatus.addNotificationEvent();
|
||||
event.setEventNumber(eventNumber);
|
||||
if (theResources.size() > 0) {
|
||||
if (!theResources.isEmpty() && !SubscriptionTopicUtil.isEmptyContentTopicSubscription(canonicalSubscription)) {
|
||||
event.setFocus(new Reference(theResources.get(0).getIdElement()));
|
||||
}
|
||||
subscriptionStatus.setSubscription(
|
||||
|
|
|
@ -8,74 +8,177 @@ import ca.uhn.fhir.util.BundleUtil;
|
|||
import org.hl7.fhir.r4b.model.Bundle;
|
||||
import org.hl7.fhir.r4b.model.Encounter;
|
||||
import org.hl7.fhir.r4b.model.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.hl7.fhir.r4b.model.SubscriptionStatus;
|
||||
import org.hl7.fhir.r5.model.Subscription;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SubscriptionTopicPayloadBuilderR4BTest {
|
||||
private static final String TEST_TOPIC_URL = "test-builder-topic-url";
|
||||
FhirContext ourFhirContext = FhirContext.forR4BCached();
|
||||
@Test
|
||||
public void testBuildPayloadDelete() {
|
||||
private SubscriptionTopicPayloadBuilder myStPayloadBuilder;
|
||||
private Encounter myEncounter;
|
||||
private CanonicalSubscription myCanonicalSubscription;
|
||||
private ActiveSubscription myActiveSubscription;
|
||||
|
||||
@BeforeEach
|
||||
void before() {
|
||||
myStPayloadBuilder = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
myEncounter = new Encounter();
|
||||
myEncounter.setId("Encounter/1");
|
||||
myCanonicalSubscription = new CanonicalSubscription();
|
||||
myCanonicalSubscription.setTopicSubscription(true);
|
||||
myActiveSubscription = new ActiveSubscription(myCanonicalSubscription, "test");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"full-resource",
|
||||
"" // payload content not provided
|
||||
})
|
||||
public void testBuildPayload_deleteWithFullResourceContent_returnsCorrectPayload(String thePayloadContent) {
|
||||
// setup
|
||||
var svc = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
var encounter = new Encounter();
|
||||
encounter.setId("Encounter/1");
|
||||
CanonicalSubscription sub = new CanonicalSubscription();
|
||||
ActiveSubscription subscription = new ActiveSubscription(sub, "test");
|
||||
Subscription.SubscriptionPayloadContent payloadContent =
|
||||
Subscription.SubscriptionPayloadContent.fromCode(thePayloadContent);
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(payloadContent);
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle)svc.buildPayload(List.of(encounter), subscription, TEST_TOPIC_URL, RestOperationTypeEnum.DELETE);
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, RestOperationTypeEnum.DELETE);
|
||||
|
||||
// verify
|
||||
// verify Bundle size
|
||||
assertEquals(2, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
|
||||
assertEquals(Bundle.HTTPVerb.DELETE, payload.getEntry().get(1).getRequest().getMethod());
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
verifySubscriptionStatusNotificationEvent(resources.get(0));
|
||||
|
||||
// verify Encounter entry
|
||||
Bundle.BundleEntryComponent encounterEntry = payload.getEntry().get(1);
|
||||
assertNull(encounterEntry.getResource());
|
||||
assertNull(encounterEntry.getFullUrl());
|
||||
verifyRequestParameters(encounterEntry, org.hl7.fhir.r5.model.Bundle.HTTPVerb.DELETE.name(), "Encounter/1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildPayloadUpdate() {
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"create, POST , full-resource, Encounter/1, Encounter",
|
||||
"update, PUT , full-resource, Encounter/1, Encounter/1",
|
||||
"create, POST , , Encounter/1, Encounter",
|
||||
"update, PUT , , Encounter/1, Encounter/1",
|
||||
})
|
||||
public void testBuildPayload_createUpdateWithFullResourceContent_returnsCorrectPayload(String theRestOperationType,
|
||||
String theHttpMethod,
|
||||
String thePayloadContent,
|
||||
String theFullUrl,
|
||||
String theRequestUrl) {
|
||||
// setup
|
||||
var svc = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
var encounter = new Encounter();
|
||||
encounter.setId("Encounter/1");
|
||||
CanonicalSubscription sub = new CanonicalSubscription();
|
||||
ActiveSubscription subscription = new ActiveSubscription(sub, "test");
|
||||
Subscription.SubscriptionPayloadContent payloadContent =
|
||||
Subscription.SubscriptionPayloadContent.fromCode(thePayloadContent);
|
||||
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(payloadContent);
|
||||
RestOperationTypeEnum restOperationType = RestOperationTypeEnum.forCode(theRestOperationType);
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle)svc.buildPayload(List.of(encounter), subscription, TEST_TOPIC_URL, RestOperationTypeEnum.UPDATE);
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, restOperationType);
|
||||
|
||||
// verify
|
||||
// verify Bundle size
|
||||
assertEquals(2, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(2, resources.size());
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
assertEquals("Encounter", resources.get(1).getResourceType().name());
|
||||
|
||||
assertEquals(Bundle.HTTPVerb.PUT, payload.getEntry().get(1).getRequest().getMethod());
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
verifySubscriptionStatusNotificationEvent(resources.get(0));
|
||||
|
||||
// verify Encounter entry
|
||||
Bundle.BundleEntryComponent encounterEntry = payload.getEntry().get(1);
|
||||
assertEquals("Encounter", resources.get(1).getResourceType().name());
|
||||
assertEquals(myEncounter, resources.get(1));
|
||||
assertEquals(theFullUrl, encounterEntry.getFullUrl());
|
||||
verifyRequestParameters(encounterEntry, theHttpMethod, theRequestUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildPayloadCreate() {
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"create, POST , Encounter/1, Encounter",
|
||||
"update, PUT , Encounter/1, Encounter/1",
|
||||
"delete, DELETE, , Encounter/1"
|
||||
})
|
||||
public void testBuildPayload_withIdOnlyContent_returnsCorrectPayload(String theRestOperationType,
|
||||
String theHttpMethod, String theFullUrl,
|
||||
String theRequestUrl) {
|
||||
// setup
|
||||
var svc = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
var encounter = new Encounter();
|
||||
encounter.setId("Encounter/1");
|
||||
CanonicalSubscription sub = new CanonicalSubscription();
|
||||
ActiveSubscription subscription = new ActiveSubscription(sub, "test");
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(Subscription.SubscriptionPayloadContent.IDONLY);
|
||||
RestOperationTypeEnum restOperationType = RestOperationTypeEnum.forCode(theRestOperationType);
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle)svc.buildPayload(List.of(encounter), subscription, TEST_TOPIC_URL, RestOperationTypeEnum.CREATE);
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, restOperationType);
|
||||
|
||||
// verify
|
||||
// verify Bundle size
|
||||
assertEquals(2, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(2, resources.size());
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
assertEquals("Encounter", resources.get(1).getResourceType().name());
|
||||
assertEquals(1, resources.size());
|
||||
|
||||
assertEquals(Bundle.HTTPVerb.POST, payload.getEntry().get(1).getRequest().getMethod());
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
verifySubscriptionStatusNotificationEvent(resources.get(0));
|
||||
|
||||
// verify Encounter entry
|
||||
Bundle.BundleEntryComponent encounterEntry = payload.getEntry().get(1);
|
||||
assertNull(encounterEntry.getResource());
|
||||
assertEquals(theFullUrl, encounterEntry.getFullUrl());
|
||||
verifyRequestParameters(encounterEntry, theHttpMethod, theRequestUrl);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"create",
|
||||
"update",
|
||||
"delete"
|
||||
})
|
||||
public void testBuildPayload_withEmptyContent_returnsCorrectPayload(String theRestOperationType) {
|
||||
// setup
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(Subscription.SubscriptionPayloadContent.EMPTY);
|
||||
RestOperationTypeEnum restOperationType = RestOperationTypeEnum.forCode(theRestOperationType);
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, restOperationType);
|
||||
|
||||
// verify Bundle size
|
||||
assertEquals(1, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
assertEquals(1, ((SubscriptionStatus) resources.get(0)).getNotificationEvent().size());
|
||||
SubscriptionStatus.SubscriptionStatusNotificationEventComponent notificationEvent =
|
||||
((SubscriptionStatus) resources.get(0)).getNotificationEventFirstRep();
|
||||
assertFalse(notificationEvent.hasFocus());
|
||||
}
|
||||
|
||||
private void verifyRequestParameters(Bundle.BundleEntryComponent theEncounterEntry,
|
||||
String theHttpMethod, String theRequestUrl) {
|
||||
assertNotNull(theEncounterEntry.getRequest());
|
||||
assertEquals(theHttpMethod, theEncounterEntry.getRequest().getMethod().name());
|
||||
assertEquals(theRequestUrl, theEncounterEntry.getRequest().getUrl());
|
||||
}
|
||||
|
||||
private void verifySubscriptionStatusNotificationEvent(Resource theResource) {
|
||||
assertEquals("SubscriptionStatus", theResource.getResourceType().name());
|
||||
assertEquals(1, ((SubscriptionStatus) theResource).getNotificationEvent().size());
|
||||
SubscriptionStatus.SubscriptionStatusNotificationEventComponent notificationEvent =
|
||||
((SubscriptionStatus) theResource).getNotificationEventFirstRep();
|
||||
assertTrue(notificationEvent.hasFocus());
|
||||
assertEquals(myEncounter.getId(), notificationEvent.getFocus().getReference());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,74 +8,177 @@ import ca.uhn.fhir.util.BundleUtil;
|
|||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.Encounter;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.hl7.fhir.r5.model.Subscription;
|
||||
import org.hl7.fhir.r5.model.SubscriptionStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SubscriptionTopicPayloadBuilderR5Test {
|
||||
private static final String TEST_TOPIC_URL = "test-builder-topic-url";
|
||||
FhirContext ourFhirContext = FhirContext.forR5Cached();
|
||||
@Test
|
||||
public void testBuildPayloadDelete() {
|
||||
// setup
|
||||
var svc = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
var encounter = new Encounter();
|
||||
encounter.setId("Encounter/1");
|
||||
CanonicalSubscription sub = new CanonicalSubscription();
|
||||
ActiveSubscription subscription = new ActiveSubscription(sub, "test");
|
||||
private static final String TEST_TOPIC_URL = "test-builder-topic-url";
|
||||
FhirContext ourFhirContext = FhirContext.forR5Cached();
|
||||
private SubscriptionTopicPayloadBuilder myStPayloadBuilder;
|
||||
private Encounter myEncounter;
|
||||
private CanonicalSubscription myCanonicalSubscription;
|
||||
private ActiveSubscription myActiveSubscription;
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle)svc.buildPayload(List.of(encounter), subscription, TEST_TOPIC_URL, RestOperationTypeEnum.DELETE);
|
||||
@BeforeEach
|
||||
void before() {
|
||||
myStPayloadBuilder = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
myEncounter = new Encounter();
|
||||
myEncounter.setId("Encounter/1");
|
||||
myCanonicalSubscription = new CanonicalSubscription();
|
||||
myCanonicalSubscription.setTopicSubscription(true);
|
||||
myActiveSubscription = new ActiveSubscription(myCanonicalSubscription, "test");
|
||||
}
|
||||
|
||||
// verify
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"full-resource",
|
||||
"" // payload content not provided
|
||||
})
|
||||
public void testBuildPayload_deleteWithFullResourceContent_returnsCorrectPayload(String thePayloadContent) {
|
||||
// setup
|
||||
Subscription.SubscriptionPayloadContent payloadContent =
|
||||
Subscription.SubscriptionPayloadContent.fromCode(thePayloadContent);
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(payloadContent);
|
||||
|
||||
assertEquals(Bundle.HTTPVerb.DELETE, payload.getEntry().get(1).getRequest().getMethod());
|
||||
}
|
||||
// run
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, RestOperationTypeEnum.DELETE);
|
||||
|
||||
@Test
|
||||
public void testBuildPayloadUpdate() {
|
||||
// setup
|
||||
var svc = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
var encounter = new Encounter();
|
||||
encounter.setId("Encounter/1");
|
||||
CanonicalSubscription sub = new CanonicalSubscription();
|
||||
ActiveSubscription subscription = new ActiveSubscription(sub, "test");
|
||||
// verify Bundle size
|
||||
assertEquals(2, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle)svc.buildPayload(List.of(encounter), subscription, TEST_TOPIC_URL, RestOperationTypeEnum.UPDATE);
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
verifySubscriptionStatusNotificationEvent(resources.get(0));
|
||||
|
||||
// verify
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(2, resources.size());
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
assertEquals("Encounter", resources.get(1).getResourceType().name());
|
||||
// verify Encounter entry
|
||||
Bundle.BundleEntryComponent encounterEntry = payload.getEntry().get(1);
|
||||
assertNull(encounterEntry.getResource());
|
||||
assertNull(encounterEntry.getFullUrl());
|
||||
verifyRequestParameters(encounterEntry, Bundle.HTTPVerb.DELETE.name(), "Encounter/1");
|
||||
}
|
||||
|
||||
assertEquals(Bundle.HTTPVerb.PUT, payload.getEntry().get(1).getRequest().getMethod());
|
||||
}
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"create, POST , full-resource, Encounter/1, Encounter",
|
||||
"update, PUT , full-resource, Encounter/1, Encounter/1",
|
||||
"create, POST , , Encounter/1, Encounter",
|
||||
"update, PUT , , Encounter/1, Encounter/1",
|
||||
})
|
||||
public void testBuildPayload_createUpdateWithFullResourceContent_returnsCorrectPayload(String theRestOperationType,
|
||||
String theHttpMethod,
|
||||
String thePayloadContent,
|
||||
String theFullUrl,
|
||||
String theRequestUrl) {
|
||||
// setup
|
||||
Subscription.SubscriptionPayloadContent payloadContent =
|
||||
Subscription.SubscriptionPayloadContent.fromCode(thePayloadContent);
|
||||
|
||||
@Test
|
||||
public void testBuildPayloadCreate() {
|
||||
// setup
|
||||
var svc = new SubscriptionTopicPayloadBuilder(ourFhirContext);
|
||||
var encounter = new Encounter();
|
||||
encounter.setId("Encounter/1");
|
||||
CanonicalSubscription sub = new CanonicalSubscription();
|
||||
ActiveSubscription subscription = new ActiveSubscription(sub, "test");
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(payloadContent);
|
||||
RestOperationTypeEnum restOperationType = RestOperationTypeEnum.forCode(theRestOperationType);
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle)svc.buildPayload(List.of(encounter), subscription, TEST_TOPIC_URL, RestOperationTypeEnum.CREATE);
|
||||
// run
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, restOperationType);
|
||||
|
||||
// verify
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(2, resources.size());
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
assertEquals("Encounter", resources.get(1).getResourceType().name());
|
||||
// verify Bundle size
|
||||
assertEquals(2, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(2, resources.size());
|
||||
|
||||
assertEquals(Bundle.HTTPVerb.POST, payload.getEntry().get(1).getRequest().getMethod());
|
||||
}
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
verifySubscriptionStatusNotificationEvent(resources.get(0));
|
||||
|
||||
// verify Encounter entry
|
||||
Bundle.BundleEntryComponent encounterEntry = payload.getEntry().get(1);
|
||||
assertEquals("Encounter", resources.get(1).getResourceType().name());
|
||||
assertEquals(myEncounter, resources.get(1));
|
||||
assertEquals(theFullUrl, encounterEntry.getFullUrl());
|
||||
verifyRequestParameters(encounterEntry, theHttpMethod, theRequestUrl);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"create, POST , Encounter/1, Encounter",
|
||||
"update, PUT , Encounter/1, Encounter/1",
|
||||
"delete, DELETE, , Encounter/1"
|
||||
})
|
||||
public void testBuildPayload_withIdOnlyContent_returnsCorrectPayload(String theRestOperationType,
|
||||
String theHttpMethod, String theFullUrl,
|
||||
String theRequestUrl) {
|
||||
// setup
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(Subscription.SubscriptionPayloadContent.IDONLY);
|
||||
RestOperationTypeEnum restOperationType = RestOperationTypeEnum.forCode(theRestOperationType);
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, restOperationType);
|
||||
|
||||
// verify Bundle size
|
||||
assertEquals(2, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
verifySubscriptionStatusNotificationEvent(resources.get(0));
|
||||
|
||||
// verify Encounter entry
|
||||
Bundle.BundleEntryComponent encounterEntry = payload.getEntry().get(1);
|
||||
assertNull(encounterEntry.getResource());
|
||||
assertEquals(theFullUrl, encounterEntry.getFullUrl());
|
||||
verifyRequestParameters(encounterEntry, theHttpMethod, theRequestUrl);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"create",
|
||||
"update",
|
||||
"delete"
|
||||
})
|
||||
public void testBuildPayload_withEmptyContent_returnsCorrectPayload(String theRestOperationType) {
|
||||
// setup
|
||||
myCanonicalSubscription.getTopicSubscription().setContent(Subscription.SubscriptionPayloadContent.EMPTY);
|
||||
RestOperationTypeEnum restOperationType = RestOperationTypeEnum.forCode(theRestOperationType);
|
||||
|
||||
// run
|
||||
Bundle payload = (Bundle) myStPayloadBuilder.buildPayload(List.of(myEncounter), myActiveSubscription, TEST_TOPIC_URL, restOperationType);
|
||||
|
||||
// verify Bundle size
|
||||
assertEquals(1, payload.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(ourFhirContext, payload, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
assertEquals("SubscriptionStatus", resources.get(0).getResourceType().name());
|
||||
assertEquals(1, ((SubscriptionStatus) resources.get(0)).getNotificationEvent().size());
|
||||
SubscriptionStatus.SubscriptionStatusNotificationEventComponent notificationEvent =
|
||||
((SubscriptionStatus) resources.get(0)).getNotificationEventFirstRep();
|
||||
assertFalse(notificationEvent.hasFocus());
|
||||
}
|
||||
|
||||
private void verifyRequestParameters(Bundle.BundleEntryComponent theEncounterEntry,
|
||||
String theHttpMethod, String theRequestUrl) {
|
||||
assertNotNull(theEncounterEntry.getRequest());
|
||||
assertEquals(theHttpMethod, theEncounterEntry.getRequest().getMethod().name());
|
||||
assertEquals(theRequestUrl, theEncounterEntry.getRequest().getUrl());
|
||||
}
|
||||
|
||||
private void verifySubscriptionStatusNotificationEvent(Resource theResource) {
|
||||
assertEquals("SubscriptionStatus", theResource.getResourceType().name());
|
||||
assertEquals(1, ((SubscriptionStatus) theResource).getNotificationEvent().size());
|
||||
SubscriptionStatus.SubscriptionStatusNotificationEventComponent notificationEvent =
|
||||
((SubscriptionStatus) theResource).getNotificationEventFirstRep();
|
||||
assertTrue(notificationEvent.hasFocus());
|
||||
assertEquals(myEncounter.getId(), notificationEvent.getFocus().getReference());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package ca.uhn.fhir.jpa.topic;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalTopicSubscription;
|
||||
import ca.uhn.fhir.rest.server.messaging.BaseResourceMessage;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
|
@ -8,9 +11,12 @@ import org.hl7.fhir.r5.model.Enumeration;
|
|||
import org.hl7.fhir.r5.model.Patient;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.Subscription;
|
||||
import org.hl7.fhir.r5.model.SubscriptionStatus;
|
||||
import org.hl7.fhir.r5.model.SubscriptionTopic;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -21,6 +27,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
|
||||
class SubscriptionTopicUtilTest {
|
||||
|
||||
private static final String TEST_CHANNEL_NAME = "TEST_CHANNEL";
|
||||
|
||||
private final FhirContext myContext = FhirContext.forR5Cached();
|
||||
|
||||
@Test
|
||||
|
@ -86,4 +94,32 @@ class SubscriptionTopicUtilTest {
|
|||
IBaseResource extractionResult = SubscriptionTopicUtil.extractResourceFromBundle(myContext, new Bundle());
|
||||
assertNull(extractionResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsEmptyContentTopicSubscription_withEmptySubscription_returnsFalse() {
|
||||
CanonicalSubscription canonicalSubscription = new CanonicalSubscription();
|
||||
boolean result = SubscriptionTopicUtil.isEmptyContentTopicSubscription(canonicalSubscription);
|
||||
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"full-resource, false",
|
||||
"id-only , false",
|
||||
"empty , true",
|
||||
" , false",
|
||||
})
|
||||
public void testIsEmptyContentTopicSubscription_withContentPayload_returnsExpectedResult(String thePayloadContent,
|
||||
boolean theExpectedResult) {
|
||||
CanonicalTopicSubscription canonicalTopicSubscription = new CanonicalTopicSubscription();
|
||||
canonicalTopicSubscription.setContent(Subscription.SubscriptionPayloadContent.fromCode(thePayloadContent));
|
||||
CanonicalSubscription canonicalSubscription = new CanonicalSubscription();
|
||||
canonicalSubscription.setTopicSubscription(canonicalTopicSubscription);
|
||||
canonicalSubscription.setTopicSubscription(true);
|
||||
|
||||
boolean actualResult = SubscriptionTopicUtil.isEmptyContentTopicSubscription(canonicalSubscription);
|
||||
|
||||
assertEquals(theExpectedResult, actualResult);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
|||
import ca.uhn.fhir.jpa.subscription.BaseSubscriptionsR4Test;
|
||||
import ca.uhn.fhir.jpa.subscription.submit.svc.ResourceModifiedSubmitterSvc;
|
||||
import ca.uhn.fhir.jpa.test.util.StoppableSubscriptionDeliveringRestHookSubscriber;
|
||||
import ca.uhn.fhir.jpa.test.util.SubscriptionTestUtil;
|
||||
import ca.uhn.fhir.jpa.topic.SubscriptionTopicDispatcher;
|
||||
import ca.uhn.fhir.jpa.topic.SubscriptionTopicRegistry;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
@ -15,6 +14,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.subscription.SubscriptionTestDataHelper;
|
||||
import ca.uhn.fhir.util.BundleUtil;
|
||||
import ca.uhn.fhir.util.HapiExtensions;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -29,11 +29,12 @@ import org.hl7.fhir.r4.model.Meta;
|
|||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Parameters;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.r4.model.SearchParameter;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.Subscription;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
@ -42,6 +43,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -66,6 +68,8 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
*/
|
||||
public class RestHookTestR4Test extends BaseSubscriptionsR4Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(RestHookTestR4Test.class);
|
||||
public static final String TEST_PATIENT_ID = "topic-test-patient-id";
|
||||
public static final String PATIENT_REFERENCE = "Patient/" + TEST_PATIENT_ID;
|
||||
|
||||
@Autowired
|
||||
ResourceModifiedSubmitterSvc myResourceModifiedSubmitterSvc;
|
||||
|
@ -1306,8 +1310,73 @@ public class RestHookTestR4Test extends BaseSubscriptionsR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTopicSubscription() throws Exception {
|
||||
Subscription subscription = SubscriptionTestDataHelper.buildR4TopicSubscription();
|
||||
public void testRestHoodTopicSubscription_withEmptyPayloadContent_generateCorrectPayload() throws Exception {
|
||||
String payloadContent = "empty";
|
||||
|
||||
// execute
|
||||
Bundle bundle = createAndDispatchTopicSubscription(payloadContent);
|
||||
|
||||
// verify Bundle size
|
||||
assertEquals(1, bundle.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(myFhirContext, bundle, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
Optional<Parameters.ParametersParameterComponent> focus = getNotificationEventFocus(resources);
|
||||
assertFalse(focus.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHoodTopicSubscription_withIdOnlyPayloadContent_generateCorrectPayload() throws Exception {
|
||||
String payloadContent = "id-only";
|
||||
|
||||
// execute
|
||||
Bundle bundle = createAndDispatchTopicSubscription(payloadContent);
|
||||
|
||||
// verify Bundle size
|
||||
assertEquals(2, bundle.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(myFhirContext, bundle, Resource.class);
|
||||
assertEquals(1, resources.size());
|
||||
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
Optional<Parameters.ParametersParameterComponent> focus = getNotificationEventFocus(resources);
|
||||
assertTrue(focus.isPresent());
|
||||
assertEquals(TEST_PATIENT_ID, ((Reference) focus.get().getValue()).getReference());
|
||||
|
||||
// verify Patient Entry
|
||||
Bundle.BundleEntryComponent patientEntry = bundle.getEntry().get(1);
|
||||
validateRequestParameters(patientEntry);
|
||||
Patient bundlePatient = (Patient) patientEntry.getResource();
|
||||
assertNull(bundlePatient);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRestHoodTopicSubscription_withFullResourcePayloadContent_generateCorrectPayload() throws Exception {
|
||||
String payloadContent = "full-resource";
|
||||
|
||||
// execute
|
||||
Bundle bundle = createAndDispatchTopicSubscription(payloadContent);
|
||||
|
||||
// verify Bundle size
|
||||
assertEquals(2, bundle.getEntry().size());
|
||||
List<Resource> resources = BundleUtil.toListOfResourcesOfType(myFhirContext, bundle, Resource.class);
|
||||
assertEquals(2, resources.size());
|
||||
|
||||
// verify SubscriptionStatus.notificationEvent.focus
|
||||
Optional<Parameters.ParametersParameterComponent> focus = getNotificationEventFocus(resources);
|
||||
assertTrue(focus.isPresent());
|
||||
assertEquals(PATIENT_REFERENCE, ((Reference) focus.get().getValue()).getReference());
|
||||
|
||||
// verify Patient Entry
|
||||
Bundle.BundleEntryComponent patientEntry = bundle.getEntry().get(1);
|
||||
validateRequestParameters(patientEntry);
|
||||
Patient bundlePatient = (Patient) patientEntry.getResource();
|
||||
assertTrue(bundlePatient.getActive());
|
||||
assertEquals(Enumerations.AdministrativeGender.FEMALE, bundlePatient.getGender());
|
||||
}
|
||||
|
||||
private Bundle createAndDispatchTopicSubscription(String thePayloadContent) throws Exception {
|
||||
Subscription subscription = SubscriptionTestDataHelper.buildR4TopicSubscriptionWithContent(thePayloadContent);
|
||||
subscription.setIdElement(null);
|
||||
subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED);
|
||||
Subscription.SubscriptionChannelComponent channel = subscription.getChannel();
|
||||
|
@ -1319,9 +1388,8 @@ public class RestHookTestR4Test extends BaseSubscriptionsR4Test {
|
|||
mySubscriptionIds.add(methodOutcome.getId());
|
||||
waitForActivatedSubscriptionCount(1);
|
||||
|
||||
String patientId = "topic-test-patient-id";
|
||||
Patient patient = new Patient();
|
||||
patient.setId(patientId);
|
||||
patient.setId(TEST_PATIENT_ID);
|
||||
patient.setActive(true);
|
||||
patient.setGender(Enumerations.AdministrativeGender.FEMALE);
|
||||
|
||||
|
@ -1332,12 +1400,22 @@ public class RestHookTestR4Test extends BaseSubscriptionsR4Test {
|
|||
|
||||
ourTransactionProvider.waitForTransactionCount(1);
|
||||
|
||||
Bundle bundle = ourTransactionProvider.getTransactions().get(0);
|
||||
assertEquals(2, bundle.getEntry().size());
|
||||
Parameters parameters = (Parameters) bundle.getEntry().get(0).getResource();
|
||||
// WIP STR5 assert parameters contents
|
||||
Patient bundlePatient = (Patient) bundle.getEntry().get(1).getResource();
|
||||
assertTrue(bundlePatient.getActive());
|
||||
assertEquals(Enumerations.AdministrativeGender.FEMALE, bundlePatient.getGender());
|
||||
return ourTransactionProvider.getTransactions().get(0);
|
||||
}
|
||||
|
||||
private Optional<Parameters.ParametersParameterComponent> getNotificationEventFocus(List<Resource> theResources) {
|
||||
assertEquals("Parameters", theResources.get(0).getResourceType().name());
|
||||
Parameters parameters = (Parameters) theResources.get(0);
|
||||
Parameters.ParametersParameterComponent notificationEvent = parameters.getParameter("notification-event");
|
||||
assertNotNull(notificationEvent);
|
||||
return notificationEvent.getPart().stream()
|
||||
.filter(part -> part.getName().equals("focus"))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private void validateRequestParameters(Bundle.BundleEntryComponent thePatientEntry) {
|
||||
assertNotNull(thePatientEntry.getRequest());
|
||||
assertEquals("POST", thePatientEntry.getRequest().getMethod().name());
|
||||
assertEquals("Patient", thePatientEntry.getRequest().getUrl());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ import java.util.Map;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static ca.uhn.fhir.util.HapiExtensions.EX_SEND_DELETE_MESSAGES;
|
||||
import static java.util.Objects.nonNull;
|
||||
import static java.util.stream.Collectors.mapping;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
|
@ -305,8 +306,6 @@ public class SubscriptionCanonicalizer {
|
|||
CanonicalTopicSubscription topicSubscription = retVal.getTopicSubscription();
|
||||
topicSubscription.setTopic(getCriteria(theSubscription));
|
||||
|
||||
// WIP STR5 support other content types
|
||||
topicSubscription.setContent(org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE);
|
||||
retVal.setEndpointUrl(channel.getEndpoint());
|
||||
retVal.setChannelType(getChannelType(subscription));
|
||||
|
||||
|
@ -320,31 +319,37 @@ public class SubscriptionCanonicalizer {
|
|||
}
|
||||
|
||||
if (channel.hasExtension(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_HEARTBEAT_PERIOD_URL)) {
|
||||
org.hl7.fhir.r4.model.Extension timeoutExtension = channel.getExtensionByUrl(
|
||||
org.hl7.fhir.r4.model.Extension channelHeartbeatPeriotUrlExtension = channel.getExtensionByUrl(
|
||||
SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_HEARTBEAT_PERIOD_URL);
|
||||
topicSubscription.setHeartbeatPeriod(
|
||||
Integer.valueOf(timeoutExtension.getValue().primitiveValue()));
|
||||
topicSubscription.setHeartbeatPeriod(Integer.valueOf(
|
||||
channelHeartbeatPeriotUrlExtension.getValue().primitiveValue()));
|
||||
}
|
||||
if (channel.hasExtension(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_TIMEOUT_URL)) {
|
||||
org.hl7.fhir.r4.model.Extension timeoutExtension =
|
||||
org.hl7.fhir.r4.model.Extension channelTimeoutUrlExtension =
|
||||
channel.getExtensionByUrl(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_TIMEOUT_URL);
|
||||
topicSubscription.setTimeout(
|
||||
Integer.valueOf(timeoutExtension.getValue().primitiveValue()));
|
||||
Integer.valueOf(channelTimeoutUrlExtension.getValue().primitiveValue()));
|
||||
}
|
||||
if (channel.hasExtension(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_MAX_COUNT)) {
|
||||
org.hl7.fhir.r4.model.Extension timeoutExtension =
|
||||
org.hl7.fhir.r4.model.Extension channelMaxCountExtension =
|
||||
channel.getExtensionByUrl(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_MAX_COUNT);
|
||||
topicSubscription.setMaxCount(
|
||||
Integer.valueOf(timeoutExtension.getValue().primitiveValue()));
|
||||
}
|
||||
if (channel.getPayloadElement()
|
||||
.hasExtension(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_PAYLOAD_CONTENT)) {
|
||||
org.hl7.fhir.r4.model.Extension timeoutExtension = channel.getPayloadElement()
|
||||
.getExtensionByUrl(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_PAYLOAD_CONTENT);
|
||||
topicSubscription.setContent(org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.fromCode(
|
||||
timeoutExtension.getValue().primitiveValue()));
|
||||
Integer.valueOf(channelMaxCountExtension.getValue().primitiveValue()));
|
||||
}
|
||||
|
||||
// setting full-resource PayloadContent if backport-payload-content is not provided
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent payloadContent =
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE;
|
||||
|
||||
org.hl7.fhir.r4.model.Extension channelPayloadContentExtension = channel.getPayloadElement()
|
||||
.getExtensionByUrl(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_PAYLOAD_CONTENT);
|
||||
|
||||
if (nonNull(channelPayloadContentExtension)) {
|
||||
payloadContent = org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.fromCode(
|
||||
channelPayloadContentExtension.getValue().primitiveValue());
|
||||
}
|
||||
|
||||
topicSubscription.setContent(payloadContent);
|
||||
} else {
|
||||
retVal.setCriteriaString(getCriteria(theSubscription));
|
||||
retVal.setEndpointUrl(channel.getEndpoint());
|
||||
|
@ -423,13 +428,25 @@ public class SubscriptionCanonicalizer {
|
|||
}
|
||||
|
||||
if (retVal.isTopicSubscription()) {
|
||||
retVal.getTopicSubscription().setTopic(getCriteria(theSubscription));
|
||||
CanonicalTopicSubscription topicSubscription = retVal.getTopicSubscription();
|
||||
topicSubscription.setTopic(getCriteria(theSubscription));
|
||||
|
||||
// WIP STR5 support other content types
|
||||
retVal.getTopicSubscription()
|
||||
.setContent(org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE);
|
||||
retVal.setEndpointUrl(channel.getEndpoint());
|
||||
retVal.setChannelType(getChannelType(subscription));
|
||||
|
||||
// setting full-resource PayloadContent if backport-payload-content is not provided
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent payloadContent =
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE;
|
||||
|
||||
org.hl7.fhir.r4b.model.Extension channelPayloadContentExtension = channel.getPayloadElement()
|
||||
.getExtensionByUrl(SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_PAYLOAD_CONTENT);
|
||||
|
||||
if (nonNull(channelPayloadContentExtension)) {
|
||||
payloadContent = org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.fromCode(
|
||||
channelPayloadContentExtension.getValue().primitiveValue());
|
||||
}
|
||||
|
||||
topicSubscription.setContent(payloadContent);
|
||||
} else {
|
||||
retVal.setCriteriaString(getCriteria(theSubscription));
|
||||
retVal.setEndpointUrl(channel.getEndpoint());
|
||||
|
|
|
@ -6,6 +6,7 @@ import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscriptionChannelType;
|
|||
import ca.uhn.fhir.jpa.subscription.model.CanonicalTopicSubscriptionFilter;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.primitive.BooleanDt;
|
||||
import ca.uhn.fhir.subscription.SubscriptionConstants;
|
||||
import ca.uhn.fhir.subscription.SubscriptionTestDataHelper;
|
||||
import org.hl7.fhir.r4.model.BooleanType;
|
||||
import org.hl7.fhir.r4.model.Extension;
|
||||
|
@ -14,6 +15,8 @@ import org.hl7.fhir.r5.model.Coding;
|
|||
import org.hl7.fhir.r5.model.Enumerations;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static ca.uhn.fhir.rest.api.Constants.CT_FHIR_JSON_NEW;
|
||||
import static ca.uhn.fhir.util.HapiExtensions.EX_SEND_DELETE_MESSAGES;
|
||||
|
@ -83,16 +86,12 @@ class SubscriptionCanonicalizerTest {
|
|||
assertTrue(canonicalize.getSendDeleteMessages());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testR5() {
|
||||
// setup
|
||||
SubscriptionCanonicalizer r5Canonicalizer = new SubscriptionCanonicalizer(FhirContext.forR5Cached());
|
||||
private org.hl7.fhir.r5.model.Subscription buildR5Subscription(org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent thePayloadContent) {
|
||||
org.hl7.fhir.r5.model.Subscription subscription = new org.hl7.fhir.r5.model.Subscription();
|
||||
|
||||
subscription.setStatus(Enumerations.SubscriptionStatusCodes.ACTIVE);
|
||||
subscription.setContentType(CT_FHIR_JSON_NEW);
|
||||
// WIP STR5 support different content types
|
||||
subscription.setContent(org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE);
|
||||
subscription.setContent(thePayloadContent);
|
||||
subscription.setEndpoint("http://foo");
|
||||
subscription.setTopic(SubscriptionTestDataHelper.TEST_TOPIC);
|
||||
Coding channelType = new Coding().setSystem("http://terminology.hl7.org/CodeSystem/subscription-channel-type").setCode("rest-hook");
|
||||
|
@ -102,13 +101,25 @@ class SubscriptionCanonicalizerTest {
|
|||
subscription.setHeartbeatPeriod(123);
|
||||
subscription.setMaxCount(456);
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"full-resource", "id-only", "empty"})
|
||||
public void testR5Canonicalize_returnsCorrectCanonicalSubscription(String thePayloadContent) {
|
||||
// setup
|
||||
SubscriptionCanonicalizer r5Canonicalizer = new SubscriptionCanonicalizer(FhirContext.forR5Cached());
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent payloadContent =
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.fromCode(thePayloadContent);
|
||||
org.hl7.fhir.r5.model.Subscription subscription = buildR5Subscription(payloadContent);
|
||||
|
||||
// execute
|
||||
CanonicalSubscription canonical = r5Canonicalizer.canonicalize(subscription);
|
||||
|
||||
// verify
|
||||
assertEquals(Subscription.SubscriptionStatus.ACTIVE, canonical.getStatus());
|
||||
assertEquals(CT_FHIR_JSON_NEW, canonical.getContentType());
|
||||
assertEquals(org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE, canonical.getContent());
|
||||
assertEquals(payloadContent, canonical.getContent());
|
||||
assertEquals("http://foo", canonical.getEndpointUrl());
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_TOPIC, canonical.getTopic());
|
||||
assertEquals(CanonicalSubscriptionChannelType.RESTHOOK, canonical.getChannelType());
|
||||
|
@ -131,37 +142,72 @@ class SubscriptionCanonicalizerTest {
|
|||
assertEquals(456, canonical.getMaxCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testR4Backport() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"full-resource", "id-only", "empty"})
|
||||
void testR4BCanonicalize_returnsCorrectCanonicalSubscription(String thePayloadContent) {
|
||||
// Example drawn from http://build.fhir.org/ig/HL7/fhir-subscription-backport-ig/Subscription-subscription-zulip.json.html
|
||||
|
||||
// setup
|
||||
SubscriptionCanonicalizer r4bCanonicalizer = new SubscriptionCanonicalizer(FhirContext.forR4BCached());
|
||||
org.hl7.fhir.r4b.model.Subscription subscription = buildR4BSubscription(thePayloadContent);
|
||||
|
||||
// execute
|
||||
CanonicalSubscription canonical = r4bCanonicalizer.canonicalize(subscription);
|
||||
|
||||
// verify
|
||||
assertEquals(Subscription.SubscriptionStatus.ACTIVE, canonical.getStatus());
|
||||
verifyStandardSubscriptionParameters(canonical);
|
||||
verifyChannelParameters(canonical, thePayloadContent);
|
||||
}
|
||||
|
||||
private org.hl7.fhir.r4b.model.Subscription buildR4BSubscription(String thePayloadContent) {
|
||||
org.hl7.fhir.r4b.model.Subscription subscription = new org.hl7.fhir.r4b.model.Subscription();
|
||||
|
||||
subscription.setId("testId");
|
||||
subscription.getMeta().addTag("http://a", "b", "c");
|
||||
subscription.getMeta().addTag("http://d", "e", "f");
|
||||
subscription.setStatus(org.hl7.fhir.r4b.model.Enumerations.SubscriptionStatus.ACTIVE);
|
||||
subscription.getChannel().setPayload(CT_FHIR_JSON_NEW);
|
||||
subscription.getChannel().setType(org.hl7.fhir.r4b.model.Subscription.SubscriptionChannelType.RESTHOOK);
|
||||
subscription.getChannel().setEndpoint(SubscriptionTestDataHelper.TEST_ENDPOINT);
|
||||
|
||||
subscription.getMeta().addProfile(SubscriptionConstants.SUBSCRIPTION_TOPIC_PROFILE_URL);
|
||||
subscription.setCriteria(SubscriptionTestDataHelper.TEST_TOPIC);
|
||||
|
||||
subscription.getChannel().setPayload(CT_FHIR_JSON_NEW);
|
||||
subscription.getChannel().addHeader(SubscriptionTestDataHelper.TEST_HEADER1);
|
||||
subscription.getChannel().addHeader(SubscriptionTestDataHelper.TEST_HEADER2);
|
||||
subscription.setStatus(org.hl7.fhir.r4b.model.Enumerations.SubscriptionStatus.ACTIVE);
|
||||
|
||||
subscription
|
||||
.getChannel()
|
||||
.getPayloadElement()
|
||||
.addExtension(
|
||||
SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_PAYLOAD_CONTENT,
|
||||
new org.hl7.fhir.r4b.model.CodeType(thePayloadContent));
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"full-resource", "id-only", "empty"})
|
||||
void testR4canonicalize_withBackPortedSubscription_returnsCorrectCanonicalSubscription(String thePayloadContent) {
|
||||
// Example drawn from http://build.fhir.org/ig/HL7/fhir-subscription-backport-ig/Subscription-subscription-zulip.json.html
|
||||
|
||||
// setup
|
||||
SubscriptionCanonicalizer r4Canonicalizer = new SubscriptionCanonicalizer(FhirContext.forR4Cached());
|
||||
|
||||
// execute
|
||||
|
||||
CanonicalSubscription canonical = r4Canonicalizer.canonicalize(SubscriptionTestDataHelper.buildR4TopicSubscription());
|
||||
Subscription subscription = SubscriptionTestDataHelper.buildR4TopicSubscriptionWithContent(thePayloadContent);
|
||||
CanonicalSubscription canonical = r4Canonicalizer.canonicalize(subscription);
|
||||
|
||||
// verify
|
||||
|
||||
// Standard R4 stuff
|
||||
assertEquals(2, canonical.getTags().size());
|
||||
assertEquals("b", canonical.getTags().get("http://a"));
|
||||
assertEquals("e", canonical.getTags().get("http://d"));
|
||||
assertEquals("testId", canonical.getIdPart());
|
||||
assertEquals("testId", canonical.getIdElementString());
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_ENDPOINT, canonical.getEndpointUrl());
|
||||
assertEquals(CT_FHIR_JSON_NEW, canonical.getContentType());
|
||||
assertThat(canonical.getHeaders(), hasSize(2));
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_HEADER1, canonical.getHeaders().get(0));
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_HEADER2, canonical.getHeaders().get(1));
|
||||
verifyStandardSubscriptionParameters(canonical);
|
||||
assertEquals(Subscription.SubscriptionStatus.ACTIVE, canonical.getStatus());
|
||||
verifyChannelParameters(canonical, thePayloadContent);
|
||||
|
||||
assertEquals(CT_FHIR_JSON_NEW, canonical.getContentType());
|
||||
assertEquals(org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.FULLRESOURCE, canonical.getContent());
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_ENDPOINT, canonical.getEndpointUrl());
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_TOPIC, canonical.getTopic());
|
||||
assertEquals(CanonicalSubscriptionChannelType.RESTHOOK, canonical.getChannelType());
|
||||
assertThat(canonical.getFilters(), hasSize(2));
|
||||
|
||||
CanonicalTopicSubscriptionFilter filter1 = canonical.getFilters().get(0);
|
||||
|
@ -183,6 +229,26 @@ class SubscriptionCanonicalizerTest {
|
|||
assertEquals(20, canonical.getMaxCount());
|
||||
}
|
||||
|
||||
private void verifyChannelParameters(CanonicalSubscription theCanonicalSubscriptions, String thePayloadContent) {
|
||||
assertThat(theCanonicalSubscriptions.getHeaders(), hasSize(2));
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_HEADER1, theCanonicalSubscriptions.getHeaders().get(0));
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_HEADER2, theCanonicalSubscriptions.getHeaders().get(1));
|
||||
|
||||
assertEquals(CT_FHIR_JSON_NEW, theCanonicalSubscriptions.getContentType());
|
||||
assertEquals(thePayloadContent, theCanonicalSubscriptions.getContent().toCode());
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_ENDPOINT, theCanonicalSubscriptions.getEndpointUrl());
|
||||
assertEquals(SubscriptionTestDataHelper.TEST_TOPIC, theCanonicalSubscriptions.getTopic());
|
||||
assertEquals(CanonicalSubscriptionChannelType.RESTHOOK, theCanonicalSubscriptions.getChannelType());
|
||||
}
|
||||
|
||||
private void verifyStandardSubscriptionParameters(CanonicalSubscription theCanonicalSubscription) {
|
||||
assertEquals(2, theCanonicalSubscription.getTags().size());
|
||||
assertEquals("b", theCanonicalSubscription.getTags().get("http://a"));
|
||||
assertEquals("e", theCanonicalSubscription.getTags().get("http://d"));
|
||||
assertEquals("testId", theCanonicalSubscription.getIdPart());
|
||||
assertEquals("testId", theCanonicalSubscription.getIdElementString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static org.hl7.fhir.r5.model.Subscription.SubscriptionFilterByComponent buildFilter(String theResourceType, String theParam, String theValue) {
|
||||
org.hl7.fhir.r5.model.Subscription.SubscriptionFilterByComponent filter = new org.hl7.fhir.r5.model.Subscription.SubscriptionFilterByComponent();
|
||||
|
|
|
@ -36,6 +36,10 @@ public class SubscriptionTestDataHelper {
|
|||
public static final String TEST_HEADER2 = "X-Bar: BAR";
|
||||
|
||||
public static Subscription buildR4TopicSubscription() {
|
||||
return buildR4TopicSubscriptionWithContent("full-resource");
|
||||
}
|
||||
|
||||
public static Subscription buildR4TopicSubscriptionWithContent(String theChannelPayloadContent) {
|
||||
Subscription subscription = new Subscription();
|
||||
|
||||
// Standard R4 stuff
|
||||
|
@ -75,7 +79,7 @@ public class SubscriptionTestDataHelper {
|
|||
.getPayloadElement()
|
||||
.addExtension(
|
||||
SubscriptionConstants.SUBSCRIPTION_TOPIC_CHANNEL_PAYLOAD_CONTENT,
|
||||
new CodeType("full-resource"));
|
||||
new CodeType(theChannelPayloadContent));
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue