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