001package ca.uhn.fhir.jpa.subscription.module.standalone; 002 003/*- 004 * #%L 005 * HAPI FHIR Subscription Server 006 * %% 007 * Copyright (C) 2014 - 2020 University Health Network 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import ca.uhn.fhir.context.FhirContext; 024import ca.uhn.fhir.context.RuntimeResourceDefinition; 025import ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage; 026import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionCanonicalizer; 027import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionConstants; 028import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionRegistry; 029import ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceModifiedJsonMessage; 030import ca.uhn.fhir.jpa.subscription.module.subscriber.SubscriptionMatchingSubscriber; 031import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum; 032import org.hl7.fhir.instance.model.api.IBaseResource; 033import org.hl7.fhir.instance.model.api.IIdType; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036import org.springframework.beans.factory.annotation.Autowired; 037import org.springframework.messaging.Message; 038import org.springframework.messaging.MessageHandler; 039import org.springframework.messaging.MessagingException; 040import org.springframework.stereotype.Service; 041 042@Service 043public class StandaloneSubscriptionMessageHandler implements MessageHandler { 044 private static final Logger ourLog = LoggerFactory.getLogger(StandaloneSubscriptionMessageHandler.class); 045 046 @Autowired 047 FhirContext myFhirContext; 048 @Autowired 049 SubscriptionMatchingSubscriber mySubscriptionMatchingSubscriber; 050 @Autowired 051 SubscriptionRegistry mySubscriptionRegistry; 052 @Autowired 053 SubscriptionCanonicalizer mySubscriptionCanonicalizer; 054 055 @Override 056 public void handleMessage(Message<?> theMessage) throws MessagingException { 057 if (!(theMessage instanceof ResourceModifiedJsonMessage)) { 058 ourLog.warn("Unexpected message payload type: {}", theMessage); 059 return; 060 } 061 updateSubscriptionRegistryAndPerformMatching(((ResourceModifiedJsonMessage) theMessage).getPayload()); 062 } 063 064 public void updateSubscriptionRegistryAndPerformMatching(ResourceModifiedMessage theResourceModifiedMessage) { 065 switch (theResourceModifiedMessage.getOperationType()) { 066 case DELETE: 067 if (isSubscription(theResourceModifiedMessage)) { 068 mySubscriptionRegistry.unregisterSubscription(theResourceModifiedMessage.getId(myFhirContext).getIdPart()); 069 } 070 return; 071 case CREATE: 072 case UPDATE: 073 if (isSubscription(theResourceModifiedMessage)) { 074 registerActiveSubscription(theResourceModifiedMessage.getNewPayload(myFhirContext)); 075 } 076 break; 077 default: 078 break; 079 } 080 081 mySubscriptionMatchingSubscriber.matchActiveSubscriptionsAndDeliver(theResourceModifiedMessage); 082 } 083 084 private boolean isSubscription(ResourceModifiedMessage theResourceModifiedMessage) { 085 String resourceType; 086 IIdType id = theResourceModifiedMessage.getId(myFhirContext); 087 if (id != null) { 088 resourceType = id.getResourceType(); 089 } else { 090 resourceType = theResourceModifiedMessage.getNewPayload(myFhirContext).getIdElement().getResourceType(); 091 } 092 if (resourceType == null) { 093 return false; 094 } 095 RuntimeResourceDefinition resourceDef = myFhirContext.getResourceDefinition(resourceType); 096 return resourceDef.getName().equals(ResourceTypeEnum.SUBSCRIPTION.getCode()); 097 } 098 099 private void registerActiveSubscription(IBaseResource theSubscription) { 100 String status = mySubscriptionCanonicalizer.getSubscriptionStatus(theSubscription); 101 if (SubscriptionConstants.ACTIVE_STATUS.equals(status)) { 102 mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(theSubscription); 103 } 104 } 105}