diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java index bee6cf9a1b3..c2c366ab2a5 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoSubscriptionDstu2.java @@ -84,6 +84,10 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2 headers) throws InterruptedException { + Subscription subscription = newSubscription(theCriteria, thePayload, theEndpoint, headers); + + MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute(); + mySubscriptionIds.add(methodOutcome.getId()); + + waitForQueueToDrain(); + + return (Subscription) methodOutcome.getResource(); + } + + @NotNull + private Subscription newSubscription(String theCriteria, String thePayload, String theEndpoint, List headers) { Subscription subscription = new Subscription(); subscription.setReason("Monitor new neonatal function (note, age will be determined by the monitor)"); subscription.setStatus(Subscription.SubscriptionStatus.REQUESTED); @@ -117,13 +131,7 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test { channel.setHeader(headers); } subscription.setChannel(channel); - - MethodOutcome methodOutcome = ourClient.create().resource(subscription).execute(); - mySubscriptionIds.add(methodOutcome.getId()); - - waitForQueueToDrain(); - - return (Subscription) methodOutcome.getResource(); + return subscription; } private Observation sendObservation(String code, String system) { @@ -514,6 +522,20 @@ public class RestHookTestDstu3Test extends BaseResourceProviderDstu3Test { assertTrue("Timed out waiting for subscription to match", communicationRequestListenerLatch.await(10, TimeUnit.SECONDS)); } + @Test + public void testSubscriptionWithNoStatusIsRejected() { + Subscription subscription = newSubscription("Observation?", "application/json", null, null); + subscription.setStatus(null); + + try { + ourClient.create().resource(subscription).execute(); + fail(); + } catch (UnprocessableEntityException e) { + assertThat(e.getMessage(), containsString("Can not process submitted Subscription - Subscription.status must be populated")); + } + } + + public static class ObservationListener implements IResourceProvider { @Create diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestR4Test.java index 65ada0547c0..c5d28bc0b1e 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/subscription/resthook/RestHookTestR4Test.java @@ -6,6 +6,8 @@ import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionConstants; import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.r4.model.*; @@ -20,8 +22,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.matchesPattern; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; /** @@ -876,6 +877,20 @@ public class RestHookTestR4Test extends BaseSubscriptionsR4Test { return toUnqualifiedVersionlessIdValues(found).size(); } + @Test + public void testSubscriptionWithNoStatusIsRejected() { + Subscription subscription = newSubscription("Observation?", "application/json"); + subscription.setStatus(null); + + try { + ourClient.create().resource(subscription).execute(); + fail(); + } catch (UnprocessableEntityException e) { + assertThat(e.getMessage(), containsString("Can not process submitted Subscription - Subscription.status must be populated")); + } + } + + @Test public void testBadSubscriptionDoesntPersist() { assertEquals(0, subscriptionCount()); diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 10667f0be03..bcbe27f2097 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -132,6 +132,11 @@ JPA server because of an indexing error. Thanks to Brian Reinhold for reporting! + + The JPA server now rejects subscriptions being submitted with no value in + Subscription.status (this field is mandatory, but the subscription was previously ignored + if no value was provided) +