001package ca.uhn.fhir.jpa.bulk.export.job;
002
003/*-
004 * #%L
005 * HAPI FHIR JPA Server
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.i18n.Msg;
024import ca.uhn.fhir.context.RuntimeResourceDefinition;
025import ca.uhn.fhir.context.RuntimeSearchParam;
026import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
027import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
028import ca.uhn.fhir.jpa.batch.config.BatchConstants;
029import ca.uhn.fhir.jpa.dao.ISearchBuilder;
030import ca.uhn.fhir.jpa.dao.SearchBuilderFactory;
031import ca.uhn.fhir.jpa.dao.data.IBulkExportJobDao;
032import ca.uhn.fhir.jpa.entity.BulkExportJobEntity;
033import ca.uhn.fhir.jpa.model.util.JpaConstants;
034import ca.uhn.fhir.util.SearchParameterUtil;
035import ca.uhn.fhir.util.UrlUtil;
036import org.hl7.fhir.instance.model.api.IBaseResource;
037import org.springframework.beans.factory.annotation.Autowired;
038import org.springframework.beans.factory.annotation.Value;
039
040import java.util.Date;
041import java.util.Map;
042import java.util.Optional;
043
044public abstract class BaseJpaBulkItemReader extends BaseBulkItemReader {
045        @Value("#{jobExecutionContext['" + BatchConstants.JOB_UUID_PARAMETER + "']}")
046        protected String myJobUUID;
047        @Autowired
048        protected DaoRegistry myDaoRegistry;
049        @Autowired
050        protected SearchBuilderFactory mySearchBuilderFactory;
051        @Autowired
052        private IBulkExportJobDao myBulkExportJobDao;
053
054        private ISearchBuilder mySearchBuilder;
055        private BulkExportJobEntity myJobEntity;
056
057        private RuntimeSearchParam myPatientSearchParam;
058
059        /**
060         * Get and cache an ISearchBuilder for the given resource type this partition is responsible for.
061         */
062        protected ISearchBuilder getSearchBuilderForLocalResourceType() {
063                if (mySearchBuilder == null) {
064                        IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(myResourceType);
065                        RuntimeResourceDefinition def = myContext.getResourceDefinition(myResourceType);
066                        Class<? extends IBaseResource> nextTypeClass = def.getImplementingClass();
067                        mySearchBuilder = mySearchBuilderFactory.newSearchBuilder(dao, myResourceType, nextTypeClass);
068                }
069                return mySearchBuilder;
070        }
071
072        @Override
073        protected String[] getTypeFilterList() {
074                BulkExportJobEntity jobEntity = getJobEntity();
075                Map<String, String[]> requestUrl = UrlUtil.parseQueryStrings(jobEntity.getRequest());
076                return requestUrl.get(JpaConstants.PARAM_EXPORT_TYPE_FILTER);
077        }
078
079        @Override
080        protected Date getSinceDate() {
081                return getJobEntity().getSince();
082        }
083
084        @Override
085        protected String getLogInfoForRead() {
086                return "Bulk export starting generation for batch export job: " + getJobEntity() + " with resourceType " + myResourceType + " and UUID " + myJobUUID;
087        }
088
089        protected BulkExportJobEntity getJobEntity() {
090                if (myJobEntity == null) {
091                        Optional<BulkExportJobEntity> jobOpt = myBulkExportJobDao.findByJobId(myJobUUID);
092                        if (jobOpt.isPresent()) {
093                                myJobEntity = jobOpt.get();
094                        } else {
095                                String errorMessage = String.format("Job with UUID %s does not exist!", myJobUUID);
096                                throw new IllegalStateException(Msg.code(795) + errorMessage);
097                        }
098                }
099                return myJobEntity;
100        }
101
102        protected RuntimeSearchParam getPatientSearchParamForCurrentResourceType() {
103                if (myPatientSearchParam == null) {
104                        Optional<RuntimeSearchParam> onlyPatientSearchParamForResourceType = SearchParameterUtil.getOnlyPatientSearchParamForResourceType(myContext, myResourceType);
105                        if (onlyPatientSearchParamForResourceType.isPresent()) {
106                                myPatientSearchParam = onlyPatientSearchParamForResourceType.get();
107                        }
108                }
109                return myPatientSearchParam;
110        }
111}