Implement validation and hierarchical get
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / authorative / provider / AuthorativeToscaProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019-2020 Nordix Foundation.
4  *  Modifications Copyright (C) 2019 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.tosca.authorative.provider;
23
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.LinkedHashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.TreeMap;
30
31 import javax.ws.rs.core.Response.Status;
32
33 import lombok.NonNull;
34
35 import org.onap.policy.models.base.PfConceptKey;
36 import org.onap.policy.models.base.PfModelException;
37 import org.onap.policy.models.base.PfModelRuntimeException;
38 import org.onap.policy.models.dao.PfDao;
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
40 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyFilter;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
43 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeFilter;
44 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
45 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
46 import org.onap.policy.models.tosca.simple.provider.SimpleToscaProvider;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 /**
51  * This class provides the provision of information on TOSCA concepts in the database to callers.
52  *
53  * @author Liam Fallon (liam.fallon@est.tech)
54  */
55 public class AuthorativeToscaProvider {
56     private static final Logger LOGGER = LoggerFactory.getLogger(AuthorativeToscaProvider.class);
57
58     /**
59      * Get policy types.
60      *
61      * @param dao the DAO to use to access the database
62      * @param name the name of the policy type to get.
63      * @param version the version of the policy type to get.
64      * @return the policy types found
65      * @throws PfModelException on errors getting policy types
66      */
67     public ToscaServiceTemplate getPolicyTypes(@NonNull final PfDao dao, final String name, final String version)
68             throws PfModelException {
69
70         LOGGER.debug("->getPolicyTypes: name={}, version={}", name, version);
71
72         JpaToscaServiceTemplate jpaServiceTemplate = new SimpleToscaProvider().getPolicyTypes(dao, name, version);
73
74         ToscaServiceTemplate serviceTemplate = jpaServiceTemplate.toAuthorative();
75
76         LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
77         return serviceTemplate;
78     }
79
80     /**
81      * Get policy types.
82      *
83      * @param dao the DAO to use to access the database
84      * @param name the name of the policy type to get, set to null to get all policy types
85      * @param version the version of the policy type to get, set to null to get all versions
86      * @return the policy types found
87      * @throws PfModelException on errors getting policy types
88      */
89     public List<ToscaPolicyType> getPolicyTypeList(@NonNull final PfDao dao, final String name, final String version)
90             throws PfModelException {
91
92         LOGGER.debug("->getPolicyTypeList: name={}, version={}", name, version);
93
94         List<ToscaPolicyType> policyTypeList;
95
96         try {
97             policyTypeList = new ArrayList<>(new SimpleToscaProvider().getPolicyTypes(dao, name, version)
98                     .toAuthorative().getPolicyTypes().values());
99         } catch (PfModelRuntimeException pfme) {
100             return handlePfModelRuntimeException(pfme);
101         }
102
103         LOGGER.debug("<-getPolicyTypeList: name={}, version={}, policyTypeList={}", name, version, policyTypeList);
104         return policyTypeList;
105     }
106
107     /**
108      * Get filtered policy types.
109      *
110      * @param dao the DAO to use to access the database
111      * @param filter the filter for the policy types to get
112      * @return the policy types found
113      * @throws PfModelException on errors getting policy types
114      */
115     public ToscaServiceTemplate getFilteredPolicyTypes(@NonNull final PfDao dao,
116             @NonNull final ToscaPolicyTypeFilter filter) throws PfModelException {
117
118         LOGGER.debug("->getFilteredPolicyTypes: filter={}", filter);
119
120         ToscaServiceTemplate serviceTemplate =
121                 new SimpleToscaProvider().getPolicyTypes(dao, null, null).toAuthorative();
122
123         List<ToscaPolicyType> filteredPolicyTypes = new ArrayList<>(serviceTemplate.getPolicyTypes().values());
124         filteredPolicyTypes = filter.filter(filteredPolicyTypes);
125
126         serviceTemplate.setPolicyTypes(asConceptMap(filteredPolicyTypes));
127
128         LOGGER.debug("<-getFilteredPolicyTypes: filter={}, serviceTemplate={}", filter, serviceTemplate);
129         return serviceTemplate;
130     }
131
132     /**
133      * Get filtered policy types.
134      *
135      * @param dao the DAO to use to access the database
136      * @param filter the filter for the policy types to get
137      * @return the policy types found
138      * @throws PfModelException on errors getting policy types
139      */
140     public List<ToscaPolicyType> getFilteredPolicyTypeList(@NonNull final PfDao dao,
141             @NonNull final ToscaPolicyTypeFilter filter) throws PfModelException {
142
143         LOGGER.debug("->getFilteredPolicyTypeList: filter={}", filter);
144
145         List<ToscaPolicyType> filteredPolicyTypeList = filter.filter(getPolicyTypeList(dao, null, null));
146
147         LOGGER.debug("<-getFilteredPolicyTypeList: filter={}, filteredPolicyTypeList={}", filter,
148                 filteredPolicyTypeList);
149
150         return filteredPolicyTypeList;
151     }
152
153     /**
154      * Create policy types.
155      *
156      * @param dao the DAO to use to access the database
157      * @param serviceTemplate the service template containing the definition of the policy types to be created
158      * @return the TOSCA service template containing the created policy types
159      * @throws PfModelException on errors creating policy types
160      */
161     public ToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
162             @NonNull final ToscaServiceTemplate serviceTemplate) throws PfModelException {
163
164         LOGGER.debug("->createPolicyTypes: serviceTemplate={}", serviceTemplate);
165
166         ToscaServiceTemplate createdServiceTempalate = new SimpleToscaProvider()
167                 .createPolicyTypes(dao, new JpaToscaServiceTemplate(serviceTemplate)).toAuthorative();
168
169         LOGGER.debug("<-createPolicyTypes: createdServiceTempalate={}", createdServiceTempalate);
170         return createdServiceTempalate;
171     }
172
173     /**
174      * Update policy types.
175      *
176      * @param dao the DAO to use to access the database
177      * @param serviceTemplate the service template containing the definition of the policy types to be modified
178      * @return the TOSCA service template containing the modified policy types
179      * @throws PfModelException on errors updating policy types
180      */
181     public ToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
182             @NonNull final ToscaServiceTemplate serviceTemplate) throws PfModelException {
183
184         LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
185
186         ToscaServiceTemplate updatedServiceTempalate = new SimpleToscaProvider()
187                 .updatePolicyTypes(dao, new JpaToscaServiceTemplate(serviceTemplate)).toAuthorative();
188
189         LOGGER.debug("<-updatePolicyTypes: updatedServiceTempalate={}", updatedServiceTempalate);
190         return updatedServiceTempalate;
191     }
192
193     /**
194      * Delete policy type.
195      *
196      * @param dao the DAO to use to access the database
197      * @param name the name of the policy type to delete.
198      * @param version the version of the policy type to delete.
199      * @return the TOSCA service template containing the policy type that was deleted
200      * @throws PfModelException on errors deleting policy types
201      */
202     public ToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final String name,
203             @NonNull final String version) throws PfModelException {
204
205         LOGGER.debug("->deletePolicyType: name={}, version={}", name, version);
206
207         ToscaServiceTemplate deletedServiceTempalate =
208                 new SimpleToscaProvider().deletePolicyType(dao, new PfConceptKey(name, version)).toAuthorative();
209
210         LOGGER.debug("<-deletePolicyType: name={}, version={}, deletedServiceTempalate={}", name, version,
211                 deletedServiceTempalate);
212         return deletedServiceTempalate;
213     }
214
215     /**
216      * Get policies.
217      *
218      * @param dao the DAO to use to access the database
219      * @param name the name of the policy to get.
220      * @param version the version of the policy to get.
221      * @return the policies found
222      * @throws PfModelException on errors getting policies
223      */
224     public ToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
225             throws PfModelException {
226         LOGGER.debug("->getPolicies: name={}, version={}", name, version);
227
228         ToscaServiceTemplate gotServiceTempalate =
229                 new SimpleToscaProvider().getPolicies(dao, name, version).toAuthorative();
230
231         LOGGER.debug("<-getPolicies: name={}, version={}, gotServiceTempalate={}", name, version, gotServiceTempalate);
232         return gotServiceTempalate;
233     }
234
235     /**
236      * Get policies.
237      *
238      * @param dao the DAO to use to access the database
239      * @param name the name of the policy to get, null to get all policies
240      * @param version the version of the policy to get, null to get all versions of a policy
241      * @return the policies found
242      * @throws PfModelException on errors getting policies
243      */
244     public List<ToscaPolicy> getPolicyList(@NonNull final PfDao dao, final String name, final String version)
245             throws PfModelException {
246         LOGGER.debug("->getPolicyList: name={}, version={}", name, version);
247
248         List<ToscaPolicy> policyList;
249
250         try {
251             policyList = asConceptList(new SimpleToscaProvider().getPolicies(dao, name, version).toAuthorative()
252                     .getToscaTopologyTemplate().getPolicies());
253         } catch (PfModelRuntimeException pfme) {
254             return handlePfModelRuntimeException(pfme);
255         }
256
257         LOGGER.debug("<-getPolicyList: name={}, version={}, policyTypeList={}", name, version, policyList);
258         return policyList;
259     }
260
261     /**
262      * Get filtered policies.
263      *
264      * @param dao the DAO to use to access the database
265      * @param filter the filter for the policies to get
266      * @return the policies found
267      * @throws PfModelException on errors getting policies
268      */
269     public ToscaServiceTemplate getFilteredPolicies(@NonNull final PfDao dao, @NonNull final ToscaPolicyFilter filter)
270             throws PfModelException {
271
272         LOGGER.debug("->getFilteredPolicies: filter={}", filter);
273         String version = ToscaPolicyFilter.LATEST_VERSION.equals(filter.getVersion()) ? null : filter.getVersion();
274
275         ToscaServiceTemplate serviceTemplate =
276                 new SimpleToscaProvider().getPolicies(dao, filter.getName(), version).toAuthorative();
277
278         List<ToscaPolicy> filteredPolicies = asConceptList(serviceTemplate.getToscaTopologyTemplate().getPolicies());
279         filteredPolicies = filter.filter(filteredPolicies);
280
281         serviceTemplate.getToscaTopologyTemplate().setPolicies(asConceptMapList(filteredPolicies));
282
283         LOGGER.debug("<-getFilteredPolicies: filter={}, serviceTemplate={}", filter, serviceTemplate);
284         return serviceTemplate;
285     }
286
287     /**
288      * Get filtered policies.
289      *
290      * @param dao the DAO to use to access the database
291      * @param filter the filter for the policies to get
292      * @return the policies found
293      * @throws PfModelException on errors getting policies
294      */
295     public List<ToscaPolicy> getFilteredPolicyList(@NonNull final PfDao dao, @NonNull final ToscaPolicyFilter filter)
296             throws PfModelException {
297
298         LOGGER.debug("->getFilteredPolicyList: filter={}", filter);
299         String version = ToscaPolicyFilter.LATEST_VERSION.equals(filter.getVersion()) ? null : filter.getVersion();
300
301         List<ToscaPolicy> policyList = filter.filter(getPolicyList(dao, filter.getName(), version));
302
303         LOGGER.debug("<-getFilteredPolicyList: filter={}, policyList={}", filter, policyList);
304         return policyList;
305     }
306
307     /**
308      * Create policies.
309      *
310      * @param dao the DAO to use to access the database
311      * @param serviceTemplate the service template containing the definitions of the new policies to be created.
312      * @return the TOSCA service template containing the policy types that were created
313      * @throws PfModelException on errors creating policies
314      */
315     public ToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
316             @NonNull final ToscaServiceTemplate serviceTemplate) throws PfModelException {
317
318         LOGGER.debug("->createPolicies: serviceTempalate={}", serviceTemplate);
319
320         ToscaServiceTemplate createdServiceTempalate = new SimpleToscaProvider()
321                 .createPolicies(dao, new JpaToscaServiceTemplate(serviceTemplate)).toAuthorative();
322
323         LOGGER.debug("<-createPolicies: createdServiceTempalate={}", createdServiceTempalate);
324         return createdServiceTempalate;
325     }
326
327     /**
328      * Update policies.
329      *
330      * @param dao the DAO to use to access the database
331      * @param serviceTemplate the service template containing the definitions of the policies to be updated.
332      * @return the TOSCA service template containing the policies that were updated
333      * @throws PfModelException on errors updating policies
334      */
335     public ToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
336             @NonNull final ToscaServiceTemplate serviceTemplate) throws PfModelException {
337
338         LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
339
340         ToscaServiceTemplate updatedServiceTempalate = new SimpleToscaProvider()
341                 .updatePolicies(dao, new JpaToscaServiceTemplate(serviceTemplate)).toAuthorative();
342
343         LOGGER.debug("<-updatePolicies: updatedServiceTempalate={}", updatedServiceTempalate);
344         return updatedServiceTempalate;
345     }
346
347     /**
348      * Delete policy.
349      *
350      * @param dao the DAO to use to access the database
351      * @param name the name of the policy to delete.
352      * @param version the version of the policy to delete.
353      * @return the TOSCA service template containing the policy that weas deleted
354      * @throws PfModelException on errors deleting policies
355      */
356     public ToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final String name,
357             @NonNull final String version) throws PfModelException {
358
359         LOGGER.debug("->deletePolicy: name={}, version={}", name, version);
360
361         ToscaServiceTemplate deletedServiceTempalate =
362                 new SimpleToscaProvider().deletePolicy(dao, new PfConceptKey(name, version)).toAuthorative();
363
364         LOGGER.debug("<-deletePolicy: name={}, version={}, deletedServiceTempalate={}", name, version,
365                 deletedServiceTempalate);
366         return deletedServiceTempalate;
367     }
368
369     /**
370      * Return the contents of a list of maps as a plain list.
371      *
372      * @param listOfMaps the list of maps
373      * @return the plain list
374      */
375     private <T> List<T> asConceptList(final List<Map<String, T>> listOfMaps) {
376         List<T> returnList = new ArrayList<>();
377         for (Map<String, T> conceptMap : listOfMaps) {
378             for (T concept : conceptMap.values()) {
379                 returnList.add(concept);
380             }
381         }
382
383         return returnList;
384     }
385
386     /**
387      * Return the contents of a list of concepts as a list of maps of concepts.
388      *
389      * @param conceptList the concept list
390      * @return the list of concept map
391      */
392     private <T extends ToscaEntity> List<Map<String, T>> asConceptMapList(List<T> conceptList) {
393         List<Map<String, T>> toscaEntityMapList = new ArrayList<>();
394         for (T concept : conceptList) {
395             Map<String, T> conceptMap = new TreeMap<>();
396             conceptMap.put(concept.getName(), concept);
397             toscaEntityMapList.add(conceptMap);
398         }
399
400         return toscaEntityMapList;
401     }
402
403     /**
404      * Return the contents of a list of concepts as map of concepts.
405      *
406      * @param conceptList the concept list
407      * @return the list of concept map
408      */
409     private <T extends ToscaEntity> Map<String, T> asConceptMap(List<T> conceptList) {
410         Map<String, T> conceptMap = new LinkedHashMap<>();
411         for (T concept : conceptList) {
412             conceptMap.put(concept.getName(), concept);
413         }
414
415         return conceptMap;
416     }
417
418     /**
419      * Handle a PfModelRuntimeException on a list call.
420      *
421      * @param pfme the model exception
422      * @return an empty list on 404
423      */
424     private <T extends ToscaEntity> List<T> handlePfModelRuntimeException(final PfModelRuntimeException pfme) {
425         if (Status.NOT_FOUND.equals(pfme.getErrorResponse().getResponseCode())) {
426             return Collections.emptyList();
427         } else {
428             throw pfme;
429         }
430     }
431 }