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