001package ca.uhn.fhir.jpa.mdm.config; 002 003/*- 004 * #%L 005 * HAPI FHIR JPA Server - Master Data Management 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.ConfigurationException; 024import ca.uhn.fhir.context.FhirContext; 025import ca.uhn.fhir.i18n.Msg; 026import ca.uhn.fhir.jpa.api.dao.DaoRegistry; 027import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; 028import ca.uhn.fhir.jpa.partition.SystemRequestDetails; 029import ca.uhn.fhir.jpa.subscription.channel.api.ChannelProducerSettings; 030import ca.uhn.fhir.jpa.subscription.channel.subscription.IChannelNamer; 031import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader; 032import ca.uhn.fhir.mdm.api.IMdmSettings; 033import ca.uhn.fhir.mdm.api.MdmConstants; 034import ca.uhn.fhir.mdm.log.Logs; 035import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; 036import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; 037import ca.uhn.fhir.util.HapiExtensions; 038import org.hl7.fhir.instance.model.api.IBaseResource; 039import org.hl7.fhir.r4.model.BooleanType; 040import org.hl7.fhir.r4.model.Subscription; 041import org.slf4j.Logger; 042import org.springframework.beans.factory.annotation.Autowired; 043import org.springframework.stereotype.Service; 044 045import java.util.List; 046import java.util.stream.Collectors; 047 048@Service 049public class MdmSubscriptionLoader { 050 051 public static final String MDM_SUBSCIPRION_ID_PREFIX = "mdm-"; 052 private static final Logger ourLog = Logs.getMdmTroubleshootingLog(); 053 @Autowired 054 public FhirContext myFhirContext; 055 @Autowired 056 public DaoRegistry myDaoRegistry; 057 @Autowired 058 IChannelNamer myChannelNamer; 059 @Autowired 060 private SubscriptionLoader mySubscriptionLoader; 061 @Autowired 062 private IMdmSettings myMdmSettings; 063 064 private IFhirResourceDao<IBaseResource> mySubscriptionDao; 065 066 synchronized public void daoUpdateMdmSubscriptions() { 067 List<IBaseResource> subscriptions; 068 List<String> mdmResourceTypes = myMdmSettings.getMdmRules().getMdmTypes(); 069 switch (myFhirContext.getVersion().getVersion()) { 070 case DSTU3: 071 subscriptions = mdmResourceTypes 072 .stream() 073 .map(resourceType -> buildMdmSubscriptionDstu3(MDM_SUBSCIPRION_ID_PREFIX + resourceType, resourceType + "?")) 074 .collect(Collectors.toList()); 075 break; 076 case R4: 077 subscriptions = mdmResourceTypes 078 .stream() 079 .map(resourceType -> buildMdmSubscriptionR4(MDM_SUBSCIPRION_ID_PREFIX + resourceType, resourceType + "?")) 080 .collect(Collectors.toList()); 081 break; 082 default: 083 throw new ConfigurationException(Msg.code(736) + "MDM not supported for FHIR version " + myFhirContext.getVersion().getVersion()); 084 } 085 086 mySubscriptionDao = myDaoRegistry.getResourceDao("Subscription"); 087 for (IBaseResource subscription : subscriptions) { 088 updateIfNotPresent(subscription); 089 } 090 //After loading all the subscriptions, sync the subscriptions to the registry. 091 if (subscriptions != null && subscriptions.size() > 0) { 092 mySubscriptionLoader.syncSubscriptions(); 093 } 094 } 095 096 synchronized void updateIfNotPresent(IBaseResource theSubscription) { 097 try { 098 mySubscriptionDao.read(theSubscription.getIdElement(), SystemRequestDetails.forAllPartitions()); 099 } catch (ResourceNotFoundException | ResourceGoneException e) { 100 ourLog.info("Creating subscription " + theSubscription.getIdElement()); 101 mySubscriptionDao.update(theSubscription, SystemRequestDetails.forAllPartitions()); 102 } 103 } 104 105 private org.hl7.fhir.dstu3.model.Subscription buildMdmSubscriptionDstu3(String theId, String theCriteria) { 106 org.hl7.fhir.dstu3.model.Subscription retval = new org.hl7.fhir.dstu3.model.Subscription(); 107 retval.setId(theId); 108 retval.setReason("MDM"); 109 retval.setStatus(org.hl7.fhir.dstu3.model.Subscription.SubscriptionStatus.REQUESTED); 110 retval.setCriteria(theCriteria); 111 retval.getMeta().addTag().setSystem(MdmConstants.SYSTEM_MDM_MANAGED).setCode(MdmConstants.CODE_HAPI_MDM_MANAGED); 112 retval.addExtension().setUrl(HapiExtensions.EXTENSION_SUBSCRIPTION_CROSS_PARTITION).setValue(new org.hl7.fhir.dstu3.model.BooleanType().setValue(true)); 113 org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelComponent channel = retval.getChannel(); 114 channel.setType(org.hl7.fhir.dstu3.model.Subscription.SubscriptionChannelType.MESSAGE); 115 channel.setEndpoint("channel:" + myChannelNamer.getChannelName(IMdmSettings.EMPI_CHANNEL_NAME, new ChannelProducerSettings())); 116 channel.setPayload("application/json"); 117 return retval; 118 } 119 120 private Subscription buildMdmSubscriptionR4(String theId, String theCriteria) { 121 Subscription retval = new Subscription(); 122 retval.setId(theId); 123 retval.setReason("MDM"); 124 retval.setStatus(Subscription.SubscriptionStatus.REQUESTED); 125 retval.setCriteria(theCriteria); 126 retval.getMeta().addTag().setSystem(MdmConstants.SYSTEM_MDM_MANAGED).setCode(MdmConstants.CODE_HAPI_MDM_MANAGED); 127 retval.addExtension().setUrl(HapiExtensions.EXTENSION_SUBSCRIPTION_CROSS_PARTITION).setValue(new BooleanType().setValue(true)); 128 Subscription.SubscriptionChannelComponent channel = retval.getChannel(); 129 channel.setType(Subscription.SubscriptionChannelType.MESSAGE); 130 channel.setEndpoint("channel:" + myChannelNamer.getChannelName(IMdmSettings.EMPI_CHANNEL_NAME, new ChannelProducerSettings())); 131 channel.setPayload("application/json"); 132 return retval; 133 } 134}