001package ca.uhn.fhir.rest.server.provider;
002
003/*-
004 * #%L
005 * HAPI FHIR - Server Framework
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.FhirContext;
025import ca.uhn.fhir.rest.annotation.IdParam;
026import ca.uhn.fhir.rest.annotation.Operation;
027import ca.uhn.fhir.rest.annotation.OperationParam;
028import ca.uhn.fhir.rest.api.server.RequestDetails;
029import ca.uhn.fhir.rest.api.server.storage.IReindexJobSubmitter;
030import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
031import ca.uhn.fhir.util.ParametersUtil;
032import org.hl7.fhir.instance.model.api.IBaseParameters;
033import org.hl7.fhir.instance.model.api.IIdType;
034import org.hl7.fhir.instance.model.api.IPrimitiveType;
035import org.springframework.batch.core.JobExecution;
036import org.springframework.batch.core.JobParametersInvalidException;
037import org.springframework.beans.factory.annotation.Autowired;
038
039import javax.annotation.Nullable;
040import java.math.BigDecimal;
041import java.util.List;
042import java.util.stream.Collectors;
043
044public class ReindexProvider {
045        private final FhirContext myFhirContext;
046        private final IReindexJobSubmitter myReindexJobSubmitter;
047        private final MultiUrlProcessor myMultiUrlProcessor;
048
049        public ReindexProvider(FhirContext theFhirContext, IReindexJobSubmitter theReindexJobSubmitter) {
050                myFhirContext = theFhirContext;
051                myMultiUrlProcessor = new MultiUrlProcessor(theFhirContext, theReindexJobSubmitter);
052                myReindexJobSubmitter = theReindexJobSubmitter;
053        }
054
055        @Operation(name = ProviderConstants.OPERATION_REINDEX, idempotent = false)
056        public IBaseParameters Reindex(
057                @OperationParam(name = ProviderConstants.OPERATION_REINDEX_PARAM_URL, typeName = "string", min = 0, max = 1) List<IPrimitiveType<String>> theUrlsToReindex,
058                @OperationParam(name = ProviderConstants.OPERATION_REINDEX_PARAM_BATCH_SIZE, typeName = "decimal", min = 0, max = 1) IPrimitiveType<BigDecimal> theBatchSize,
059                @OperationParam(name = ProviderConstants.OPERATION_REINDEX_PARAM_EVERYTHING, typeName = "boolean", min = 0, max = 1) IPrimitiveType<Boolean> theEverything,
060                RequestDetails theRequestDetails
061        ) {
062                boolean everything = theEverything != null && theEverything.getValue();
063                @Nullable Integer batchSize = myMultiUrlProcessor.getBatchSize(theBatchSize);
064                if (everything) {
065                        return processEverything(batchSize, theRequestDetails);
066                } else if (theUrlsToReindex != null && !theUrlsToReindex.isEmpty()) {
067                        List<String> urls = theUrlsToReindex.stream().map(IPrimitiveType::getValue).collect(Collectors.toList());
068                        return myMultiUrlProcessor.processUrls(urls, batchSize, theRequestDetails);
069                } else {
070                        throw new InvalidRequestException(Msg.code(318) + ProviderConstants.OPERATION_REINDEX + " must specify either everything=true or provide at least one value for " + ProviderConstants.OPERATION_REINDEX_PARAM_URL);
071                }
072        }
073
074        private IBaseParameters processEverything(Integer theBatchSize, RequestDetails theRequestDetails) {
075                try {
076                        JobExecution jobExecution = myReindexJobSubmitter.submitEverythingJob(theBatchSize, theRequestDetails);
077                        IBaseParameters retVal = ParametersUtil.newInstance(myFhirContext);
078                        ParametersUtil.addParameterToParametersLong(myFhirContext, retVal, ProviderConstants.OPERATION_BATCH_RESPONSE_JOB_ID, jobExecution.getJobId());
079                        return retVal;
080                } catch (JobParametersInvalidException e) {
081                        throw new InvalidRequestException(Msg.code(319) + "Invalid job parameters: " + e.getMessage(), e);
082                }
083        }
084
085
086}