001package ca.uhn.fhir.jpa.subscription.match.matcher.subscriber;
002
003/*-
004 * #%L
005 * HAPI FHIR Subscription Server
006 * %%
007 * Copyright (C) 2014 - 2022 Smile CDR, Inc.
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.jpa.api.dao.DaoRegistry;
025import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
026import ca.uhn.fhir.jpa.model.config.PartitionSettings;
027import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
028import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionCanonicalizer;
029import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
030import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
031import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
032import ca.uhn.fhir.rest.api.server.RequestDetails;
033import org.hl7.fhir.instance.model.api.IBaseResource;
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;
040
041import javax.annotation.Nonnull;
042
043/**
044 * Responsible for transitioning subscription resources from REQUESTED to ACTIVE
045 * Once activated, the subscription is added to the SubscriptionRegistry.
046 * <p>
047 * Also validates criteria.  If invalid, rejects the subscription without persisting the subscription.
048 */
049public class SubscriptionRegisteringSubscriber extends BaseSubscriberForSubscriptionResources implements MessageHandler {
050        private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionRegisteringSubscriber.class);
051        @Autowired
052        private FhirContext myFhirContext;
053        @Autowired
054        private SubscriptionRegistry mySubscriptionRegistry;
055        @Autowired
056        private SubscriptionCanonicalizer mySubscriptionCanonicalizer;
057        @Autowired
058        private PartitionSettings myPartitionSettings;
059        @Autowired
060        private DaoRegistry myDaoRegistry;
061
062        /**
063         * Constructor
064         */
065        public SubscriptionRegisteringSubscriber() {
066                super();
067        }
068
069        @Override
070        public void handleMessage(@Nonnull Message<?> theMessage) throws MessagingException {
071                if (!(theMessage instanceof ResourceModifiedJsonMessage)) {
072                        ourLog.warn("Received message of unexpected type on matching channel: {}", theMessage);
073                        return;
074                }
075
076                ResourceModifiedMessage payload = ((ResourceModifiedJsonMessage) theMessage).getPayload();
077
078                if (!isSubscription(payload)) {
079                        return;
080                }
081
082                switch (payload.getOperationType()) {
083                        case DELETE:
084                                mySubscriptionRegistry.unregisterSubscriptionIfRegistered(payload.getPayloadId(myFhirContext).getIdPart());
085                                break;
086                        case CREATE:
087                        case UPDATE:
088                                IBaseResource subscription = payload.getNewPayload(myFhirContext);
089                                IBaseResource subscriptionToRegister = subscription;
090                                String statusString = mySubscriptionCanonicalizer.getSubscriptionStatus(subscription);
091
092                                // reading resource back from db in order to store partition id in the userdata of the resource for partitioned subscriptions
093                                if (myPartitionSettings.isPartitioningEnabled()) {
094                                        IFhirResourceDao subscriptionDao = myDaoRegistry.getSubscriptionDao();
095                                        RequestDetails systemRequestDetails = new SystemRequestDetails().setRequestPartitionId(payload.getPartitionId());
096                                        subscriptionToRegister = subscriptionDao.read(subscription.getIdElement(), systemRequestDetails);
097                                }
098
099                                if ("active".equals(statusString)) {
100                                        mySubscriptionRegistry.registerSubscriptionUnlessAlreadyRegistered(subscriptionToRegister);
101                                } else {
102                                        mySubscriptionRegistry.unregisterSubscriptionIfRegistered(payload.getPayloadId(myFhirContext).getIdPart());
103                                }
104                                break;
105                        case MANUALLY_TRIGGERED:
106                        default:
107                                break;
108                }
109
110        }
111
112}