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