Add logging to model providers
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / provider / SimpleToscaProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
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.models.tosca.simple.provider;
22
23 import java.util.ArrayList;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import javax.ws.rs.core.Response;
29
30 import lombok.NonNull;
31
32 import org.onap.policy.models.base.PfConcept;
33 import org.onap.policy.models.base.PfConceptFilter;
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.dao.PfDao;
39 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies;
40 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy;
41 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType;
42 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes;
43 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
44 import org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate;
45 import org.onap.policy.models.tosca.utils.ToscaUtils;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 /**
50  * This class provides the provision of information on TOSCA concepts in the database to callers.
51  *
52  * @author Liam Fallon (liam.fallon@est.tech)
53  */
54 public class SimpleToscaProvider {
55     private static final Logger LOGGER = LoggerFactory.getLogger(SimpleToscaProvider.class);
56
57     /**
58      * Get policy types.
59      *
60      * @param dao the DAO to use to access the database
61      * @param name the name of the policy type to get, set to null to get all policy types
62      * @param version the version of the policy type to get, set to null to get all versions
63      * @return the policy types found
64      * @throws PfModelException on errors getting policy types
65      */
66     public JpaToscaServiceTemplate getPolicyTypes(@NonNull final PfDao dao, final String name, final String version)
67             throws PfModelException {
68         LOGGER.debug("->getPolicyTypes: name={}, version={}", name, version);
69
70         // Create the structure of the TOSCA service template to contain the policy type
71         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate();
72         serviceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
73
74         // Add the policy type to the TOSCA service template
75         List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, name, version);
76         serviceTemplate.getPolicyTypes().getConceptMap().putAll(asConceptMap(jpaPolicyTypeList));
77
78         LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate=", name, version, serviceTemplate);
79         return serviceTemplate;
80     }
81
82     /**
83      * Create policy types.
84      *
85      * @param dao the DAO to use to access the database
86      * @param serviceTemplate the service template containing the definition of the policy types to be created
87      * @return the TOSCA service template containing the created policy types
88      * @throws PfModelException on errors creating policy types
89      */
90     public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
91             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
92         LOGGER.debug("->createPolicyTypes: serviceTempalate={}", serviceTemplate);
93
94         ToscaUtils.assertPolicyTypesExist(serviceTemplate);
95
96         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
97             dao.create(policyType);
98         }
99
100         // Return the created policy types
101         JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
102
103         for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
104             returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
105         }
106
107         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
108         returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
109
110         LOGGER.debug("<-createPolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
111         return returnServiceTemplate;
112     }
113
114     /**
115      * Create policy types.
116      *
117      * @param dao the DAO to use to access the database
118      * @param serviceTemplate the service template containing the definition of the policy types to be modified
119      * @return the TOSCA service template containing the modified policy types
120      * @throws PfModelException on errors updating policy types
121      */
122     public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
123             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
124         LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
125
126         ToscaUtils.assertPolicyTypesExist(serviceTemplate);
127
128         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
129             dao.update(policyType);
130         }
131
132         // Return the created policy types
133         JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
134
135         for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
136             returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
137         }
138
139         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
140         returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
141
142         LOGGER.debug("<-updatePolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
143         return returnServiceTemplate;
144     }
145
146     /**
147      * Delete policy types.
148      *
149      * @param dao the DAO to use to access the database
150      * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
151      *        all versions of the policy type are deleted.
152      * @return the TOSCA service template containing the policy types that were deleted
153      * @throws PfModelException on errors deleting policy types
154      */
155     public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
156             throws PfModelException {
157         LOGGER.debug("->deletePolicyType: key={}", policyTypeKey);
158
159         JpaToscaServiceTemplate serviceTemplate =
160                 getPolicyTypes(dao, policyTypeKey.getName(), policyTypeKey.getVersion());
161
162         dao.delete(JpaToscaPolicyType.class, policyTypeKey);
163
164         LOGGER.debug("<-deletePolicyType: key={}, serviceTempalate=", policyTypeKey, serviceTemplate);
165         return serviceTemplate;
166     }
167
168     /**
169      * Get policies.
170      *
171      * @param dao the DAO to use to access the database
172      * @param name the name of the policy to get, set to null to get all policy types
173      * @param version the version of the policy to get, set to null to get all versions
174      * @return the policies found
175      * @throws PfModelException on errors getting policies
176      */
177     public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
178             throws PfModelException {
179         LOGGER.debug("->getPolicies: name={}, version={}", name, version);
180
181         // Create the structure of the TOSCA service template to contain the policy type
182         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate();
183         serviceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate());
184         serviceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
185
186         // Add the policy type to the TOSCA service template
187         List<JpaToscaPolicy> jpaPolicyList = dao.getFiltered(JpaToscaPolicy.class, name, version);
188         serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().putAll(asConceptMap(jpaPolicyList));
189
190         LOGGER.debug("<-getPolicies: name={}, version={}, serviceTemplate=", name, version, serviceTemplate);
191         return serviceTemplate;
192     }
193
194     /**
195      * Create policies.
196      *
197      * @param dao the DAO to use to access the database
198      * @param serviceTemplate the service template containing the definitions of the new policies to be created.
199      * @return the TOSCA service template containing the policy types that were created
200      * @throws PfModelException on errors creating policies
201      */
202     public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
203             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
204         LOGGER.debug("->createPolicies: serviceTempalate={}", serviceTemplate);
205
206         ToscaUtils.assertPoliciesExist(serviceTemplate);
207
208         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
209             verifyPolicyTypeForPolicy(dao, policy);
210             dao.create(policy);
211         }
212
213         // Return the created policy types
214         JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
215         returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
216
217         for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
218             returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
219         }
220
221         serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
222
223         LOGGER.debug("<-createPolicies: serviceTemplate={}", serviceTemplate);
224         return serviceTemplate;
225     }
226
227     /**
228      * Update policies.
229      *
230      * @param dao the DAO to use to access the database
231      * @param serviceTemplate the service template containing the definitions of the policies to be updated.
232      * @return the TOSCA service template containing the policies that were updated
233      * @throws PfModelException on errors updating policies
234      */
235     public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
236             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
237         LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
238
239         ToscaUtils.assertPoliciesExist(serviceTemplate);
240
241         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
242             verifyPolicyTypeForPolicy(dao, policy);
243             dao.update(policy);
244         }
245
246         // Return the created policy types
247         JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
248         returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
249
250         for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
251             returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
252         }
253
254         serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
255
256         LOGGER.debug("<-updatePolicies: serviceTemplate={}", serviceTemplate);
257         return serviceTemplate;
258     }
259
260     /**
261      * Delete policies.
262      *
263      * @param dao the DAO to use to access the database
264      * @param policyKey the policy key
265      * @return the TOSCA service template containing the policies that were deleted
266      * @throws PfModelException on errors deleting policies
267      */
268     public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
269             throws PfModelException {
270         LOGGER.debug("->deletePolicy: key={}", policyKey);
271
272         JpaToscaServiceTemplate serviceTemplate = getPolicies(dao, policyKey.getName(), policyKey.getVersion());
273
274         dao.delete(JpaToscaPolicy.class, policyKey);
275
276         LOGGER.debug("<-deletePolicy: key={}, serviceTempalate=", policyKey, serviceTemplate);
277         return serviceTemplate;
278     }
279
280     /**
281      * Convert a list of concepts to a map of concepts.
282      *
283      * @param conceptList the concept list
284      * @return the concept map
285      */
286     private <T extends PfConcept> Map<PfConceptKey, T> asConceptMap(List<T> conceptList) {
287         Map<PfConceptKey, T> conceptMap = new LinkedHashMap<>();
288         for (T concept : conceptList) {
289             conceptMap.put((PfConceptKey) concept.getKey(), concept);
290         }
291
292         return conceptMap;
293     }
294
295     /**
296      * Verify the policy type for a policy exists.
297      *
298      * @param dao the DAO to use to access policy types in the database
299      * @param policy the policy to check the policy type for
300      */
301     private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
302         PfConceptKey policyTypeKey = policy.getType();
303
304         JpaToscaPolicyType policyType = null;
305
306         if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
307             policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
308
309             if (policyType != null) {
310                 policy.getType().setVersion(policyType.getKey().getVersion());
311             }
312         } else {
313             policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
314         }
315
316         if (policyType == null) {
317             String errorMessage =
318                     "policy type " + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
319             LOGGER.warn(errorMessage);
320             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
321         }
322     }
323
324     /**
325      * Get the latest version of the policy type for the given policy type name.
326      *
327      * @param dao the DAO to use to access policy types in the database
328      * @param policyTypeName the name of the policy type
329      * @return the latest policy type
330      */
331     private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
332         // Policy type version is not specified, get the latest version from the database
333         List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
334
335         if (jpaPolicyTypeList.isEmpty()) {
336             return null;
337         }
338
339         // Create a filter to get the latest version of the policy type
340         PfConceptFilter pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
341
342         // FIlter the returned policy type list
343         List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
344         List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
345
346         // We should have one and only one returned entry
347         if (filterdPolicyTypeList.size() != 1) {
348             String errorMessage = "search for lates policy type " + policyTypeName + " returned more than one entry";
349             LOGGER.warn(errorMessage);
350             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
351         }
352
353         return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);
354     }
355 }