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        IPartitionLookupSvc myPartitionConfigSvc;
038
039        @Override
040        public RequestPartitionId validateAndNormalizePartitionIds(RequestPartitionId theRequestPartitionId) {
041                List<String> names = null;
042                List<Integer> partitionIds = null;
043                for (int i = 0; i < theRequestPartitionId.getPartitionIds().size(); i++) {
044
045                        PartitionEntity partition;
046                        Integer id = theRequestPartitionId.getPartitionIds().get(i);
047                        if (id == null) {
048                                partition = null;
049                                if (myPartitionSettings.getDefaultPartitionId() != null) {
050                                        if (partitionIds == null) {
051                                                partitionIds = new ArrayList<>(theRequestPartitionId.getPartitionIds());
052                                        }
053                                        partitionIds.set(i, myPartitionSettings.getDefaultPartitionId());
054                                }
055                        } else {
056                                try {
057                                        partition = myPartitionConfigSvc.getPartitionById(id);
058                                } catch (IllegalArgumentException e) {
059                                        String msg = myFhirContext
060                                                        .getLocalizer()
061                                                        .getMessage(
062                                                                        BaseRequestPartitionHelperSvc.class,
063                                                                        "unknownPartitionId",
064                                                                        theRequestPartitionId.getPartitionIds().get(i));
065                                        throw new ResourceNotFoundException(Msg.code(1316) + msg);
066                                }
067                        }
068
069                        if (theRequestPartitionId.hasPartitionNames()) {
070                                if (partition == null) {
071                                        Validate.isTrue(
072                                                        theRequestPartitionId.getPartitionIds().get(i) == null,
073                                                        "Partition %s must not have an ID",
074                                                        JpaConstants.DEFAULT_PARTITION_NAME);
075                                } else {
076                                        Validate.isTrue(
077                                                        Objects.equals(
078                                                                        theRequestPartitionId.getPartitionNames().get(i), partition.getName()),
079                                                        "Partition name %s does not match ID %s",
080                                                        theRequestPartitionId.getPartitionNames().get(i),
081                                                        theRequestPartitionId.getPartitionIds().get(i));
082                                }
083                        } else {
084                                if (names == null) {
085                                        names = new ArrayList<>();
086                                }
087                                if (partition != null) {
088                                        names.add(partition.getName());
089                                } else {
090                                        names.add(null);
091                                }
092                        }
093                }
094
095                if (names != null) {
096                        List<Integer> partitionIdsToUse = theRequestPartitionId.getPartitionIds();
097                        if (partitionIds != null) {
098                                partitionIdsToUse = partitionIds;
099                        }
100                        return RequestPartitionId.forPartitionIdsAndNames(
101                                        names, partitionIdsToUse, theRequestPartitionId.getPartitionDate());
102                }
103
104                return theRequestPartitionId;
105        }
106
107        @Override
108        public RequestPartitionId validateAndNormalizePartitionNames(RequestPartitionId theRequestPartitionId) {
109                List<Integer> ids = null;
110                for (int i = 0; i < theRequestPartitionId.getPartitionNames().size(); i++) {
111
112                        PartitionEntity partition;
113                        try {
114                                partition = myPartitionConfigSvc.getPartitionByName(
115                                                theRequestPartitionId.getPartitionNames().get(i));
116                        } catch (IllegalArgumentException e) {
117                                String msg = myFhirContext
118                                                .getLocalizer()
119                                                .getMessage(
120                                                                BaseRequestPartitionHelperSvc.class,
121                                                                "unknownPartitionName",
122                                                                theRequestPartitionId.getPartitionNames().get(i));
123                                throw new ResourceNotFoundException(Msg.code(1317) + msg);
124                        }
125
126                        if (theRequestPartitionId.hasPartitionIds()) {
127                                Integer partitionId = theRequestPartitionId.getPartitionIds().get(i);
128                                if (partition == null) {
129                                        Validate.isTrue(
130                                                        partitionId == null || partitionId.equals(myPartitionSettings.getDefaultPartitionId()),
131                                                        "Partition %s must not have an ID",
132                                                        JpaConstants.DEFAULT_PARTITION_NAME);
133                                } else {
134                                        Validate.isTrue(
135                                                        Objects.equals(partitionId, partition.getId()),
136                                                        "Partition ID %s does not match name %s",
137                                                        partitionId,
138                                                        theRequestPartitionId.getPartitionNames().get(i));
139                                }
140                        } else {
141                                if (ids == null) {
142                                        ids = new ArrayList<>();
143                                }
144                                if (partition != null) {
145                                        ids.add(partition.getId());
146                                } else {
147                                        ids.add(myPartitionSettings.getDefaultPartitionId());
148                                }
149                        }
150                }
151
152                if (ids != null) {
153                        return RequestPartitionId.forPartitionIdsAndNames(
154                                        theRequestPartitionId.getPartitionNames(), ids, theRequestPartitionId.getPartitionDate());
155                }
156
157                return theRequestPartitionId;
158        }
159}