Set default and check existance of Policy Type
[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
69         // Create the structure of the TOSCA service template to contain the policy type
70         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate();
71         serviceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
72
73         // Add the policy type to the TOSCA service template
74         List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, name, version);
75         serviceTemplate.getPolicyTypes().getConceptMap().putAll(asConceptMap(jpaPolicyTypeList));
76
77         return serviceTemplate;
78     }
79
80     /**
81      * Create policy types.
82      *
83      * @param dao the DAO to use to access the database
84      * @param serviceTemplate the service template containing the definition of the policy types to be created
85      * @return the TOSCA service template containing the created policy types
86      * @throws PfModelException on errors creating policy types
87      */
88     public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
89             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
90
91         ToscaUtils.assertPolicyTypesExist(serviceTemplate);
92
93         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
94             dao.create(policyType);
95         }
96
97         // Return the created policy types
98         JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
99
100         for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
101             returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
102         }
103
104         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
105         returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
106
107         return returnServiceTemplate;
108     }
109
110     /**
111      * Create policy types.
112      *
113      * @param dao the DAO to use to access the database
114      * @param serviceTemplate the service template containing the definition of the policy types to be modified
115      * @return the TOSCA service template containing the modified policy types
116      * @throws PfModelException on errors updating policy types
117      */
118     public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
119             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
120
121         ToscaUtils.assertPolicyTypesExist(serviceTemplate);
122
123         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
124             dao.update(policyType);
125         }
126
127         // Return the created policy types
128         JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
129
130         for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
131             returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
132         }
133
134         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
135         returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
136
137         return returnServiceTemplate;
138     }
139
140     /**
141      * Delete policy types.
142      *
143      * @param dao the DAO to use to access the database
144      * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
145      *        all versions of the policy type are deleted.
146      * @return the TOSCA service template containing the policy types that were deleted
147      * @throws PfModelException on errors deleting policy types
148      */
149     public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
150             throws PfModelException {
151
152         JpaToscaServiceTemplate serviceTemplate =
153                 getPolicyTypes(dao, policyTypeKey.getName(), policyTypeKey.getVersion());
154
155         dao.delete(JpaToscaPolicyType.class, policyTypeKey);
156
157         return serviceTemplate;
158     }
159
160     /**
161      * Get policies.
162      *
163      * @param dao the DAO to use to access the database
164      * @param name the name of the policy to get, set to null to get all policy types
165      * @param version the version of the policy to get, set to null to get all versions
166      * @return the policies found
167      * @throws PfModelException on errors getting policies
168      */
169     public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
170             throws PfModelException {
171
172         // Create the structure of the TOSCA service template to contain the policy type
173         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate();
174         serviceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate());
175         serviceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
176
177         // Add the policy type to the TOSCA service template
178         List<JpaToscaPolicy> jpaPolicyList = dao.getFiltered(JpaToscaPolicy.class, name, version);
179         serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().putAll(asConceptMap(jpaPolicyList));
180         return serviceTemplate;
181     }
182
183     /**
184      * Create policies.
185      *
186      * @param dao the DAO to use to access the database
187      * @param serviceTemplate the service template containing the definitions of the new policies to be created.
188      * @return the TOSCA service template containing the policy types that were created
189      * @throws PfModelException on errors creating policies
190      */
191     public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
192             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
193
194         ToscaUtils.assertPoliciesExist(serviceTemplate);
195
196         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
197             verifyPolicyTypeForPolicy(dao, policy);
198
199             dao.create(policy);
200         }
201
202         // Return the created policy types
203         JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
204         returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
205
206         for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
207             returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
208         }
209
210         serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
211
212         return serviceTemplate;
213     }
214
215     /**
216      * Update policies.
217      *
218      * @param dao the DAO to use to access the database
219      * @param serviceTemplate the service template containing the definitions of the policies to be updated.
220      * @return the TOSCA service template containing the policies that were updated
221      * @throws PfModelException on errors updating policies
222      */
223     public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
224             @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
225
226         ToscaUtils.assertPoliciesExist(serviceTemplate);
227
228         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
229             dao.update(policy);
230         }
231
232         // Return the created policy types
233         JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
234         returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
235
236         for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
237             returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
238         }
239
240         serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
241
242         return serviceTemplate;
243     }
244
245     /**
246      * Delete policies.
247      *
248      * @param dao the DAO to use to access the database
249      * @param policyKey the policy key
250      * @return the TOSCA service template containing the policies that were deleted
251      * @throws PfModelException on errors deleting policies
252      */
253     public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
254             throws PfModelException {
255
256         JpaToscaServiceTemplate serviceTemplate = getPolicies(dao, policyKey.getName(), policyKey.getVersion());
257
258         dao.delete(JpaToscaPolicy.class, policyKey);
259
260         return serviceTemplate;
261     }
262
263     /**
264      * Convert a list of concepts to a map of concepts.
265      *
266      * @param conceptList the concept list
267      * @return the concept map
268      */
269     private <T extends PfConcept> Map<PfConceptKey, T> asConceptMap(List<T> conceptList) {
270         Map<PfConceptKey, T> conceptMap = new LinkedHashMap<>();
271         for (T concept : conceptList) {
272             conceptMap.put((PfConceptKey) concept.getKey(), concept);
273         }
274
275         return conceptMap;
276     }
277
278     /**
279      * Verify the policy type for a policy exists.
280      *
281      * @param dao the DAO to use to access policy types in the database
282      * @param policy the policy to check the policy type for
283      */
284     private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
285         PfConceptKey policyTypeKey = policy.getType();
286
287         JpaToscaPolicyType policyType = null;
288
289         if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
290             policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
291         } else {
292             policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
293         }
294
295         if (policyType == null) {
296             String errorMessage =
297                     "policy type " + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
298             LOGGER.warn(errorMessage);
299             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
300         }
301     }
302
303     /**
304      * Get the latest version of the policy type for the given policy type name.
305      *
306      * @param dao the DAO to use to access policy types in the database
307      * @param policyTypeName the name of the policy type
308      * @return the latest policy type
309      */
310     private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
311         // Policy type version is not specified, get the latest version from the database
312         List<JpaToscaPolicyType> jpaPolicyTypeList =
313                 dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
314
315         if (jpaPolicyTypeList.isEmpty()) {
316             return null;
317         }
318
319         // Create a filter to get the latest version of the policy type
320         PfConceptFilter pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
321
322         // FIlter the returned policy type list
323         List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
324         List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
325
326         // We should have one and only one returned entry
327         if (filterdPolicyTypeList.size() != 1 ) {
328             String errorMessage =
329                     "search for lates policy type " + policyTypeName + " returned more than one entry";
330             LOGGER.warn(errorMessage);
331             throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
332         }
333
334         return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);
335     }
336 }