8ac9e805d7f64a074d3eba1012ae27cf4e9ffb61
[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-2020 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.Collection;
25 import java.util.List;
26 import javax.ws.rs.core.Response;
27 import lombok.NonNull;
28 import org.apache.commons.collections4.CollectionUtils;
29 import org.onap.policy.models.base.PfConcept;
30 import org.onap.policy.models.base.PfConceptFilter;
31 import org.onap.policy.models.base.PfConceptKey;
32 import org.onap.policy.models.base.PfKey;
33 import org.onap.policy.models.base.PfModelException;
34 import org.onap.policy.models.base.PfModelRuntimeException;
35 import org.onap.policy.models.base.PfValidationResult;
36 import org.onap.policy.models.dao.PfDao;
37 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
38 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType;
39 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes;
40 import org.onap.policy.models.tosca.simple.concepts.JpaToscaEntityType;
41 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies;
42 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy;
43 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType;
44 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes;
45 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
46 import org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate;
47 import org.onap.policy.models.tosca.utils.ToscaServiceTemplateUtils;
48 import org.onap.policy.models.tosca.utils.ToscaUtils;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 /**
53  * This class provides the provision of information on TOSCA concepts in the database to callers.
54  *
55  * @author Liam Fallon (liam.fallon@est.tech)
56  */
57 public class SimpleToscaProvider {
58     private static final Logger LOGGER = LoggerFactory.getLogger(SimpleToscaProvider.class);
59
60     // Recurring string constants
61     private static final String DATA_TYPE = "data type ";
62     private static final String POLICY_TYPE = "policy type ";
63     private static final String SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE = "service template not found in database";
64     private static final String DO_NOT_EXIST = " do not exist";
65     private static final String NOT_FOUND = " not found";
66
67     /**
68      * Get Service Template.
69      *
70      * @param dao the DAO to use to access the database
71      * @return the service template
72      * @throws PfModelException on errors getting the service template
73      */
74     public JpaToscaServiceTemplate getServiceTemplate(@NonNull final PfDao dao) throws PfModelException {
75         LOGGER.debug("->getServiceTemplate");
76
77         JpaToscaServiceTemplate serviceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
78         if (serviceTemplate == null) {
79             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE);
80         }
81
82         LOGGER.debug("<-getServiceTemplate: serviceTemplate={}", serviceTemplate);
83         return serviceTemplate;
84     }
85
86     /**
87      * Append a service template fragment to the service template in the database.
88      *
89      * @param dao the DAO to use to access the database
90      * @param incomingServiceTemplateFragment the service template containing the definition of the entities to be
91      *        created
92      * @return the TOSCA service template in the database after the operation
93      * @throws PfModelException on errors appending a service template to the template in the database
94      */
95     public JpaToscaServiceTemplate appendToServiceTemplate(@NonNull final PfDao dao,
96         @NonNull final JpaToscaServiceTemplate incomingServiceTemplateFragment) throws PfModelException {
97         LOGGER.debug("->appendServiceTemplateFragment: incomingServiceTemplateFragment={}",
98             incomingServiceTemplateFragment);
99
100         JpaToscaServiceTemplate dbServiceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
101
102         JpaToscaServiceTemplate serviceTemplateToWrite;
103         if (dbServiceTemplate == null) {
104             serviceTemplateToWrite = incomingServiceTemplateFragment;
105         } else {
106             serviceTemplateToWrite =
107                 ToscaServiceTemplateUtils.addFragment(dbServiceTemplate, incomingServiceTemplateFragment);
108         }
109
110         PfValidationResult result = serviceTemplateToWrite.validate(new PfValidationResult());
111         if (!result.isValid()) {
112             throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, result.toString());
113         }
114
115         new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplateToWrite);
116
117         LOGGER.debug("<-appendServiceTemplateFragment: returnServiceTempalate={}", serviceTemplateToWrite);
118         return serviceTemplateToWrite;
119     }
120
121     /**
122      * Get data types.
123      *
124      * @param dao the DAO to use to access the database
125      * @param name the name of the data type to get, set to null to get all policy types
126      * @param version the version of the data type to get, set to null to get all versions
127      * @return the data types found
128      * @throws PfModelException on errors getting data types
129      */
130     public JpaToscaServiceTemplate getDataTypes(@NonNull final PfDao dao, final String name, final String version)
131         throws PfModelException {
132         LOGGER.debug("->getDataTypes: name={}, version={}", name, version);
133
134         final JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
135
136         if (!ToscaUtils.doDataTypesExist(dbServiceTemplate)) {
137             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
138                 "data types for " + name + ":" + version + DO_NOT_EXIST);
139         }
140
141         JpaToscaServiceTemplate serviceTemplate = getCascadedDataTypes(dbServiceTemplate, name, version);
142
143         LOGGER.debug("<-getDataTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
144         return serviceTemplate;
145     }
146
147     /**
148      * Get the cascaded data types for a data type name and version.
149      *
150      * @param dbServiceTemplate the service template to search for the cascaded data types
151      * @param name the data type name we are searching for
152      * @param version the data type version we are searching for
153      * @return a service template containing the cascaded data types
154      * @throws PfModelException on errors getting the data types
155      */
156     public JpaToscaServiceTemplate getCascadedDataTypes(@NonNull final JpaToscaServiceTemplate dbServiceTemplate,
157         final String name, final String version) throws PfModelException {
158
159         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
160         serviceTemplate.setPolicyTypes(null);
161         serviceTemplate.setTopologyTemplate(null);
162
163         ToscaUtils.getEntityTree(serviceTemplate.getDataTypes(), name, version);
164
165         if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
166             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
167                 "data types for " + name + ":" + version + DO_NOT_EXIST);
168         }
169
170         for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getConceptMap().values()) {
171             Collection<PfConceptKey> referencedDataTypeKeys = dataType.getReferencedDataTypes();
172
173             for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
174                 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate = getCascadedDataTypes(dbServiceTemplate,
175                     referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
176
177                 serviceTemplate =
178                     ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeEntityTreeServiceTemplate);
179             }
180         }
181         return serviceTemplate;
182     }
183
184     /**
185      * Create data types.
186      *
187      * @param dao the DAO to use to access the database
188      * @param incomingServiceTemplate the service template containing the definition of the data types to be created
189      * @return the TOSCA service template containing the created data types
190      * @throws PfModelException on errors creating data types
191      */
192     public JpaToscaServiceTemplate createDataTypes(@NonNull final PfDao dao,
193         @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
194         LOGGER.debug("->createDataTypes: incomingServiceTemplate={}", incomingServiceTemplate);
195
196         ToscaUtils.assertDataTypesExist(incomingServiceTemplate);
197
198         JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
199
200         LOGGER.debug("<-createDataTypes: writtenServiceTemplate={}", writtenServiceTemplate);
201         return incomingServiceTemplate;
202     }
203
204     /**
205      * Update Data types.
206      *
207      * @param dao the DAO to use to access the database
208      * @param serviceTemplate the service template containing the definition of the data types to be modified
209      * @return the TOSCA service template containing the modified data types
210      * @throws PfModelException on errors updating Data types
211      */
212     public JpaToscaServiceTemplate updateDataTypes(@NonNull final PfDao dao,
213         @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
214         LOGGER.debug("->updateDataTypes: serviceTempalate={}", serviceTemplate);
215
216         ToscaUtils.assertDataTypesExist(serviceTemplate);
217
218         for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
219             dao.update(dataType);
220         }
221
222         // Return the created data types
223         JpaToscaDataTypes returnDataTypes = new JpaToscaDataTypes();
224
225         for (PfConceptKey dataTypeKey : serviceTemplate.getDataTypes().getConceptMap().keySet()) {
226             returnDataTypes.getConceptMap().put(dataTypeKey, dao.get(JpaToscaDataType.class, dataTypeKey));
227         }
228
229         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
230         returnServiceTemplate.setDataTypes(returnDataTypes);
231
232         LOGGER.debug("<-updateDataTypes: returnServiceTempalate={}", returnServiceTemplate);
233         return returnServiceTemplate;
234     }
235
236     /**
237      * Delete Data types.
238      *
239      * @param dao the DAO to use to access the database
240      * @param dataTypeKey the data type key for the Data types to be deleted, if the version of the key is null, all
241      *        versions of the data type are deleted.
242      * @return the TOSCA service template containing the data types that were deleted
243      * @throws PfModelException on errors deleting data types
244      */
245     public JpaToscaServiceTemplate deleteDataType(@NonNull final PfDao dao, @NonNull final PfConceptKey dataTypeKey)
246         throws PfModelException {
247         LOGGER.debug("->deleteDataType: key={}", dataTypeKey);
248
249         JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
250
251         if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
252             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no data types found");
253         }
254
255         JpaToscaDataType dataType4Deletion = serviceTemplate.getDataTypes().get(dataTypeKey);
256         if (dataType4Deletion == null) {
257             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, DATA_TYPE + dataTypeKey.getId() + NOT_FOUND);
258         }
259
260         for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
261             if (dataType.getReferencedDataTypes().contains(dataTypeKey)) {
262                 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE,
263                     DATA_TYPE + dataTypeKey.getId() + " is in use, it is referenced in data type " + dataType.getId());
264             }
265         }
266
267         if (ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
268             for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
269                 if (policyType.getReferencedDataTypes().contains(dataTypeKey)) {
270                     throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, DATA_TYPE + dataTypeKey.getId()
271                         + " is in use, it is referenced in policy type " + policyType.getId());
272                 }
273             }
274         }
275
276         serviceTemplate.getDataTypes().getConceptMap().remove(dataTypeKey);
277         new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplate);
278         dao.delete(dataType4Deletion);
279
280         JpaToscaServiceTemplate deletedServiceTemplate = new JpaToscaServiceTemplate();
281         deletedServiceTemplate.setDataTypes(new JpaToscaDataTypes());
282         deletedServiceTemplate.getDataTypes().getConceptMap().put(dataTypeKey, dataType4Deletion);
283
284         LOGGER.debug("<-deleteDataType: key={}, serviceTempalate={}", dataTypeKey, deletedServiceTemplate);
285         return deletedServiceTemplate;
286     }
287
288     /**
289      * Get policy types.
290      *
291      * @param dao the DAO to use to access the database
292      * @param name the name of the policy type to get, set to null to get all policy types
293      * @param version the version of the policy type to get, set to null to get all versions
294      * @return the policy types found
295      * @throws PfModelException on errors getting policy types
296      */
297     public JpaToscaServiceTemplate getPolicyTypes(@NonNull final PfDao dao, final String name, final String version)
298         throws PfModelException {
299         LOGGER.debug("->getPolicyTypes: name={}, version={}", name, version);
300
301         final JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
302
303         if (!ToscaUtils.doPolicyTypesExist(dbServiceTemplate)) {
304             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
305                 "policy types for " + name + ":" + version + DO_NOT_EXIST);
306         }
307
308         JpaToscaServiceTemplate serviceTemplate = getCascadedPolicyTypes(dbServiceTemplate, name, version);
309
310         LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
311         return serviceTemplate;
312     }
313
314     /**
315      * Get the cascaded policy types for a policy type name and version.
316      *
317      * @param dbServiceTemplate the service template to search for the cascaded policy types
318      * @param name the policy type name we are searching for
319      * @param version the policy type version we are searching for
320      * @return a service template containing the cascaded policy types
321      * @throws PfModelException on errors getting the policy types
322      */
323     public JpaToscaServiceTemplate getCascadedPolicyTypes(final JpaToscaServiceTemplate dbServiceTemplate,
324         final String name, final String version) throws PfModelException {
325
326         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
327
328         serviceTemplate.setDataTypes(null);
329         serviceTemplate.setTopologyTemplate(null);
330
331         ToscaUtils.getEntityTree(serviceTemplate.getPolicyTypes(), name, version);
332
333         if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
334             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
335                 "policy types for " + name + ":" + version + DO_NOT_EXIST);
336         }
337
338         JpaToscaServiceTemplate dataTypeServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate);
339         dataTypeServiceTemplate.setPolicyTypes(null);
340
341         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getConceptMap().values()) {
342             Collection<PfConceptKey> referencedDataTypeKeys = policyType.getReferencedDataTypes();
343
344             for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
345                 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate = getCascadedDataTypes(dbServiceTemplate,
346                     referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
347
348                 dataTypeServiceTemplate =
349                     ToscaServiceTemplateUtils.addFragment(dataTypeServiceTemplate, dataTypeEntityTreeServiceTemplate);
350             }
351         }
352
353         serviceTemplate = ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeServiceTemplate);
354         return serviceTemplate;
355     }
356
357     /**
358      * Create policy types.
359      *
360      * @param dao the DAO to use to access the database
361      * @param incomingServiceTemplate the service template containing the definition of the policy types to be created
362      * @return the TOSCA service template containing the created policy types
363      * @throws PfModelException on errors creating policy types
364      */
365     public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
366         @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
367         LOGGER.debug("->createPolicyTypes: serviceTempalate={}", incomingServiceTemplate);
368
369         ToscaUtils.assertPolicyTypesExist(incomingServiceTemplate);
370
371         JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
372
373         LOGGER.debug("<-createPolicyTypes: writtenServiceTemplate={}", writtenServiceTemplate);
374         return incomingServiceTemplate;
375     }
376
377     /**
378      * Update policy types.
379      *
380      * @param dao the DAO to use to access the database
381      * @param serviceTemplate the service template containing the definition of the policy types to be modified
382      * @return the TOSCA service template containing the modified policy types
383      * @throws PfModelException on errors updating policy types
384      */
385     public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
386         @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
387         LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
388
389         ToscaUtils.assertPolicyTypesExist(serviceTemplate);
390
391         // Update the data types on the policy type
392         if (ToscaUtils.doDataTypesExist(serviceTemplate)) {
393             updateDataTypes(dao, serviceTemplate);
394         }
395
396         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
397             dao.update(policyType);
398         }
399
400         // Return the created policy types
401         JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
402
403         for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
404             returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
405         }
406
407         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
408         returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
409
410         LOGGER.debug("<-updatePolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
411         return returnServiceTemplate;
412     }
413
414     /**
415      * Delete policy types.
416      *
417      * @param dao the DAO to use to access the database
418      * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
419      *        all versions of the policy type are deleted.
420      * @return the TOSCA service template containing the policy types that were deleted
421      * @throws PfModelException on errors deleting policy types
422      */
423     public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
424         throws PfModelException {
425         LOGGER.debug("->deletePolicyType: key={}", policyTypeKey);
426
427         JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
428
429         if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
430             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no policy types found");
431         }
432
433         JpaToscaPolicyType policyType4Deletion = serviceTemplate.getPolicyTypes().get(policyTypeKey);
434         if (policyType4Deletion == null) {
435             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
436                 POLICY_TYPE + policyTypeKey.getId() + NOT_FOUND);
437         }
438
439         for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
440             Collection<JpaToscaEntityType<ToscaEntity>> ancestorList = ToscaUtils
441                 .getEntityTypeAncestors(serviceTemplate.getPolicyTypes(), policyType, new PfValidationResult());
442
443             if (ancestorList.contains(policyType4Deletion)) {
444                 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, POLICY_TYPE + policyTypeKey.getId()
445                     + " is in use, it is referenced in policy type " + policyType.getId());
446             }
447         }
448
449         if (ToscaUtils.doPoliciesExist(serviceTemplate)) {
450             for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
451                 if (policyTypeKey.equals(policy.getType())) {
452                     throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, POLICY_TYPE
453                         + policyTypeKey.getId() + " is in use, it is referenced in policy " + policy.getId());
454                 }
455             }
456         }
457
458         serviceTemplate.getPolicyTypes().getConceptMap().remove(policyTypeKey);
459         new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplate);
460         dao.delete(policyType4Deletion);
461
462         JpaToscaServiceTemplate deletedServiceTemplate = new JpaToscaServiceTemplate();
463         deletedServiceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
464         deletedServiceTemplate.getPolicyTypes().getConceptMap().put(policyTypeKey, policyType4Deletion);
465
466         LOGGER.debug("<-deletePolicyType: key={}, serviceTempalate={}", policyTypeKey, deletedServiceTemplate);
467         return deletedServiceTemplate;
468     }
469
470     /**
471      * Get policies.
472      *
473      * @param dao the DAO to use to access the database
474      * @param name the name of the policy to get, set to null to get all policy types
475      * @param version the version of the policy to get, set to null to get all versions
476      * @return the policies found
477      * @throws PfModelException on errors getting policies
478      */
479     public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
480         throws PfModelException {
481         LOGGER.debug("->getPolicies: name={}, version={}", name, version);
482
483         JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
484
485         if (!ToscaUtils.doPoliciesExist(dbServiceTemplate)) {
486             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
487                 "policies for " + name + ":" + version + DO_NOT_EXIST);
488         }
489
490         JpaToscaServiceTemplate returnServiceTemplate = getCascadedPolicies(dbServiceTemplate, name, version);
491
492         LOGGER.debug("<-getPolicies: name={}, version={}, serviceTemplate={}", name, version, returnServiceTemplate);
493         return returnServiceTemplate;
494     }
495
496     /**
497      * Get the cascaded policies for a policy name and version.
498      *
499      * @param dbServiceTemplate the service template to search for the cascaded policy
500      * @param name the policy name we are searching for
501      * @param version the policy version we are searching for
502      * @return a service template containing the cascaded policy
503      * @throws PfModelException on errors getting the policy
504      */
505     public JpaToscaServiceTemplate getCascadedPolicies(final JpaToscaServiceTemplate dbServiceTemplate,
506         final String name, final String version) throws PfModelException {
507
508         JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
509         serviceTemplate.setDataTypes(new JpaToscaDataTypes());
510         serviceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
511
512         ToscaUtils.getEntityTree(serviceTemplate.getTopologyTemplate().getPolicies(), name, version);
513
514         if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
515             throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
516                 "policies for " + name + ":" + version + DO_NOT_EXIST);
517         }
518
519         JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate);
520         returnServiceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
521
522         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().values()) {
523             JpaToscaServiceTemplate referencedEntitiesServiceTemplate =
524                 getCascadedPolicyTypes(dbServiceTemplate, policy.getType().getName(), policy.getType().getVersion());
525
526             returnServiceTemplate.getTopologyTemplate().getPolicies().getConceptMap().put(policy.getKey(), policy);
527             returnServiceTemplate =
528                 ToscaServiceTemplateUtils.addFragment(returnServiceTemplate, referencedEntitiesServiceTemplate);
529         }
530
531         return returnServiceTemplate;
532     }
533
534     /**
535      * Create policies.
536      *
537      * @param dao the DAO to use to access the database
538      * @param incomingServiceTemplate the service template containing the definitions of the new policies to be created.
539      * @return the TOSCA service template containing the policy types that were created
540      * @throws PfModelException on errors creating policies
541      */
542     public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
543         @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
544         LOGGER.debug("->createPolicies: incomingServiceTemplate={}", incomingServiceTemplate);
545
546         ToscaUtils.assertPoliciesExist(incomingServiceTemplate);
547
548         JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
549
550         LOGGER.debug("<-createPolicies: writtenServiceTemplate={}", writtenServiceTemplate);
551         return incomingServiceTemplate;
552     }
553
554     /**
555      * Update policies.
556      *
557      * @param dao the DAO to use to access the database
558      * @param serviceTemplate the service template containing the definitions of the policies to be updated.
559      * @return the TOSCA service template containing the policies that were updated
560      * @throws PfModelException on errors updating policies
561      */
562     public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
563         @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
564         LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
565
566         ToscaUtils.assertPoliciesExist(serviceTemplate);
567
568         for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
569             verifyPolicyTypeForPolicy(dao, policy);
570             dao.update(policy);
571         }
572
573         // Return the created policy types
574         JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
575         returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
576
577         for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
578             returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
579         }
580
581         serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
582
583         LOGGER.debug("<-updatePolicies: serviceTemplate={}", serviceTemplate);
584         return serviceTemplate;
585     }
586
587     /**
588      * Delete policies.
589      *
590      * @param dao the DAO to use to access the database
591      * @param policyKey the policy key
592      * @return the TOSCA service template containing the policies that were deleted
593      * @throws PfModelException on errors deleting policies
594      */
595     public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
596         throws PfModelException {
597         LOGGER.debug("->deletePolicy: key={}", policyKey);
598
599         JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
600
601         if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
602             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no policies found");
603         }
604
605         JpaToscaPolicy policy4Deletion = serviceTemplate.getTopologyTemplate().getPolicies().get(policyKey);
606         if (policy4Deletion == null) {
607             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "policy " + policyKey.getId() + NOT_FOUND);
608         }
609
610         serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().remove(policyKey);
611         new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplate);
612         dao.delete(policy4Deletion);
613
614         JpaToscaServiceTemplate deletedServiceTemplate = new JpaToscaServiceTemplate();
615         deletedServiceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate());
616         deletedServiceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
617         deletedServiceTemplate.getTopologyTemplate().getPolicies().getConceptMap().put(policyKey, policy4Deletion);
618
619         LOGGER.debug("<-deletePolicy: key={}, serviceTempalate={}", policyKey, deletedServiceTemplate);
620         return deletedServiceTemplate;
621     }
622
623     /**
624      * Verify the policy type for a policy exists.
625      *
626      * @param dao the DAO to use to access policy types in the database
627      * @param policy the policy to check the policy type for
628      */
629     private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
630         PfConceptKey policyTypeKey = policy.getType();
631
632         JpaToscaPolicyType policyType = null;
633
634         if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
635             policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
636
637             if (policyType != null) {
638                 policy.getType().setVersion(policyType.getKey().getVersion());
639             }
640         } else {
641             policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
642         }
643
644         if (policyType == null) {
645             String errorMessage =
646                 POLICY_TYPE + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
647             throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, errorMessage);
648         }
649     }
650
651     /**
652      * Get the latest version of the policy type for the given policy type name.
653      *
654      * @param dao the DAO to use to access policy types in the database
655      * @param policyTypeName the name of the policy type
656      * @return the latest policy type
657      */
658     private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
659         // Policy type version is not specified, get the latest version from the database
660         List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
661
662         if (CollectionUtils.isEmpty(jpaPolicyTypeList)) {
663             return null;
664         }
665
666         // Create a filter to get the latest version of the policy type
667         PfConceptFilter pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
668
669         // FIlter the returned policy type list
670         List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
671         List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
672
673         // We should have one and only one returned entry
674         if (filterdPolicyTypeList.size() != 1) {
675             String errorMessage = "search for latest policy type " + policyTypeName + " returned more than one entry";
676             throw new PfModelRuntimeException(Response.Status.CONFLICT, errorMessage);
677         }
678
679         return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);
680     }
681 }