001package ca.uhn.fhir.jpa.mdm.svc; 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.interceptor.model.RequestPartitionId; 024import ca.uhn.fhir.i18n.Msg; 025import ca.uhn.fhir.jpa.api.dao.DaoRegistry; 026import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; 027import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; 028import ca.uhn.fhir.jpa.model.entity.TagTypeEnum; 029import ca.uhn.fhir.jpa.partition.SystemRequestDetails; 030import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 031import ca.uhn.fhir.mdm.api.IMdmSettings; 032import ca.uhn.fhir.mdm.api.MdmConstants; 033import ca.uhn.fhir.rest.api.Constants; 034import ca.uhn.fhir.rest.api.server.IBundleProvider; 035import ca.uhn.fhir.rest.api.server.RequestDetails; 036import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; 037import ca.uhn.fhir.rest.param.TokenParam; 038import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 039import org.hl7.fhir.instance.model.api.IAnyResource; 040import org.hl7.fhir.instance.model.api.IBaseResource; 041import org.springframework.beans.factory.annotation.Autowired; 042import org.springframework.stereotype.Service; 043 044import javax.annotation.Nonnull; 045import java.util.List; 046import java.util.Optional; 047 048@Service 049public class MdmResourceDaoSvc { 050 051 private static final int MAX_MATCHING_GOLDEN_RESOURCES = 1000; 052 053 @Autowired 054 DaoRegistry myDaoRegistry; 055 @Autowired 056 IMdmSettings myMdmSettings; 057 058 public DaoMethodOutcome upsertGoldenResource(IAnyResource theGoldenResource, String theResourceType) { 059 IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType); 060 RequestDetails requestDetails = new SystemRequestDetails().setRequestPartitionId((RequestPartitionId) theGoldenResource.getUserData(Constants.RESOURCE_PARTITION_ID)); 061 if (theGoldenResource.getIdElement().hasIdPart()) { 062 return resourceDao.update(theGoldenResource, requestDetails); 063 } else { 064 return resourceDao.create(theGoldenResource, requestDetails); 065 } 066 } 067 068 /** 069 * Given a resource, remove its Golden Resource tag. 070 * 071 * @param theGoldenResource the {@link IAnyResource} to remove the tag from. 072 * @param theResourcetype the type of that resource 073 */ 074 public void removeGoldenResourceTag(IAnyResource theGoldenResource, String theResourcetype) { 075 IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourcetype); 076 RequestDetails requestDetails = new SystemRequestDetails().setRequestPartitionId((RequestPartitionId) theGoldenResource.getUserData(Constants.RESOURCE_PARTITION_ID)); 077 resourceDao.removeTag(theGoldenResource.getIdElement(), TagTypeEnum.TAG, MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD, requestDetails); 078 } 079 080 public IAnyResource readGoldenResourceByPid(ResourcePersistentId theGoldenResourcePid, String theResourceType) { 081 IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType); 082 return (IAnyResource) resourceDao.readByPid(theGoldenResourcePid); 083 } 084 085 public Optional<IAnyResource> searchGoldenResourceByEID(String theEid, String theResourceType) { 086 return this.searchGoldenResourceByEID(theEid, theResourceType, null); 087 } 088 089 public Optional<IAnyResource> searchGoldenResourceByEID(String theEid, String theResourceType, RequestPartitionId thePartitionId) { 090 SearchParameterMap map = buildEidSearchParameterMap(theEid, theResourceType); 091 092 IFhirResourceDao resourceDao = myDaoRegistry.getResourceDao(theResourceType); 093 SystemRequestDetails systemRequestDetails = new SystemRequestDetails(); 094 systemRequestDetails.setRequestPartitionId(thePartitionId); 095 IBundleProvider search = resourceDao.search(map, systemRequestDetails); 096 List<IBaseResource> resources = search.getResources(0, MAX_MATCHING_GOLDEN_RESOURCES); 097 098 if (resources.isEmpty()) { 099 return Optional.empty(); 100 } else if (resources.size() > 1) { 101 throw new InternalErrorException(Msg.code(737) + "Found more than one active " + 102 MdmConstants.CODE_HAPI_MDM_MANAGED + 103 " Golden Resource with EID " + 104 theEid + 105 ": " + 106 resources.get(0).getIdElement().getValue() + 107 ", " + 108 resources.get(1).getIdElement().getValue() 109 ); 110 } else { 111 return Optional.of((IAnyResource) resources.get(0)); 112 } 113 } 114 115 @Nonnull 116 private SearchParameterMap buildEidSearchParameterMap(String theEid, String theResourceType) { 117 SearchParameterMap map = new SearchParameterMap(); 118 map.setLoadSynchronous(true); 119 map.add("identifier", new TokenParam(myMdmSettings.getMdmRules().getEnterpriseEIDSystemForResourceType(theResourceType), theEid)); 120 map.add("_tag", new TokenParam(MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD)); 121 return map; 122 } 123}