Merge "Fix sonars in policy models"
[policy/models.git] / models-pdp / src / main / java / org / onap / policy / models / pdp / persistence / provider / PdpProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
4  *  Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.models.pdp.persistence.provider;
23
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.stream.Collectors;
30 import javax.ws.rs.core.Response;
31 import lombok.NonNull;
32 import org.onap.policy.common.parameters.BeanValidationResult;
33 import org.onap.policy.models.base.PfConceptKey;
34 import org.onap.policy.models.base.PfKey;
35 import org.onap.policy.models.base.PfModelException;
36 import org.onap.policy.models.base.PfModelRuntimeException;
37 import org.onap.policy.models.base.PfReferenceKey;
38 import org.onap.policy.models.dao.PfDao;
39 import org.onap.policy.models.pdp.concepts.Pdp;
40 import org.onap.policy.models.pdp.concepts.PdpGroup;
41 import org.onap.policy.models.pdp.concepts.PdpGroupFilter;
42 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus;
43 import org.onap.policy.models.pdp.concepts.PdpStatistics;
44 import org.onap.policy.models.pdp.concepts.PdpSubGroup;
45 import org.onap.policy.models.pdp.persistence.concepts.JpaPdp;
46 import org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup;
47 import org.onap.policy.models.pdp.persistence.concepts.JpaPdpPolicyStatus;
48 import org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifierOptVersion;
50
51 /**
52  * This class provides the provision of information on PAP concepts in the database to callers.
53  *
54  * @author Liam Fallon (liam.fallon@est.tech)
55  */
56 public class PdpProvider {
57     private static final Object statusLock = new Object();
58
59     /**
60      * Get PDP groups.
61      *
62      * @param dao the DAO to use to access the database
63      * @param name the name of the PDP group to get, null to get all PDP groups
64      * @return the PDP groups found
65      * @throws PfModelException on errors getting PDP groups
66      */
67     public List<PdpGroup> getPdpGroups(@NonNull final PfDao dao, final String name) throws PfModelException {
68
69         return asPdpGroupList(dao.getFiltered(JpaPdpGroup.class, name, PfKey.NULL_KEY_VERSION));
70     }
71
72     /**
73      * Get filtered PDP groups.
74      *
75      * @param dao the DAO to use to access the database
76      * @param filter the filter for the PDP groups to get
77      * @return the PDP groups found
78      * @throws PfModelException on errors getting policies
79      */
80     public List<PdpGroup> getFilteredPdpGroups(@NonNull final PfDao dao, @NonNull final PdpGroupFilter filter) {
81
82         return filter.filter(
83                         asPdpGroupList(dao.getFiltered(JpaPdpGroup.class, filter.getName(), PfKey.NULL_KEY_VERSION)));
84     }
85
86     /**
87      * Creates PDP groups.
88      *
89      * @param dao the DAO to use to access the database
90      * @param pdpGroups a specification of the PDP groups to create
91      * @return the PDP groups created
92      * @throws PfModelException on errors creating PDP groups
93      */
94     public List<PdpGroup> createPdpGroups(@NonNull final PfDao dao, @NonNull final List<PdpGroup> pdpGroups)
95             throws PfModelException {
96
97         for (PdpGroup pdpGroup : pdpGroups) {
98             var jpaPdpGroup = new JpaPdpGroup();
99             jpaPdpGroup.fromAuthorative(pdpGroup);
100
101             BeanValidationResult validationResult = jpaPdpGroup.validate("PDP group");
102             if (!validationResult.isValid()) {
103                 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
104             }
105
106             dao.create(jpaPdpGroup);
107         }
108
109         // Return the created PDP groups
110         List<PdpGroup> returnPdpGroups = new ArrayList<>();
111
112         for (PdpGroup pdpGroup : pdpGroups) {
113             var jpaPdpGroup = dao.get(JpaPdpGroup.class, new PfConceptKey(pdpGroup.getName(), PfKey.NULL_KEY_VERSION));
114             returnPdpGroups.add(jpaPdpGroup.toAuthorative());
115         }
116
117         return returnPdpGroups;
118     }
119
120     /**
121      * Updates PDP groups.
122      *
123      * @param dao the DAO to use to access the database
124      * @param pdpGroups a specification of the PDP groups to update
125      * @return the PDP groups updated
126      * @throws PfModelException on errors updating PDP groups
127      */
128     public List<PdpGroup> updatePdpGroups(@NonNull final PfDao dao, @NonNull final List<PdpGroup> pdpGroups)
129             throws PfModelException {
130
131         for (PdpGroup pdpGroup : pdpGroups) {
132             var jpaPdpGroup = new JpaPdpGroup();
133             jpaPdpGroup.fromAuthorative(pdpGroup);
134
135             BeanValidationResult validationResult = jpaPdpGroup.validate("PDP group");
136             if (!validationResult.isValid()) {
137                 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
138             }
139
140             dao.update(jpaPdpGroup);
141         }
142
143         // Return the created PDP groups
144         List<PdpGroup> returnPdpGroups = new ArrayList<>();
145
146         for (PdpGroup pdpGroup : pdpGroups) {
147             var jpaPdpGroup =
148                     dao.get(JpaPdpGroup.class, new PfConceptKey(pdpGroup.getName(), PfKey.NULL_KEY_VERSION));
149             returnPdpGroups.add(jpaPdpGroup.toAuthorative());
150         }
151
152         return returnPdpGroups;
153     }
154
155     /**
156      * Update a PDP subgroup.
157      *
158      * @param dao the DAO to use to access the database
159      * @param pdpGroupName the name of the PDP group of the PDP subgroup
160      * @param pdpSubGroup the PDP subgroup to be updated
161      * @throws PfModelException on errors updating PDP subgroups
162      */
163     public void updatePdpSubGroup(@NonNull final PfDao dao, @NonNull final String pdpGroupName,
164             @NonNull final PdpSubGroup pdpSubGroup) throws PfModelException {
165
166         final var subGroupKey =
167                 new PfReferenceKey(pdpGroupName, PfKey.NULL_KEY_VERSION, pdpSubGroup.getPdpType());
168         final var jpaPdpSubgroup = new JpaPdpSubGroup(subGroupKey);
169         jpaPdpSubgroup.fromAuthorative(pdpSubGroup);
170
171         BeanValidationResult validationResult = jpaPdpSubgroup.validate("PDP sub group");
172         if (!validationResult.isValid()) {
173             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
174         }
175
176         dao.update(jpaPdpSubgroup);
177     }
178
179     /**
180      * Update a PDP.
181      *
182      * @param dao the DAO to use to access the database
183      * @param pdpGroupName the name of the PDP group of the PDP subgroup
184      * @param pdpSubGroup the PDP subgroup to be updated
185      * @param pdp the PDP to be updated
186      * @throws PfModelException on errors updating PDP subgroups
187      */
188     public void updatePdp(@NonNull final PfDao dao, @NonNull final String pdpGroupName,
189             @NonNull final String pdpSubGroup, @NonNull final Pdp pdp) {
190
191         final var pdpKey =
192                 new PfReferenceKey(pdpGroupName, PfKey.NULL_KEY_VERSION, pdpSubGroup, pdp.getInstanceId());
193         final var jpaPdp = new JpaPdp(pdpKey);
194         jpaPdp.fromAuthorative(pdp);
195
196         BeanValidationResult validationResult = jpaPdp.validate("PDP");
197         if (!validationResult.isValid()) {
198             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
199         }
200
201         dao.update(jpaPdp);
202     }
203
204     /**
205      * Delete a PDP group.
206      *
207      * @param dao the DAO to use to access the database
208      * @param name the name of the policy to get, null to get all PDP groups
209      * @return the PDP group deleted
210      * @throws PfModelException on errors deleting PDP groups
211      */
212     public PdpGroup deletePdpGroup(@NonNull final PfDao dao, @NonNull final String name) {
213
214         var pdpGroupKey = new PfConceptKey(name, PfKey.NULL_KEY_VERSION);
215
216         JpaPdpGroup jpaDeletePdpGroup = dao.get(JpaPdpGroup.class, pdpGroupKey);
217
218         if (jpaDeletePdpGroup == null) {
219             String errorMessage =
220                     "delete of PDP group \"" + pdpGroupKey.getId() + "\" failed, PDP group does not exist";
221             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
222         }
223
224         dao.delete(jpaDeletePdpGroup);
225
226         return jpaDeletePdpGroup.toAuthorative();
227     }
228
229     /**
230      * Get PDP statistics.
231      *
232      * @param dao the DAO to use to access the database
233      * @param name the name of the PDP group to get statistics for, null to get all PDP groups
234      * @return the statistics found
235      * @throws PfModelException on errors getting statistics
236      */
237     public List<PdpStatistics> getPdpStatistics(@NonNull final PfDao dao, final String name) throws PfModelException {
238         return new ArrayList<>();
239     }
240
241     /**
242      * Update PDP statistics for a PDP.
243      *
244      * @param dao the DAO to use to access the database
245      * @param pdpGroupName the name of the PDP group containing the PDP that the statistics are for
246      * @param pdpType the PDP type of the subgroup containing the PDP that the statistics are for
247      * @param pdpInstanceId the instance ID of the PDP to update statistics for
248      * @param pdpStatistics the statistics to update
249      * @throws PfModelException on errors updating statistics
250      */
251     public void updatePdpStatistics(@NonNull final PfDao dao, @NonNull final String pdpGroupName,
252             @NonNull final String pdpType, @NonNull final String pdpInstanceId,
253             @NonNull final PdpStatistics pdpStatistics) throws PfModelException {
254         // Not implemented yet
255     }
256
257     /**
258      * Gets all policy deployments.
259      *
260      * @param dao the DAO to use to access the database
261      * @return the deployments found
262      * @throws PfModelException on errors getting PDP groups
263      */
264     public List<PdpPolicyStatus> getAllPolicyStatus(@NonNull final PfDao dao)
265                     throws PfModelException {
266
267         return dao.getAll(JpaPdpPolicyStatus.class).stream().map(JpaPdpPolicyStatus::toAuthorative)
268                         .collect(Collectors.toList());
269     }
270
271     /**
272      * Gets all deployments for a policy.
273      *
274      * @param dao the DAO to use to access the database
275      * @return the deployments found
276      * @throws PfModelException on errors getting PDP groups
277      */
278     public List<PdpPolicyStatus> getAllPolicyStatus(@NonNull final PfDao dao,
279                     @NonNull ToscaConceptIdentifierOptVersion policy) throws PfModelException {
280
281         if (policy.getVersion() != null) {
282             return dao.getAll(JpaPdpPolicyStatus.class, new PfConceptKey(policy.getName(), policy.getVersion()))
283                             .stream().map(JpaPdpPolicyStatus::toAuthorative).collect(Collectors.toList());
284
285         } else {
286             return dao.getAllVersionsByParent(JpaPdpPolicyStatus.class, policy.getName()).stream()
287                             .map(JpaPdpPolicyStatus::toAuthorative).collect(Collectors.toList());
288         }
289     }
290
291     /**
292      * Gets the policy deployments for a PDP group.
293      *
294      * @param dao the DAO to use to access the database
295      * @param groupName the name of the PDP group of interest, null to get results for all
296      *        PDP groups
297      * @return the deployments found
298      * @throws PfModelException on errors getting PDP groups
299      */
300     public List<PdpPolicyStatus> getGroupPolicyStatus(@NonNull final PfDao dao, @NonNull final String groupName)
301                     throws PfModelException {
302
303         Map<String, Object> filter = Map.of("pdpGroup", groupName);
304
305         return dao.getFiltered(JpaPdpPolicyStatus.class, null, null, null, null, filter, null, 0).stream()
306                         .map(JpaPdpPolicyStatus::toAuthorative).collect(Collectors.toList());
307     }
308
309     /**
310      * Creates, updates, and deletes collections of policy status.
311      *
312      * @param dao the DAO to use to access the database
313      * @param createObjs the objects to create
314      * @param updateObjs the objects to update
315      * @param deleteObjs the objects to delete
316      */
317     public void cudPolicyStatus(@NonNull final PfDao dao, Collection<PdpPolicyStatus> createObjs,
318                     Collection<PdpPolicyStatus> updateObjs, Collection<PdpPolicyStatus> deleteObjs) {
319
320         synchronized (statusLock) {
321             dao.deleteCollection(fromAuthorativeStatus(deleteObjs, "deletePdpPolicyStatusList"));
322             dao.createCollection(fromAuthorativeStatus(createObjs, "createPdpPolicyStatusList"));
323             dao.createCollection(fromAuthorativeStatus(updateObjs, "updatePdpPolicyStatusList"));
324         }
325     }
326
327     /**
328      * Converts a collection of authorative policy status to a collection of JPA policy
329      * status.  Validates the resulting list.
330      *
331      * @param objs authorative policy status to convert
332      * @param fieldName name of the field containing the collection
333      * @return a collection of JPA policy status
334      */
335     private Collection<JpaPdpPolicyStatus> fromAuthorativeStatus(Collection<PdpPolicyStatus> objs, String fieldName) {
336         if (objs == null) {
337             return Collections.emptyList();
338         }
339
340         List<JpaPdpPolicyStatus> jpas = objs.stream().map(JpaPdpPolicyStatus::new).collect(Collectors.toList());
341
342         // validate the objects
343         var result = new BeanValidationResult(fieldName, jpas);
344
345         var count = 0;
346         for (JpaPdpPolicyStatus jpa: jpas) {
347             result.addResult(jpa.validate(String.valueOf(count++)));
348         }
349
350         if (!result.isValid()) {
351             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, result.getResult());
352         }
353
354         return jpas;
355     }
356
357     /**
358      * Convert JPA PDP group list to an authorative PDP group list.
359      *
360      * @param foundPdpGroups the list to convert
361      * @return the authorative list
362      */
363     private List<PdpGroup> asPdpGroupList(List<JpaPdpGroup> jpaPdpGroupList) {
364         List<PdpGroup> pdpGroupList = new ArrayList<>(jpaPdpGroupList.size());
365
366         for (JpaPdpGroup jpaPdpGroup : jpaPdpGroupList) {
367             pdpGroupList.add(jpaPdpGroup.toAuthorative());
368         }
369
370         return pdpGroupList;
371     }
372 }