001/*-
002 * #%L
003 * HAPI FHIR Subscription Server
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.topic;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
024import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
025import ca.uhn.fhir.rest.server.messaging.BaseResourceMessage;
026import ca.uhn.fhir.util.BundleUtil;
027import org.hl7.fhir.instance.model.api.IBaseBundle;
028import org.hl7.fhir.instance.model.api.IBaseResource;
029import org.hl7.fhir.r5.model.BaseReference;
030import org.hl7.fhir.r5.model.Enumeration;
031import org.hl7.fhir.r5.model.SubscriptionStatus;
032import org.hl7.fhir.r5.model.SubscriptionTopic;
033
034import java.util.List;
035import java.util.Objects;
036
037public class SubscriptionTopicUtil {
038        public static boolean matches(
039                        BaseResourceMessage.OperationTypeEnum theOperationType,
040                        List<Enumeration<SubscriptionTopic.InteractionTrigger>> theSupportedInteractions) {
041                for (Enumeration<SubscriptionTopic.InteractionTrigger> next : theSupportedInteractions) {
042                        if (next.getValue() == SubscriptionTopic.InteractionTrigger.CREATE
043                                        && theOperationType == BaseResourceMessage.OperationTypeEnum.CREATE) {
044                                return true;
045                        }
046                        if (next.getValue() == SubscriptionTopic.InteractionTrigger.UPDATE
047                                        && theOperationType == BaseResourceMessage.OperationTypeEnum.UPDATE) {
048                                return true;
049                        }
050                        if (next.getValue() == SubscriptionTopic.InteractionTrigger.DELETE
051                                        && theOperationType == BaseResourceMessage.OperationTypeEnum.DELETE) {
052                                return true;
053                        }
054                }
055                return false;
056        }
057
058        /**
059         * Extracts source resource from bundle contained in {@link ResourceModifiedJsonMessage} payload.
060         * Used for R5 resource modified message handling.
061         */
062        public static IBaseResource extractResourceFromBundle(FhirContext myFhirContext, IBaseBundle theBundle) {
063                List<IBaseResource> resources = BundleUtil.toListOfResources(myFhirContext, theBundle);
064
065                return resources.stream()
066                                .filter(SubscriptionStatus.class::isInstance)
067                                .map(SubscriptionStatus.class::cast)
068                                .flatMap(subscriptionStatus -> subscriptionStatus.getNotificationEvent().stream())
069                                .filter(SubscriptionStatus.SubscriptionStatusNotificationEventComponent::hasFocus)
070                                .map(SubscriptionStatus.SubscriptionStatusNotificationEventComponent::getFocus)
071                                .map(BaseReference::getResource)
072                                .filter(Objects::nonNull)
073                                .findFirst()
074                                .orElse(null);
075        }
076
077        /**
078         * Checks if {@link CanonicalSubscription} has EMPTY {@link org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent}
079         * Used for R5/R4B/R4 Notification Status object building.
080         */
081        public static boolean isEmptyContentTopicSubscription(CanonicalSubscription theCanonicalSubscription) {
082                return theCanonicalSubscription.isTopicSubscription()
083                                && org.hl7.fhir.r5.model.Subscription.SubscriptionPayloadContent.EMPTY
084                                                == theCanonicalSubscription.getTopicSubscription().getContent();
085        }
086}