001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2024 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.search.reindex;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.context.RuntimeResourceDefinition;
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.dao.IFulltextSearchSvc;
028import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
029import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
030import ca.uhn.fhir.jpa.model.dao.JpaPid;
031import ca.uhn.fhir.jpa.model.entity.ResourceTable;
032import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
033import org.hl7.fhir.instance.model.api.IBaseResource;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036import org.springframework.beans.factory.annotation.Autowired;
037import org.springframework.stereotype.Service;
038
039/**
040 * @deprecated
041 */
042@Service
043public class ResourceReindexer {
044        private static final Logger ourLog = LoggerFactory.getLogger(ResourceReindexer.class);
045
046        @Autowired
047        private IResourceHistoryTableDao myResourceHistoryTableDao;
048
049        @Autowired
050        private IResourceTableDao myResourceTableDao;
051
052        @Autowired
053        private DaoRegistry myDaoRegistry;
054
055        @Autowired(required = false)
056        private IFulltextSearchSvc myFulltextSearchSvc;
057
058        private final FhirContext myFhirContext;
059
060        public ResourceReindexer(FhirContext theFhirContext) {
061                myFhirContext = theFhirContext;
062        }
063
064        public void readAndReindexResourceByPid(Long theResourcePid) {
065                ResourceTable resourceTable =
066                                myResourceTableDao.findById(theResourcePid).orElseThrow(IllegalStateException::new);
067                reindexResourceEntity(resourceTable);
068        }
069
070        public void reindexResourceEntity(ResourceTable theResourceTable) {
071                IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceTable.getResourceType());
072                long expectedVersion = theResourceTable.getVersion();
073                IBaseResource resource = dao.readByPid(JpaPid.fromId(theResourceTable.getId()), true);
074
075                if (resource == null) {
076                        throw new InternalErrorException(Msg.code(1171) + "Could not find resource version "
077                                        + theResourceTable.getIdDt().toUnqualified().getValue() + " in database");
078                }
079
080                Long actualVersion = resource.getIdElement().getVersionIdPartAsLong();
081                if (actualVersion < expectedVersion) {
082                        ourLog.warn(
083                                        "Resource {} version {} does not exist, renumbering version {}",
084                                        resource.getIdElement().toUnqualifiedVersionless().getValue(),
085                                        resource.getIdElement().getVersionIdPart(),
086                                        expectedVersion);
087                        myResourceHistoryTableDao.updateVersion(theResourceTable.getId(), actualVersion, expectedVersion);
088                }
089
090                doReindex(theResourceTable, resource);
091        }
092
093        @SuppressWarnings("unchecked")
094        <T extends IBaseResource> void doReindex(ResourceTable theResourceTable, T theResource) {
095                RuntimeResourceDefinition resourceDefinition = myFhirContext.getResourceDefinition(theResource.getClass());
096                Class<T> resourceClass = (Class<T>) resourceDefinition.getImplementingClass();
097                final IFhirResourceDao<T> dao = myDaoRegistry.getResourceDao(resourceClass);
098                dao.reindex(theResource, theResourceTable);
099                if (myFulltextSearchSvc != null && !myFulltextSearchSvc.isDisabled()) {
100                        // update the full-text index, if active.
101                        myFulltextSearchSvc.reindex(theResourceTable);
102                }
103        }
104}