001/*-
002 * #%L
003 * HAPI FHIR - Master Data Management
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.mdm.api;
021
022import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
023import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
024import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
025import ca.uhn.fhir.mdm.api.params.GenerateMdmMetricsParameters;
026import ca.uhn.fhir.mdm.model.MdmResourceMetrics;
027import ca.uhn.fhir.mdm.util.MdmSearchParamBuildingUtils;
028import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
029import ca.uhn.fhir.rest.api.server.IBundleProvider;
030import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
031
032public abstract class BaseMdmMetricSvc implements IMdmMetricSvc {
033
034        /**
035         * Count of numbered buckets.
036         * There will also be a NULL bucket, so there will be a total
037         * of BUCKETS + 1 buckets.
038         */
039        public static final int BUCKETS = 100;
040
041        /**
042         * The NULL label
043         */
044        public static final String NULL_VALUE = "NULL";
045
046        /**
047         * The label for the first bucket
048         */
049        public static final String FIRST_BUCKET = "x_<_%.2f";
050
051        /**
052         * The label for the nth bucket (2... buckets)
053         */
054        public static final String NTH_BUCKET = "%.2f_<_x_<=_%.2f";
055
056        protected final DaoRegistry myDaoRegistry;
057
058        public BaseMdmMetricSvc(DaoRegistry theDaoRegistry) {
059                myDaoRegistry = theDaoRegistry;
060        }
061
062        protected double getBucket(int theBucketId) {
063                return (double) Math.round((float) (100 * theBucketId) / BUCKETS) / 100;
064        }
065
066        protected MdmResourceMetrics generateResourceMetrics(GenerateMdmMetricsParameters theParameters) {
067                String resourceType = theParameters.getResourceType();
068                @SuppressWarnings("rawtypes")
069                IFhirResourceDao dao = myDaoRegistry.getResourceDao(resourceType);
070
071                // TODO
072                /*
073                 * We are using 3 different queries to count:
074                 * * all resources
075                 * * all golden resources
076                 * * all blocked resources.
077                 *
078                 * This is inefficient and if we want, we can speed it up with
079                 * a custom query in the future.
080                 */
081                IBundleProvider outcome = null;
082                SearchParameterMap map = null;
083
084                MdmResourceMetrics metrics = new MdmResourceMetrics();
085                metrics.setResourceType(resourceType);
086
087                // find golden resources
088                map = MdmSearchParamBuildingUtils.buildBasicGoldenResourceSearchParameterMap(resourceType);
089                setCountOnly(map);
090                outcome = dao.search(map, new SystemRequestDetails());
091                metrics.setGoldenResourcesCount(outcome.size());
092
093                // find blocked resources
094                map = MdmSearchParamBuildingUtils.buildSearchParameterForBlockedResourceCount(resourceType);
095                setCountOnly(map);
096                outcome = dao.search(map, new SystemRequestDetails());
097                metrics.setExcludedResources(outcome.size());
098
099                // find all resources
100                map = new SearchParameterMap();
101                setCountOnly(map);
102                outcome = dao.search(map, new SystemRequestDetails());
103                metrics.setSourceResourcesCount(outcome.size() - metrics.getGoldenResourcesCount());
104
105                return metrics;
106        }
107
108        private void setCountOnly(SearchParameterMap theMap) {
109                theMap.setCount(0);
110                theMap.setLoadSynchronous(true);
111                theMap.setSearchTotalMode(SearchTotalModeEnum.ACCURATE);
112        }
113}