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.dao; 021 022import ca.uhn.fhir.interceptor.model.RequestPartitionId; 023import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient; 024import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters; 025import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; 026import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 027import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; 028import ca.uhn.fhir.model.api.IResource; 029import ca.uhn.fhir.rest.api.CacheControlDirective; 030import ca.uhn.fhir.rest.api.Constants; 031import ca.uhn.fhir.rest.api.SortSpec; 032import ca.uhn.fhir.rest.api.server.IBundleProvider; 033import ca.uhn.fhir.rest.api.server.RequestDetails; 034import ca.uhn.fhir.rest.param.DateRangeParam; 035import ca.uhn.fhir.rest.param.StringAndListParam; 036import ca.uhn.fhir.rest.param.TokenOrListParam; 037import ca.uhn.fhir.rest.param.TokenParam; 038import jakarta.servlet.http.HttpServletRequest; 039import org.hl7.fhir.instance.model.api.IBaseResource; 040import org.hl7.fhir.instance.model.api.IIdType; 041import org.hl7.fhir.instance.model.api.IPrimitiveType; 042import org.slf4j.Logger; 043import org.slf4j.LoggerFactory; 044import org.springframework.beans.factory.annotation.Autowired; 045import org.springframework.transaction.annotation.Propagation; 046import org.springframework.transaction.annotation.Transactional; 047 048import java.util.Collections; 049 050public class JpaResourceDaoPatient<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> 051 implements IFhirResourceDaoPatient<T> { 052 053 private static final Logger ourLog = LoggerFactory.getLogger(JpaResourceDaoPatient.class); 054 055 @Autowired 056 private IRequestPartitionHelperSvc myPartitionHelperSvc; 057 058 private IBundleProvider doEverythingOperation( 059 TokenOrListParam theIds, 060 IPrimitiveType<Integer> theCount, 061 IPrimitiveType<Integer> theOffset, 062 DateRangeParam theLastUpdated, 063 SortSpec theSort, 064 StringAndListParam theContent, 065 StringAndListParam theNarrative, 066 StringAndListParam theFilter, 067 StringAndListParam theTypes, 068 boolean theMdmExpand, 069 RequestDetails theRequest) { 070 SearchParameterMap paramMap = new SearchParameterMap(); 071 if (theCount != null) { 072 paramMap.setCount(theCount.getValue()); 073 } 074 if (theOffset != null) { 075 paramMap.setOffset(theOffset.getValue()); 076 } 077 if (theContent != null) { 078 paramMap.add(Constants.PARAM_CONTENT, theContent); 079 } 080 if (theNarrative != null) { 081 paramMap.add(Constants.PARAM_TEXT, theNarrative); 082 } 083 if (theTypes != null) { 084 paramMap.add(Constants.PARAM_TYPE, theTypes); 085 } else { 086 paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive())); 087 } 088 089 paramMap.setEverythingMode( 090 theIds != null && theIds.getValuesAsQueryTokens().size() == 1 091 ? EverythingModeEnum.PATIENT_INSTANCE 092 : EverythingModeEnum.PATIENT_TYPE); 093 paramMap.setSort(theSort); 094 paramMap.setLastUpdated(theLastUpdated); 095 if (theIds != null) { 096 if (theMdmExpand) { 097 theIds.getValuesAsQueryTokens().forEach(param -> param.setMdmExpand(true)); 098 } 099 paramMap.add("_id", theIds); 100 } 101 102 if (!isPagingProviderDatabaseBacked(theRequest)) { 103 paramMap.setLoadSynchronous(true); 104 } 105 106 RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType( 107 theRequest, getResourceName(), paramMap); 108 109 adjustCount(theRequest, paramMap); 110 111 return mySearchCoordinatorSvc.registerSearch( 112 this, 113 paramMap, 114 getResourceName(), 115 new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), 116 theRequest, 117 requestPartitionId); 118 } 119 120 private void adjustCount(RequestDetails theRequest, SearchParameterMap theParamMap) { 121 if (theRequest.getServer() == null) { 122 return; 123 } 124 125 if (theParamMap.getCount() == null && theRequest.getServer().getDefaultPageSize() != null) { 126 theParamMap.setCount(theRequest.getServer().getDefaultPageSize()); 127 return; 128 } 129 130 Integer maxPageSize = theRequest.getServer().getMaximumPageSize(); 131 if (maxPageSize != null && theParamMap.getCount() > maxPageSize) { 132 ourLog.info( 133 "Reducing {} from {} to {} which is the maximum allowable page size.", 134 Constants.PARAM_COUNT, 135 theParamMap.getCount(), 136 maxPageSize); 137 theParamMap.setCount(maxPageSize); 138 } 139 } 140 141 @Override 142 @Transactional(propagation = Propagation.SUPPORTS) 143 public IBundleProvider patientInstanceEverything( 144 HttpServletRequest theServletRequest, 145 RequestDetails theRequestDetails, 146 PatientEverythingParameters theQueryParams, 147 IIdType theId) { 148 TokenOrListParam id = new TokenOrListParam().add(new TokenParam(theId.getIdPart())); 149 return doEverythingOperation( 150 id, 151 theQueryParams.getCount(), 152 theQueryParams.getOffset(), 153 theQueryParams.getLastUpdated(), 154 theQueryParams.getSort(), 155 theQueryParams.getContent(), 156 theQueryParams.getNarrative(), 157 theQueryParams.getFilter(), 158 theQueryParams.getTypes(), 159 theQueryParams.getMdmExpand(), 160 theRequestDetails); 161 } 162 163 @Override 164 @Transactional(propagation = Propagation.SUPPORTS) 165 public IBundleProvider patientTypeEverything( 166 HttpServletRequest theServletRequest, 167 RequestDetails theRequestDetails, 168 PatientEverythingParameters theQueryParams, 169 TokenOrListParam theId) { 170 return doEverythingOperation( 171 theId, 172 theQueryParams.getCount(), 173 theQueryParams.getOffset(), 174 theQueryParams.getLastUpdated(), 175 theQueryParams.getSort(), 176 theQueryParams.getContent(), 177 theQueryParams.getNarrative(), 178 theQueryParams.getFilter(), 179 theQueryParams.getTypes(), 180 theQueryParams.getMdmExpand(), 181 theRequestDetails); 182 } 183}