001package ca.uhn.fhir.jpa.api.svc;
002
003/*-
004 * #%L
005 * HAPI FHIR Storage api
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.context.FhirContext;
024import ca.uhn.fhir.interceptor.model.RequestPartitionId;
025import ca.uhn.fhir.jpa.model.cross.IResourceLookup;
026import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
027import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
028import org.hl7.fhir.instance.model.api.IIdType;
029
030import javax.annotation.Nonnull;
031import javax.annotation.Nullable;
032import java.util.Date;
033import java.util.List;
034import java.util.Map;
035import java.util.Optional;
036import java.util.Set;
037
038/**
039 * This interface is used to translate between {@link ResourcePersistentId}
040 * and actual resource IDs.
041 */
042public interface IIdHelperService {
043
044        /**
045         * Given a collection of resource IDs (resource type + id), resolves the internal persistent IDs.
046         * <p>
047         * This implementation will always try to use a cache for performance, meaning that it can resolve resources that
048         * are deleted (but note that forced IDs can't change, so the cache can't return incorrect results)
049         *
050         * @param theOnlyForcedIds If <code>true</code>, resources which are not existing forced IDs will not be resolved
051         */
052        @Nonnull
053        List<ResourcePersistentId> resolveResourcePersistentIdsWithCache(@Nonnull RequestPartitionId theRequestPartitionId, List<IIdType> theIds, boolean theOnlyForcedIds);
054
055        /**
056         * Given a resource type and ID, determines the internal persistent ID for the resource.
057         *
058         * @throws ResourceNotFoundException If the ID can not be found
059         */
060        @Nonnull
061        ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId);
062
063        /**
064         * Given a resource type and ID, determines the internal persistent ID for a resource.
065         * Optionally filters out deleted resources.
066         *
067         * @throws ResourceNotFoundException If the ID can not be found
068         */
069        @Nonnull
070        ResourcePersistentId resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theId, boolean theExcludeDeleted);
071
072        /**
073         * Returns a mapping of Id -> ResourcePersistentId.
074         * If any resource is not found, it will throw ResourceNotFound exception
075         * (and no map will be returned)
076         */
077        @Nonnull
078        Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, List<String> theIds);
079
080        /**
081         * Returns a mapping of Id -> ResourcePersistentId.
082         * If any resource is not found, it will throw ResourceNotFound exception (and no map will be returned)
083         * Optionally filters out deleted resources.
084         */
085        @Nonnull
086        Map<String, ResourcePersistentId> resolveResourcePersistentIds(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, List<String> theIds, boolean theExcludeDeleted);
087
088        /**
089         * Given a persistent ID, returns the associated resource ID
090         */
091        @Nonnull
092        IIdType translatePidIdToForcedId(FhirContext theCtx, String theResourceType, ResourcePersistentId theId);
093
094        /**
095         * Given a forced ID, convert it to it's Long value. Since you are allowed to use string IDs for resources, we need to
096         * convert those to the underlying Long values that are stored, for lookup and comparison purposes.
097         *
098         * @throws ResourceNotFoundException If the ID can not be found
099         */
100        @Nonnull
101        IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId) throws ResourceNotFoundException;
102
103        /**
104         * Given a forced ID, convert it to it's Long value. Since you are allowed to use string IDs for resources, we need to
105         * convert those to the underlying Long values that are stored, for lookup and comparison purposes.
106         * Optionally filters out deleted resources.
107         *
108         * @throws ResourceNotFoundException If the ID can not be found
109         */
110        @Nonnull
111        IResourceLookup resolveResourceIdentity(@Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, String theResourceId, boolean theExcludeDeleted) throws ResourceNotFoundException;
112
113        /**
114         * Returns true if the given resource ID should be stored in a forced ID. Under default config
115         * (meaning client ID strategy is {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ALPHANUMERIC})
116         * this will return true if the ID has any non-digit characters.
117         * <p>
118         * In {@link ca.uhn.fhir.jpa.api.config.DaoConfig.ClientIdStrategyEnum#ANY} mode it will always return true.
119         */
120        boolean idRequiresForcedId(String theId);
121
122        /**
123         * Given a collection of resource IDs (resource type + id), resolves the internal persistent IDs.
124         * <p>
125         * This implementation will always try to use a cache for performance, meaning that it can resolve resources that
126         * are deleted (but note that forced IDs can't change, so the cache can't return incorrect results)
127         */
128        @Nonnull
129        List<ResourcePersistentId> resolveResourcePersistentIdsWithCache(RequestPartitionId theRequestPartitionId, List<IIdType> theIds);
130
131        Optional<String> translatePidIdToForcedIdWithCache(ResourcePersistentId theResourcePersistentId);
132
133        Map<Long, Optional<String>> translatePidsToForcedIds(Set<Long> thePids);
134
135        /**
136         * Pre-cache a PID-to-Resource-ID mapping for later retrieval by {@link #translatePidsToForcedIds(Set)} and related methods
137         */
138        void addResolvedPidToForcedId(ResourcePersistentId theResourcePersistentId, @Nonnull RequestPartitionId theRequestPartitionId, String theResourceType, @Nullable String theForcedId, @Nullable Date theDeletedAt);
139
140}