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.status;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
024import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
025import ca.uhn.fhir.jpa.topic.SubscriptionTopicUtil;
026import ca.uhn.fhir.subscription.SubscriptionConstants;
027import org.hl7.fhir.instance.model.api.IBaseResource;
028import org.hl7.fhir.r4.model.CanonicalType;
029import org.hl7.fhir.r4.model.CodeType;
030import org.hl7.fhir.r4.model.DateType;
031import org.hl7.fhir.r4.model.Parameters;
032import org.hl7.fhir.r4.model.Reference;
033import org.hl7.fhir.r4.model.StringType;
034import org.hl7.fhir.r4.model.Subscription;
035import org.hl7.fhir.r5.model.SubscriptionStatus;
036
037import java.util.Date;
038import java.util.List;
039import java.util.UUID;
040
041public class R4NotificationStatusBuilder implements INotificationStatusBuilder<Parameters> {
042        private final FhirContext myFhirContext;
043
044        public R4NotificationStatusBuilder(FhirContext theFhirContext) {
045                myFhirContext = theFhirContext;
046        }
047
048        public Parameters buildNotificationStatus(
049                        List<IBaseResource> theResources, ActiveSubscription theActiveSubscription, String theTopicUrl) {
050                Long eventNumber = theActiveSubscription.getDeliveriesCount();
051                CanonicalSubscription canonicalSubscription = theActiveSubscription.getSubscription();
052
053                // See http://build.fhir.org/ig/HL7/fhir-subscription-backport-ig/Parameters-r4-notification-status.json.html
054                // and
055                // http://build.fhir.org/ig/HL7/fhir-subscription-backport-ig/StructureDefinition-backport-subscription-status-r4.html
056                Parameters parameters = new Parameters();
057                parameters.getMeta().addProfile(SubscriptionConstants.SUBSCRIPTION_TOPIC_STATUS);
058                parameters.setId(UUID.randomUUID().toString());
059                parameters.addParameter(
060                                "subscription",
061                                new Reference(theActiveSubscription.getSubscription().getIdElement(myFhirContext)));
062                parameters.addParameter("topic", new CanonicalType(theTopicUrl));
063                parameters.addParameter("status", new CodeType(Subscription.SubscriptionStatus.ACTIVE.toCode()));
064                parameters.addParameter(
065                                "type", new CodeType(SubscriptionStatus.SubscriptionNotificationType.EVENTNOTIFICATION.toCode()));
066                // WIP STR5 events-since-subscription-start should be read from the database
067                parameters.addParameter("events-since-subscription-start", eventNumber.toString());
068                Parameters.ParametersParameterComponent notificationEvent = parameters.addParameter();
069                notificationEvent.setName("notification-event");
070                notificationEvent.addPart().setName("event-number").setValue(new StringType(eventNumber.toString()));
071                notificationEvent.addPart().setName("timestamp").setValue(new DateType(new Date()));
072                if (!theResources.isEmpty() && !SubscriptionTopicUtil.isEmptyContentTopicSubscription(canonicalSubscription)) {
073                        IBaseResource firstResource = theResources.get(0);
074                        Reference resourceReference =
075                                        new Reference(firstResource.getIdElement().toUnqualifiedVersionless());
076
077                        notificationEvent.addPart().setName("focus").setValue(resourceReference);
078                }
079
080                return parameters;
081        }
082}