001/*-
002 * #%L
003 * HAPI FHIR - Master Data Management
004 * %%
005 * Copyright (C) 2014 - 2025 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.mdm.svc;
021
022import ca.uhn.fhir.broker.api.ChannelProducerSettings;
023import ca.uhn.fhir.broker.api.IBrokerClient;
024import ca.uhn.fhir.broker.api.IChannelProducer;
025import ca.uhn.fhir.context.FhirContext;
026import ca.uhn.fhir.interceptor.api.HookParams;
027import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
028import ca.uhn.fhir.interceptor.api.Pointcut;
029import ca.uhn.fhir.interceptor.model.RequestPartitionId;
030import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
031import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
032import ca.uhn.fhir.mdm.api.IMdmChannelSubmitterSvc;
033import ca.uhn.fhir.mdm.log.Logs;
034import ca.uhn.fhir.rest.api.Constants;
035import org.hl7.fhir.instance.model.api.IAnyResource;
036import org.hl7.fhir.instance.model.api.IBaseResource;
037import org.slf4j.Logger;
038import org.springframework.beans.factory.annotation.Autowired;
039
040import static ca.uhn.fhir.mdm.api.IMdmSettings.EMPI_CHANNEL_NAME;
041
042/**
043 * This class is responsible for manual submissions of {@link IAnyResource} resources onto the MDM Channel.
044 */
045public class MdmChannelSubmitterSvcImpl implements IMdmChannelSubmitterSvc {
046        private static final Logger ourLog = Logs.getMdmTroubleshootingLog();
047
048        private IChannelProducer<ResourceModifiedMessage> myMdmChannelProducer;
049
050        private final FhirContext myFhirContext;
051
052        private final IBrokerClient myBrokerClient;
053
054        @Autowired
055        private IInterceptorBroadcaster myInterceptorBroadcaster;
056
057        @Override
058        public void submitResourceToMdmChannel(IBaseResource theResource) {
059                ResourceModifiedJsonMessage resourceModifiedJsonMessage = new ResourceModifiedJsonMessage();
060                ResourceModifiedMessage resourceModifiedMessage = new ResourceModifiedMessage(
061                                myFhirContext,
062                                theResource,
063                                ResourceModifiedMessage.OperationTypeEnum.MANUALLY_TRIGGERED,
064                                null,
065                                (RequestPartitionId) theResource.getUserData(Constants.RESOURCE_PARTITION_ID));
066                resourceModifiedMessage.setOperationType(ResourceModifiedMessage.OperationTypeEnum.MANUALLY_TRIGGERED);
067                resourceModifiedJsonMessage.setPayload(resourceModifiedMessage);
068                if (myInterceptorBroadcaster.hasHooks(Pointcut.MDM_SUBMIT_PRE_MESSAGE_DELIVERY)) {
069                        final HookParams params =
070                                        new HookParams().add(ResourceModifiedJsonMessage.class, resourceModifiedJsonMessage);
071                        myInterceptorBroadcaster.callHooks(Pointcut.MDM_SUBMIT_PRE_MESSAGE_DELIVERY, params);
072                }
073                boolean success =
074                                getMdmChannelProducer().send(resourceModifiedJsonMessage).isSuccessful();
075                if (!success) {
076                        ourLog.error("Failed to submit {} to MDM Channel.", resourceModifiedMessage.getPayloadId());
077                }
078        }
079
080        @Autowired
081        public MdmChannelSubmitterSvcImpl(FhirContext theFhirContext, IBrokerClient theBrokerClient) {
082                myFhirContext = theFhirContext;
083                myBrokerClient = theBrokerClient;
084        }
085
086        protected ChannelProducerSettings getChannelProducerSettings() {
087                return new ChannelProducerSettings();
088        }
089
090        private void init() {
091                ChannelProducerSettings channelSettings = getChannelProducerSettings();
092                myMdmChannelProducer = myBrokerClient.getOrCreateProducer(
093                                EMPI_CHANNEL_NAME, ResourceModifiedJsonMessage.class, channelSettings);
094        }
095
096        private IChannelProducer<ResourceModifiedMessage> getMdmChannelProducer() {
097                if (myMdmChannelProducer == null) {
098                        init();
099                }
100                return myMdmChannelProducer;
101        }
102}