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