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}