From 9a54d7086e6d9093423af3010534aac757b35bb3 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Tue, 26 Mar 2019 05:39:40 -0400 Subject: [PATCH] Fix a couple of bugs (#1251) * might keep this * might keep this * undoing start in interface * fixed bug that only supported resources with ResourceType/id prefixes * added standalone subscription support for Dstu2. untested. * failing test * fixed cannonicalsubscription.equals for email * final cleanup --- .../IResourceModifiedConsumer.java | 0 .../SubscriptionMatcherInterceptor.java | 22 +++--- .../module/CanonicalSubscription.java | 22 ++++++ .../cache/SubscriptionCanonicalizer.java | 6 +- .../config/SubscriptionDstu2Config.java | 67 +++++++++++++++++++ .../StandaloneSubscriptionMessageHandler.java | 11 ++- .../module/CanonicalSubscriptionTest.java | 20 ++++++ 7 files changed, 135 insertions(+), 13 deletions(-) mode change 100644 => 100755 hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/IResourceModifiedConsumer.java create mode 100755 hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/config/SubscriptionDstu2Config.java diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/IResourceModifiedConsumer.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/IResourceModifiedConsumer.java old mode 100644 new mode 100755 diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionMatcherInterceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionMatcherInterceptor.java index 894e20aaf2d..a5a002954e8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionMatcherInterceptor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionMatcherInterceptor.java @@ -51,14 +51,14 @@ public class SubscriptionMatcherInterceptor implements IResourceModifiedConsumer private Logger ourLog = LoggerFactory.getLogger(SubscriptionMatcherInterceptor.class); public static final String SUBSCRIPTION_MATCHING_CHANNEL_NAME = "subscription-matching"; - private SubscribableChannel myProcessingChannel; + protected SubscribableChannel myMatchingChannel; @Autowired private FhirContext myFhirContext; @Autowired private SubscriptionMatchingSubscriber mySubscriptionMatchingSubscriber; @Autowired - private SubscriptionChannelFactory mySubscriptionChannelFactory; + protected SubscriptionChannelFactory mySubscriptionChannelFactory; /** * Constructor @@ -68,11 +68,11 @@ public class SubscriptionMatcherInterceptor implements IResourceModifiedConsumer } public void start() { - if (myProcessingChannel == null) { - myProcessingChannel = mySubscriptionChannelFactory.newMatchingChannel(SUBSCRIPTION_MATCHING_CHANNEL_NAME); + if (myMatchingChannel == null) { + myMatchingChannel = mySubscriptionChannelFactory.newMatchingChannel(SUBSCRIPTION_MATCHING_CHANNEL_NAME); } - myProcessingChannel.subscribe(mySubscriptionMatchingSubscriber); - ourLog.info("Subscription Matching Subscriber subscribed to Matching Channel {} with name {}", myProcessingChannel.getClass().getName(), SUBSCRIPTION_MATCHING_CHANNEL_NAME); + myMatchingChannel.subscribe(mySubscriptionMatchingSubscriber); + ourLog.info("Subscription Matching Subscriber subscribed to Matching Channel {} with name {}", myMatchingChannel.getClass().getName(), SUBSCRIPTION_MATCHING_CHANNEL_NAME); } @@ -80,8 +80,8 @@ public class SubscriptionMatcherInterceptor implements IResourceModifiedConsumer @PreDestroy public void preDestroy() { - if (myProcessingChannel != null) { - myProcessingChannel.unsubscribe(mySubscriptionMatchingSubscriber); + if (myMatchingChannel != null) { + myMatchingChannel.unsubscribe(mySubscriptionMatchingSubscriber); } } @@ -115,8 +115,8 @@ public class SubscriptionMatcherInterceptor implements IResourceModifiedConsumer protected void sendToProcessingChannel(final ResourceModifiedMessage theMessage) { ourLog.trace("Sending resource modified message to processing channel"); - Validate.notNull(myProcessingChannel, "A SubscriptionMatcherInterceptor has been registered without calling start() on it."); - myProcessingChannel.send(new ResourceModifiedJsonMessage(theMessage)); + Validate.notNull(myMatchingChannel, "A SubscriptionMatcherInterceptor has been registered without calling start() on it."); + myMatchingChannel.send(new ResourceModifiedJsonMessage(theMessage)); } public void setFhirContext(FhirContext theCtx) { @@ -152,6 +152,6 @@ public class SubscriptionMatcherInterceptor implements IResourceModifiedConsumer @VisibleForTesting LinkedBlockingQueueSubscribableChannel getProcessingChannelForUnitTest() { - return (LinkedBlockingQueueSubscribableChannel) myProcessingChannel; + return (LinkedBlockingQueueSubscribableChannel) myMatchingChannel; } } diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java index 66ff70e4f47..13428b0c9bd 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscription.java @@ -308,6 +308,28 @@ public class CanonicalSubscription implements Serializable, Cloneable { public void setSubjectTemplate(String theSubjectTemplate) { mySubjectTemplate = theSubjectTemplate; } + + @Override + public boolean equals(Object theO) { + if (this == theO) return true; + + if (theO == null || getClass() != theO.getClass()) return false; + + EmailDetails that = (EmailDetails) theO; + + return new EqualsBuilder() + .append(myFrom, that.myFrom) + .append(mySubjectTemplate, that.mySubjectTemplate) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(myFrom) + .append(mySubjectTemplate) + .toHashCode(); + } } @JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java index 3b36116605a..f0ec4779ca4 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/cache/SubscriptionCanonicalizer.java @@ -51,8 +51,12 @@ import static java.util.stream.Collectors.toList; public class SubscriptionCanonicalizer { private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionCanonicalizer.class); + final FhirContext myFhirContext; + @Autowired - FhirContext myFhirContext; + public SubscriptionCanonicalizer(FhirContext theFhirContext) { + myFhirContext = theFhirContext; + } public CanonicalSubscription canonicalize(S theSubscription) { switch (myFhirContext.getVersion().getVersion()) { diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/config/SubscriptionDstu2Config.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/config/SubscriptionDstu2Config.java new file mode 100755 index 00000000000..c302868b9d0 --- /dev/null +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/config/SubscriptionDstu2Config.java @@ -0,0 +1,67 @@ +package ca.uhn.fhir.jpa.subscription.module.config; + +/*- + * #%L + * HAPI FHIR Subscription Server + * %% + * Copyright (C) 2014 - 2019 University Health Network + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.ParserOptions; +import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorDstu2; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryDstu2; +import org.hl7.fhir.instance.hapi.validation.DefaultProfileValidationSupport; +import org.hl7.fhir.instance.hapi.validation.IValidationSupport; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +public class SubscriptionDstu2Config extends BaseSubscriptionConfig { + @Override + public FhirContext fhirContext() { + return fhirContextDstu2(); + } + + @Bean + @Primary + public FhirContext fhirContextDstu2() { + FhirContext retVal = FhirContext.forDstu2(); + + // Don't strip versions in some places + ParserOptions parserOptions = retVal.getParserOptions(); + parserOptions.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference"); + + return retVal; + } + + @Bean + public ISearchParamRegistry searchParamRegistry() { + return new SearchParamRegistryDstu2(); + } + + @Bean(autowire = Autowire.BY_TYPE) + public SearchParamExtractorDstu2 searchParamExtractor() { + return new SearchParamExtractorDstu2(); + } + + @Primary + @Bean(autowire = Autowire.BY_NAME, name = "myJpaValidationSupportChainDstu2") + public IValidationSupport validationSupportChainDstu2() { + return new DefaultProfileValidationSupport(); + } +} diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/standalone/StandaloneSubscriptionMessageHandler.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/standalone/StandaloneSubscriptionMessageHandler.java index e4b94a9f898..ea7fa534624 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/standalone/StandaloneSubscriptionMessageHandler.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/module/standalone/StandaloneSubscriptionMessageHandler.java @@ -82,8 +82,17 @@ public class StandaloneSubscriptionMessageHandler implements MessageHandler { } private boolean isSubscription(ResourceModifiedMessage theResourceModifiedMessage) { + String resourceType; IIdType id = theResourceModifiedMessage.getId(myFhirContext); - RuntimeResourceDefinition resourceDef = myFhirContext.getResourceDefinition(id.getResourceType()); + if (id != null) { + resourceType = id.getResourceType(); + } else { + resourceType = theResourceModifiedMessage.getNewPayload(myFhirContext).getIdElement().getResourceType(); + } + if (resourceType == null) { + return false; + } + RuntimeResourceDefinition resourceDef = myFhirContext.getResourceDefinition(resourceType); return resourceDef.getName().equals(ResourceTypeEnum.SUBSCRIPTION.getCode()); } diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscriptionTest.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscriptionTest.java index 4503f279e80..fefd9fa4a92 100644 --- a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscriptionTest.java +++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/CanonicalSubscriptionTest.java @@ -1,10 +1,13 @@ package ca.uhn.fhir.jpa.subscription.module; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionCanonicalizer; import ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryJsonMessage; import ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage; import com.fasterxml.jackson.databind.ObjectMapper; import org.assertj.core.util.Lists; import org.hamcrest.Matchers; +import org.hl7.fhir.r4.model.Subscription; import org.junit.Test; import java.io.IOException; @@ -12,6 +15,7 @@ import java.util.HashMap; import java.util.List; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; public class CanonicalSubscriptionTest { @@ -49,6 +53,22 @@ public class CanonicalSubscriptionTest { assertThat(s.getChannelExtensions("key3"), Matchers.empty()); } + @Test + public void emailDetailsEquals() { + SubscriptionCanonicalizer canonicalizer = new SubscriptionCanonicalizer<>(FhirContext.forR4()); + CanonicalSubscription sub1 = canonicalizer.canonicalize(makeEmailSubscription()); + CanonicalSubscription sub2 = canonicalizer.canonicalize(makeEmailSubscription()); + assertTrue(sub1.equals(sub2)); + } + + private Subscription makeEmailSubscription() { + Subscription retval = new Subscription(); + Subscription.SubscriptionChannelComponent channel = new Subscription.SubscriptionChannelComponent(); + channel.setType(Subscription.SubscriptionChannelType.EMAIL); + retval.setChannel(channel); + return retval; + } + private CanonicalSubscription serializeAndDeserialize(CanonicalSubscription theSubscription) throws IOException { ResourceDeliveryJsonMessage resourceDeliveryMessage = new ResourceDeliveryJsonMessage();