001package ca.uhn.fhir.jpa.mdm.svc.candidate;
002
003/*-
004 * #%L
005 * HAPI FHIR JPA Server - Master Data Management
006 * %%
007 * Copyright (C) 2014 - 2023 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.jpa.mdm.dao.MdmLinkDaoSvc;
025import ca.uhn.fhir.jpa.mdm.svc.MdmResourceDaoSvc;
026import ca.uhn.fhir.mdm.api.IMdmLink;
027import ca.uhn.fhir.mdm.api.MdmMatchOutcome;
028import ca.uhn.fhir.mdm.log.Logs;
029import ca.uhn.fhir.mdm.model.CanonicalEID;
030import ca.uhn.fhir.mdm.util.EIDHelper;
031import ca.uhn.fhir.rest.api.Constants;
032import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
033import org.hl7.fhir.instance.model.api.IAnyResource;
034import org.slf4j.Logger;
035import org.springframework.beans.factory.annotation.Autowired;
036import org.springframework.stereotype.Service;
037
038import java.util.ArrayList;
039import java.util.List;
040import java.util.Optional;
041
042@Service
043public class FindCandidateByEidSvc extends BaseCandidateFinder {
044
045        private static final Logger ourLog = Logs.getMdmTroubleshootingLog();
046
047        @Autowired
048        private EIDHelper myEIDHelper;
049        @Autowired
050        private MdmResourceDaoSvc myMdmResourceDaoSvc;
051        @Autowired
052        private MdmLinkDaoSvc myMdmLinkDaoSvc;
053
054        @Override
055        protected List<MatchedGoldenResourceCandidate> findMatchGoldenResourceCandidates(IAnyResource theIncomingResource) {
056                List<MatchedGoldenResourceCandidate> retval = new ArrayList<>();
057
058                List<CanonicalEID> eidFromResource = myEIDHelper.getExternalEid(theIncomingResource);
059                if (!eidFromResource.isEmpty()) {
060                        for (CanonicalEID eid : eidFromResource) {
061                                Optional<IAnyResource> oFoundGoldenResource = myMdmResourceDaoSvc.searchGoldenResourceByEID(eid.getValue(), theIncomingResource.getIdElement().getResourceType(), (RequestPartitionId) theIncomingResource.getUserData(Constants.RESOURCE_PARTITION_ID));
062                                if (oFoundGoldenResource.isPresent()) {
063                                        IAnyResource foundGoldenResource = oFoundGoldenResource.get();
064                                        // Exclude manually declared NO_MATCH links from candidates
065                                        if (isNoMatch(foundGoldenResource, theIncomingResource)) {
066                                                continue;
067                                        }
068                                        IResourcePersistentId pidOrNull = myIdHelperService.getPidOrNull(RequestPartitionId.allPartitions(), foundGoldenResource);
069                                        MatchedGoldenResourceCandidate mpc = new MatchedGoldenResourceCandidate(pidOrNull, MdmMatchOutcome.EID_MATCH);
070                                        ourLog.debug("Incoming Resource {} matched Golden Resource {} by EID {}", theIncomingResource.getIdElement().toUnqualifiedVersionless(), foundGoldenResource.getIdElement().toUnqualifiedVersionless(), eid);
071
072                                        retval.add(mpc);
073                                }
074                        }
075                }
076                return retval;
077        }
078
079        private boolean isNoMatch(IAnyResource theGoldenResource, IAnyResource theSourceResource) {
080                Optional<? extends IMdmLink> oLink = myMdmLinkDaoSvc.getLinkByGoldenResourceAndSourceResource(theGoldenResource, theSourceResource);
081                if (oLink.isEmpty()) {
082                        return false;
083                }
084                IMdmLink link = oLink.get();
085                return link.isNoMatch();
086        }
087
088        @Override
089        protected CandidateStrategyEnum getStrategy() {
090                return CandidateStrategyEnum.EID;
091        }
092}