001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2025 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.partition;
021
022import ca.uhn.fhir.i18n.Msg;
023import ca.uhn.fhir.interceptor.model.RequestPartitionId;
024import ca.uhn.fhir.jpa.entity.PartitionEntity;
025import ca.uhn.fhir.jpa.model.util.JpaConstants;
026import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
027import org.apache.commons.lang3.Validate;
028import org.springframework.beans.factory.annotation.Autowired;
029
030import java.util.ArrayList;
031import java.util.List;
032import java.util.Objects;
033
034public class RequestPartitionHelperSvc extends BaseRequestPartitionHelperSvc {
035
036        @Autowired
037        private IPartitionLookupSvc myPartitionConfigSvc;
038
039        public RequestPartitionHelperSvc() {}
040
041        @Override
042        public RequestPartitionId validateAndNormalizePartitionIds(RequestPartitionId theRequestPartitionId) {
043                List<String> names = null;
044                List<Integer> partitionIds = null;
045                List<Integer> originalPartitionIds = theRequestPartitionId.getPartitionIds();
046                for (int i = 0; i < originalPartitionIds.size(); i++) {
047
048                        PartitionEntity partition;
049                        Integer id = originalPartitionIds.get(i);
050                        if (id == null) {
051                                partition = null;
052                                if (myPartitionSettings.getDefaultPartitionId() != null) {
053                                        if (partitionIds == null) {
054                                                partitionIds = new ArrayList<>(originalPartitionIds);
055                                        }
056                                        partitionIds.set(i, myPartitionSettings.getDefaultPartitionId());
057                                }
058                        } else {
059                                try {
060                                        partition = myPartitionConfigSvc.getPartitionById(id);
061                                } catch (IllegalArgumentException e) {
062                                        String msg = myFhirContext
063                                                        .getLocalizer()
064                                                        .getMessage(
065                                                                        BaseRequestPartitionHelperSvc.class,
066                                                                        "unknownPartitionId",
067                                                                        originalPartitionIds.get(i));
068                                        throw new ResourceNotFoundException(Msg.code(1316) + msg);
069                                }
070                        }
071
072                        if (theRequestPartitionId.hasPartitionNames()) {
073                                if (partition == null) {
074                                        Validate.isTrue(
075                                                        originalPartitionIds.get(i) == null,
076                                                        "Partition %s must not have an ID",
077                                                        JpaConstants.DEFAULT_PARTITION_NAME);
078                                } else {
079                                        Validate.isTrue(
080                                                        Objects.equals(
081                                                                        theRequestPartitionId.getPartitionNames().get(i), partition.getName()),
082                                                        "Partition name %s does not match ID %s",
083                                                        theRequestPartitionId.getPartitionNames().get(i),
084                                                        originalPartitionIds.get(i));
085                                }
086                        } else {
087                                if (names == null) {
088                                        names = new ArrayList<>();
089                                }
090                                if (partition != null) {
091                                        names.add(partition.getName());
092                                } else {
093                                        names.add(null);
094                                }
095                        }
096                }
097
098                if (names != null) {
099                        List<Integer> partitionIdsToUse = originalPartitionIds;
100                        if (partitionIds != null) {
101                                partitionIdsToUse = partitionIds;
102                        }
103                        return RequestPartitionId.forPartitionIdsAndNames(
104                                        names,
105                                        partitionIdsToUse,
106                                        theRequestPartitionId.getPartitionDate(),
107                                        theRequestPartitionId.isAllPartitions());
108                }
109
110                return theRequestPartitionId;
111        }
112
113        @Override
114        public RequestPartitionId validateAndNormalizePartitionNames(RequestPartitionId theRequestPartitionId) {
115                List<Integer> ids = null;
116                for (int i = 0; i < theRequestPartitionId.getPartitionNames().size(); i++) {
117                        String partitionName = theRequestPartitionId.getPartitionNames().get(i);
118
119                        PartitionEntity partition = null;
120                        if (partitionName != null) {
121                                try {
122                                        partition = myPartitionConfigSvc.getPartitionByName(partitionName);
123                                } catch (IllegalArgumentException e) {
124                                        String msg = myFhirContext
125                                                        .getLocalizer()
126                                                        .getMessage(
127                                                                        BaseRequestPartitionHelperSvc.class,
128                                                                        "unknownPartitionName",
129                                                                        theRequestPartitionId.getPartitionNames().get(i));
130                                        throw new ResourceNotFoundException(Msg.code(1317) + msg);
131                                }
132                        }
133
134                        if (theRequestPartitionId.hasPartitionIds()) {
135                                Integer partitionId = theRequestPartitionId.getPartitionIds().get(i);
136                                if (partition == null) {
137                                        Validate.isTrue(
138                                                        partitionId == null || partitionId.equals(myPartitionSettings.getDefaultPartitionId()),
139                                                        "Partition %s must not have an ID",
140                                                        JpaConstants.DEFAULT_PARTITION_NAME);
141                                } else {
142                                        Validate.isTrue(
143                                                        Objects.equals(partitionId, partition.getId()),
144                                                        "Partition ID %s does not match name %s",
145                                                        partitionId,
146                                                        theRequestPartitionId.getPartitionNames().get(i));
147                                }
148                        } else {
149                                if (ids == null) {
150                                        ids = new ArrayList<>();
151                                }
152                                if (partition != null) {
153                                        ids.add(partition.getId());
154                                } else {
155                                        ids.add(myPartitionSettings.getDefaultPartitionId());
156                                }
157                        }
158                }
159
160                if (ids != null) {
161                        return RequestPartitionId.forPartitionIdsAndNames(
162                                        theRequestPartitionId.getPartitionNames(), ids, theRequestPartitionId.getPartitionDate());
163                }
164
165                return theRequestPartitionId;
166        }
167}