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.provider; 021 022import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; 023import ca.uhn.fhir.jpa.model.util.JpaConstants; 024import ca.uhn.fhir.model.api.annotation.Description; 025import ca.uhn.fhir.rest.annotation.Operation; 026import ca.uhn.fhir.rest.annotation.OperationParam; 027import ca.uhn.fhir.rest.annotation.Transaction; 028import ca.uhn.fhir.rest.annotation.TransactionParam; 029import ca.uhn.fhir.rest.api.server.RequestDetails; 030import ca.uhn.fhir.rest.server.provider.ProviderConstants; 031import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; 032import ca.uhn.fhir.util.ParametersUtil; 033import org.hl7.fhir.instance.model.api.IBaseBundle; 034import org.hl7.fhir.instance.model.api.IBaseParameters; 035import org.hl7.fhir.instance.model.api.IBaseResource; 036import org.hl7.fhir.instance.model.api.IPrimitiveType; 037 038import java.util.Collections; 039import java.util.Map; 040import java.util.TreeMap; 041 042import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; 043import static org.apache.commons.lang3.StringUtils.isNotBlank; 044 045public final class JpaSystemProvider<T, MT> extends BaseJpaSystemProvider<T, MT> { 046 047 @Description( 048 "Marks all currently existing resources of a given type, or all resources of all types, for reindexing.") 049 @Operation( 050 name = MARK_ALL_RESOURCES_FOR_REINDEXING, 051 idempotent = false, 052 returnParameters = {@OperationParam(name = "status")}) 053 /** 054 * @deprecated 055 * @see ReindexProvider#Reindex(List, IPrimitiveType, RequestDetails) 056 */ 057 @Deprecated 058 public IBaseResource markAllResourcesForReindexing( 059 @OperationParam(name = "type", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theType) { 060 061 if (theType != null && isNotBlank(theType.getValueAsString())) { 062 getResourceReindexingSvc().markAllResourcesForReindexing(theType.getValueAsString()); 063 } else { 064 getResourceReindexingSvc().markAllResourcesForReindexing(); 065 } 066 067 IBaseParameters retVal = ParametersUtil.newInstance(getContext()); 068 069 IPrimitiveType<?> string = ParametersUtil.createString(getContext(), "Marked resources"); 070 ParametersUtil.addParameterToParameters(getContext(), retVal, "status", string); 071 072 return retVal; 073 } 074 075 @Description("Forces a single pass of the resource reindexing processor") 076 @Operation( 077 name = PERFORM_REINDEXING_PASS, 078 idempotent = false, 079 returnParameters = {@OperationParam(name = "status")}) 080 /** 081 * @deprecated 082 * @see ReindexProvider#Reindex(List, IPrimitiveType, RequestDetails) 083 */ 084 @Deprecated 085 public IBaseResource performReindexingPass() { 086 Integer count = getResourceReindexingSvc().runReindexingPass(); 087 088 IBaseParameters retVal = ParametersUtil.newInstance(getContext()); 089 090 IPrimitiveType<?> string; 091 if (count == null) { 092 string = ParametersUtil.createString(getContext(), "Index pass already proceeding"); 093 } else { 094 string = ParametersUtil.createString(getContext(), "Indexed " + count + " resources"); 095 } 096 ParametersUtil.addParameterToParameters(getContext(), retVal, "status", string); 097 098 return retVal; 099 } 100 101 @Operation(name = JpaConstants.OPERATION_GET_RESOURCE_COUNTS, idempotent = true) 102 @Description( 103 shortDefinition = 104 "Provides the number of resources currently stored on the server, broken down by resource type") 105 public IBaseParameters getResourceCounts() { 106 IBaseParameters retVal = ParametersUtil.newInstance(getContext()); 107 108 Map<String, Long> counts = getDao().getResourceCountsFromCache(); 109 counts = defaultIfNull(counts, Collections.emptyMap()); 110 counts = new TreeMap<>(counts); 111 for (Map.Entry<String, Long> nextEntry : counts.entrySet()) { 112 ParametersUtil.addParameterToParametersInteger( 113 getContext(), 114 retVal, 115 nextEntry.getKey(), 116 nextEntry.getValue().intValue()); 117 } 118 119 return retVal; 120 } 121 122 @Operation( 123 name = ProviderConstants.OPERATION_META, 124 idempotent = true, 125 returnParameters = {@OperationParam(name = "return", typeName = "Meta")}) 126 public IBaseParameters meta(RequestDetails theRequestDetails) { 127 IBaseParameters retVal = ParametersUtil.newInstance(getContext()); 128 ParametersUtil.addParameterToParameters( 129 getContext(), retVal, "return", getDao().metaGetOperation(theRequestDetails)); 130 return retVal; 131 } 132 133 @SuppressWarnings("unchecked") 134 @Transaction 135 public IBaseBundle transaction(RequestDetails theRequestDetails, @TransactionParam IBaseBundle theResources) { 136 startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest()); 137 try { 138 IFhirSystemDao<T, MT> dao = getDao(); 139 return (IBaseBundle) dao.transaction(theRequestDetails, (T) theResources); 140 } finally { 141 endRequest(((ServletRequestDetails) theRequestDetails).getServletRequest()); 142 } 143 } 144}