Move PAP database provider to spring boot default
[policy/pap.git] / main / src / main / java / org / onap / policy / pap / main / service / PdpStatisticsService.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2022 Bell Canada. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pap.main.service;
22
23 import java.time.Instant;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.concurrent.atomic.AtomicLong;
30 import java.util.stream.Collectors;
31 import javax.ws.rs.core.Response;
32 import lombok.NonNull;
33 import lombok.RequiredArgsConstructor;
34 import org.onap.policy.common.parameters.BeanValidationResult;
35 import org.onap.policy.common.utils.services.Registry;
36 import org.onap.policy.models.base.PfGeneratedIdKey;
37 import org.onap.policy.models.base.PfKey;
38 import org.onap.policy.models.base.PfModelRuntimeException;
39 import org.onap.policy.models.pdp.concepts.PdpStatistics;
40 import org.onap.policy.models.pdp.persistence.concepts.JpaPdpStatistics;
41 import org.onap.policy.pap.main.PapConstants;
42 import org.onap.policy.pap.main.repository.PdpStatisticsRepository;
43 import org.onap.policy.pap.main.rest.PapStatisticsManager;
44 import org.onap.policy.pap.main.rest.StatisticsReport;
45 import org.onap.policy.pap.main.startstop.PapActivator;
46 import org.springframework.data.domain.PageRequest;
47 import org.springframework.data.domain.Pageable;
48 import org.springframework.data.domain.Sort;
49 import org.springframework.stereotype.Service;
50 import org.springframework.transaction.annotation.Transactional;
51
52 @Service
53 @Transactional
54 @RequiredArgsConstructor
55 public class PdpStatisticsService {
56
57     private static final String TIMESTAMP = "timeStamp";
58     private static final int DEFAULT_RECORD_COUNT = 10;
59     private static final int MAX_RECORD_COUNT = 100;
60
61     private AtomicLong generatedId = new AtomicLong();
62
63     private final PdpStatisticsRepository pdpStatisticsRepository;
64
65     /**
66      * Returns the current statistics of pap component.
67      *
68      * @return Report containing statistics of pap component
69      */
70     public StatisticsReport fetchCurrentStatistics() {
71         final var report = new StatisticsReport();
72         report.setCode(Registry.get(PapConstants.REG_PAP_ACTIVATOR, PapActivator.class).isAlive() ? 200 : 500);
73
74         PapStatisticsManager mgr = Registry.get(PapConstants.REG_STATISTICS_MANAGER, PapStatisticsManager.class);
75         report.setTotalPdpCount(mgr.getTotalPdpCount());
76         report.setTotalPdpGroupCount(mgr.getTotalPdpGroupCount());
77         report.setTotalPolicyDownloadCount(mgr.getTotalPolicyDownloadCount());
78         report.setPolicyDownloadSuccessCount(mgr.getPolicyDownloadSuccessCount());
79         report.setPolicyDownloadFailureCount(mgr.getPolicyDownloadFailureCount());
80         report.setTotalPolicyDeployCount(mgr.getTotalPolicyDeployCount());
81         report.setPolicyDeploySuccessCount(mgr.getPolicyDeploySuccessCount());
82         report.setPolicyDeployFailureCount(mgr.getPolicyDeployFailureCount());
83
84         return report;
85     }
86
87     /**
88      * Creates PDP statistics.
89      *
90      * @param pdpStatisticsList a specification of the PDP statistics to create
91      * @return the PDP statistics created
92      */
93     public List<PdpStatistics> createPdpStatistics(@NonNull final List<PdpStatistics> pdpStatisticsList) {
94         for (PdpStatistics pdpStatistics : pdpStatisticsList) {
95             var jpaPdpStatistics = new JpaPdpStatistics();
96             jpaPdpStatistics.fromAuthorative(pdpStatistics);
97             BeanValidationResult validationResult = jpaPdpStatistics.validate("pdp statistics");
98             if (!validationResult.isValid()) {
99                 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
100             }
101             //TODO: Fix this as part of POLICY-3897
102             jpaPdpStatistics.getKey().setGeneratedId(generatedId.incrementAndGet());
103             pdpStatisticsRepository.saveAndFlush(jpaPdpStatistics);
104             pdpStatistics.setGeneratedId(jpaPdpStatistics.getKey().getGeneratedId());
105         }
106
107         // Return the created PDP statistics
108         List<PdpStatistics> pdpStatistics = new ArrayList<>(pdpStatisticsList.size());
109
110         for (PdpStatistics pdpStatisticsItem : pdpStatisticsList) {
111             var jpaPdpStatistics =
112                 pdpStatisticsRepository.getById(new PfGeneratedIdKey(pdpStatisticsItem.getPdpInstanceId(),
113                     PfKey.NULL_KEY_VERSION, pdpStatisticsItem.getGeneratedId()));
114             pdpStatistics.add(jpaPdpStatistics.toAuthorative());
115         }
116         return pdpStatistics;
117     }
118
119     /**
120      * Fetch PdpStatistics from db.
121      *
122      * @param pdpGroup the name of the group
123      * @param pdpSubGroup the name of the subgroup
124      * @param pdp the pdp instance id
125      * @param recordCount the number of records to return
126      * @param startTime start time of the records to be returned
127      * @param endTime end time of the records to be returned
128      * @return pdpStatistics grouped by pdpGroup
129      */
130     public Map<String, Map<String, List<PdpStatistics>>> fetchDatabaseStatistics(@NonNull String pdpGroup,
131         @NonNull String pdpSubGroup, @NonNull String pdp, int recordCount, Instant startTime, Instant endTime) {
132
133         Pageable recordSize = getRecordSize(recordCount);
134         if (startTime != null && endTime != null) {
135             return generatePdpStatistics(asPdpStatisticsList(pdpStatisticsRepository
136                 .findByPdpGroupNameAndPdpSubGroupNameAndKeyNameAndTimeStampBetween(pdpGroup, pdpSubGroup, pdp,
137                     convertInstantToDate(startTime), convertInstantToDate(endTime), recordSize)));
138         } else if (startTime == null && endTime == null) {
139             return generatePdpStatistics(
140                 asPdpStatisticsList(pdpStatisticsRepository.findByPdpGroupNameAndPdpSubGroupNameAndKeyName(pdpGroup,
141                     pdpSubGroup, pdp, recordSize)));
142         } else if (startTime != null) {
143             return generatePdpStatistics(asPdpStatisticsList(
144                 pdpStatisticsRepository.findByPdpGroupNameAndPdpSubGroupNameAndKeyNameAndTimeStampGreaterThanEqual(
145                     pdpGroup, pdpSubGroup, pdp, convertInstantToDate(startTime), recordSize)));
146         } else {
147             return generatePdpStatistics(asPdpStatisticsList(
148                 pdpStatisticsRepository.findByPdpGroupNameAndPdpSubGroupNameAndKeyNameAndTimeStampLessThanEqual(
149                     pdpGroup, pdpSubGroup, pdp, convertInstantToDate(endTime), recordSize)));
150         }
151     }
152
153     /**
154      * Fetch PdpStatistics from db.
155      *
156      * @param pdpGroup the name of the group
157      * @param pdpSubGroup the name of the subgroup
158      * @param recordCount the number of records to return
159      * @param startTime start time of the records to be returned
160      * @param endTime end time of the records to be returned
161      * @return pdpStatistics grouped by pdpGroup
162      */
163     public Map<String, Map<String, List<PdpStatistics>>> fetchDatabaseStatistics(@NonNull String pdpGroup,
164         @NonNull String pdpSubGroup, int recordCount, Instant startTime, Instant endTime) {
165
166         Pageable recordSize = getRecordSize(recordCount);
167         if (startTime != null && endTime != null) {
168             return generatePdpStatistics(asPdpStatisticsList(
169                 pdpStatisticsRepository.findByPdpGroupNameAndPdpSubGroupNameAndTimeStampBetween(pdpGroup, pdpSubGroup,
170                     convertInstantToDate(startTime), convertInstantToDate(endTime), recordSize)));
171         } else if (startTime == null && endTime == null) {
172             return generatePdpStatistics(asPdpStatisticsList(pdpStatisticsRepository
173                 .findByPdpGroupNameAndPdpSubGroupName(pdpGroup, pdpSubGroup, recordSize)));
174         } else if (startTime != null) {
175             return generatePdpStatistics(asPdpStatisticsList(
176                 pdpStatisticsRepository.findByPdpGroupNameAndPdpSubGroupNameAndTimeStampGreaterThanEqual(pdpGroup,
177                     pdpSubGroup, convertInstantToDate(startTime), recordSize)));
178         } else {
179             return generatePdpStatistics(asPdpStatisticsList(
180                 pdpStatisticsRepository.findByPdpGroupNameAndPdpSubGroupNameAndTimeStampLessThanEqual(pdpGroup,
181                     pdpSubGroup, convertInstantToDate(endTime), recordSize)));
182         }
183     }
184
185     /**
186      * Fetch PdpStatistics from db.
187      *
188      * @param pdpGroup the name of the group
189      * @param recordCount the number of records to return
190      * @param startTime start time of the records to be returned
191      * @param endTime end time of the records to be returned
192      * @return pdpStatistics grouped by pdpGroup
193      */
194     public Map<String, Map<String, List<PdpStatistics>>> fetchDatabaseStatistics(@NonNull String pdpGroup,
195         int recordCount, Instant startTime, Instant endTime) {
196
197         Pageable recordSize = getRecordSize(recordCount);
198         if (startTime != null && endTime != null) {
199             return generatePdpStatistics(
200                 asPdpStatisticsList(pdpStatisticsRepository.findByPdpGroupNameAndTimeStampBetween(pdpGroup,
201                     convertInstantToDate(startTime), convertInstantToDate(endTime), recordSize)));
202         } else if (startTime == null && endTime == null) {
203             return generatePdpStatistics(
204                 asPdpStatisticsList(pdpStatisticsRepository.findByPdpGroupName(pdpGroup, recordSize)));
205         } else if (startTime != null) {
206             return generatePdpStatistics(
207                 asPdpStatisticsList(pdpStatisticsRepository.findByPdpGroupNameAndTimeStampGreaterThanEqual(pdpGroup,
208                     convertInstantToDate(startTime), recordSize)));
209         } else {
210             return generatePdpStatistics(
211                 asPdpStatisticsList(pdpStatisticsRepository.findByPdpGroupNameAndTimeStampLessThanEqual(pdpGroup,
212                     convertInstantToDate(endTime), recordSize)));
213         }
214     }
215
216     /**
217      * Fetch PdpStatistics from db.
218      *
219      * @param recordCount the number of records to return
220      * @param startTime start time of the records to be returned
221      * @param endTime end time of the records to be returned
222      * @return pdpStatistics grouped by pdpGroup
223      */
224     public Map<String, Map<String, List<PdpStatistics>>> fetchDatabaseStatistics(int recordCount, Instant startTime,
225         Instant endTime) {
226
227         Pageable recordSize = getRecordSize(recordCount);
228         if (startTime != null && endTime != null) {
229             return generatePdpStatistics(asPdpStatisticsList(pdpStatisticsRepository.findByTimeStampBetween(
230                 convertInstantToDate(startTime), convertInstantToDate(endTime), recordSize)));
231         } else if (startTime == null && endTime == null) {
232             return generatePdpStatistics(
233                 asPdpStatisticsList(pdpStatisticsRepository.findAll(recordSize).toList()));
234         } else if (startTime != null) {
235             return generatePdpStatistics(asPdpStatisticsList(pdpStatisticsRepository
236                 .findByTimeStampGreaterThanEqual(convertInstantToDate(startTime), recordSize)));
237         } else {
238             return generatePdpStatistics(asPdpStatisticsList(pdpStatisticsRepository
239                 .findByTimeStampLessThanEqual(convertInstantToDate(endTime), recordSize)));
240         }
241     }
242
243     private Pageable getRecordSize(int recordCount) {
244         if (recordCount < 1) {
245             recordCount = DEFAULT_RECORD_COUNT;
246         } else if (recordCount > MAX_RECORD_COUNT) {
247             recordCount = MAX_RECORD_COUNT;
248         }
249         return PageRequest.of(0, recordCount, Sort.by(TIMESTAMP).descending());
250     }
251
252     /**
253      * generate the statistics of pap component by group/subgroup.
254      *
255      */
256     private Map<String, Map<String, List<PdpStatistics>>> generatePdpStatistics(List<PdpStatistics> pdpStatisticsList) {
257         Map<String, Map<String, List<PdpStatistics>>> groupMap = new HashMap<>();
258         if (pdpStatisticsList != null) {
259             pdpStatisticsList.stream().forEach(s -> {
260                 String curGroup = s.getPdpGroupName();
261                 String curSubGroup = s.getPdpSubGroupName();
262                 groupMap.computeIfAbsent(curGroup, curGroupMap -> new HashMap<>())
263                     .computeIfAbsent(curSubGroup, curSubGroupList -> new ArrayList<>()).add(s);
264             });
265         }
266         return groupMap;
267     }
268
269     /**
270      * Convert JPA PDP statistics list to an PDP statistics list.
271      *
272      * @param jpaPdpStatisticsList the list to convert
273      * @return the PDP statistics list
274      */
275     private List<PdpStatistics> asPdpStatisticsList(List<JpaPdpStatistics> jpaPdpStatisticsList) {
276         return jpaPdpStatisticsList.stream().map(JpaPdpStatistics::toAuthorative).collect(Collectors.toList());
277     }
278
279     private Date convertInstantToDate(Instant instant) {
280         return (instant == null ? null : Date.from(instant));
281     }
282 }