001/*-
002 * #%L
003 * HAPI FHIR - Master Data Management
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.mdm.svc;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.interceptor.api.HookParams;
024import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
025import ca.uhn.fhir.interceptor.api.Pointcut;
026import ca.uhn.fhir.interceptor.model.RequestPartitionId;
027import ca.uhn.fhir.jpa.subscription.channel.api.ChannelProducerSettings;
028import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory;
029import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
030import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
031import ca.uhn.fhir.mdm.api.IMdmChannelSubmitterSvc;
032import ca.uhn.fhir.mdm.log.Logs;
033import ca.uhn.fhir.rest.api.Constants;
034import org.hl7.fhir.instance.model.api.IAnyResource;
035import org.hl7.fhir.instance.model.api.IBaseResource;
036import org.slf4j.Logger;
037import org.springframework.beans.factory.annotation.Autowired;
038import org.springframework.messaging.MessageChannel;
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 MessageChannel myMdmChannelProducer;
049
050        private final FhirContext myFhirContext;
051
052        private final IChannelFactory myChannelFactory;
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 = getMdmChannelProducer().send(resourceModifiedJsonMessage);
074                if (!success) {
075                        ourLog.error("Failed to submit {} to MDM Channel.", resourceModifiedMessage.getPayloadId());
076                }
077        }
078
079        @Autowired
080        public MdmChannelSubmitterSvcImpl(FhirContext theFhirContext, IChannelFactory theIChannelFactory) {
081                myFhirContext = theFhirContext;
082                myChannelFactory = theIChannelFactory;
083        }
084
085        private void init() {
086                ChannelProducerSettings channelSettings = new ChannelProducerSettings();
087                myMdmChannelProducer = myChannelFactory.getOrCreateProducer(
088                                EMPI_CHANNEL_NAME, ResourceModifiedJsonMessage.class, channelSettings);
089        }
090
091        private MessageChannel getMdmChannelProducer() {
092                if (myMdmChannelProducer == null) {
093                        init();
094                }
095                return myMdmChannelProducer;
096        }
097}