2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2020, 2022-2023 Nordix Foundation.
4 * Modifications Copyright (C) 2020-2021 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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.models.tosca.simple.provider;
24 import jakarta.ws.rs.core.Response;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.List;
29 import java.util.Optional;
30 import lombok.NonNull;
31 import org.apache.commons.collections4.CollectionUtils;
32 import org.onap.policy.common.parameters.BeanValidationResult;
33 import org.onap.policy.models.base.PfConcept;
34 import org.onap.policy.models.base.PfConceptFilter;
35 import org.onap.policy.models.base.PfConceptKey;
36 import org.onap.policy.models.base.PfKey;
37 import org.onap.policy.models.base.PfModelException;
38 import org.onap.policy.models.base.PfModelRuntimeException;
39 import org.onap.policy.models.dao.PfDao;
40 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntityKey;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
43 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType;
44 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes;
45 import org.onap.policy.models.tosca.simple.concepts.JpaToscaEntityType;
46 import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate;
47 import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplates;
48 import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeType;
49 import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTypes;
50 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies;
51 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy;
52 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType;
53 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes;
54 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
55 import org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate;
56 import org.onap.policy.models.tosca.utils.ToscaServiceTemplateUtils;
57 import org.onap.policy.models.tosca.utils.ToscaUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
62 * This class provides the provision of information on TOSCA concepts in the database to callers.
64 * @author Liam Fallon (liam.fallon@est.tech)
66 public class SimpleToscaProvider {
67 private static final Logger LOGGER = LoggerFactory.getLogger(SimpleToscaProvider.class);
69 // Recurring string constants
70 private static final String DATA_TYPE = "data type ";
71 private static final String POLICY_TYPE = "policy type ";
72 private static final String SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE = "service template not found in database";
73 private static final String DO_NOT_EXIST = " do not exist";
74 private static final String NOT_FOUND = " not found";
77 * Get Service Template.
79 * @param dao the DAO to use to access the database
80 * @return the service template
81 * @throws PfModelException on errors getting the service template
83 public JpaToscaServiceTemplate getServiceTemplate(@NonNull final PfDao dao) throws PfModelException {
84 LOGGER.debug("->getServiceTemplate");
86 JpaToscaServiceTemplate serviceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
87 if (serviceTemplate == null) {
88 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE);
91 LOGGER.debug("<-getServiceTemplate: serviceTemplate={}", serviceTemplate);
92 return serviceTemplate;
96 * Append a service template fragment to the service template in the database.
98 * @param dao the DAO to use to access the database
99 * @param incomingServiceTemplateFragment the service template containing the definition of the entities to be
101 * @return the TOSCA service template in the database after the operation
102 * @throws PfModelException on errors appending a service template to the template in the database
104 public JpaToscaServiceTemplate appendToServiceTemplate(@NonNull final PfDao dao,
105 @NonNull final JpaToscaServiceTemplate incomingServiceTemplateFragment) throws PfModelException {
106 LOGGER.debug("->appendServiceTemplateFragment: incomingServiceTemplateFragment={}",
107 incomingServiceTemplateFragment);
109 JpaToscaServiceTemplate dbServiceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
111 JpaToscaServiceTemplate serviceTemplateToWrite;
112 if (dbServiceTemplate == null) {
113 serviceTemplateToWrite = incomingServiceTemplateFragment;
115 serviceTemplateToWrite =
116 ToscaServiceTemplateUtils.addFragment(dbServiceTemplate, incomingServiceTemplateFragment);
119 BeanValidationResult result = serviceTemplateToWrite.validate("service template");
120 if (!result.isValid()) {
121 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, result.getResult());
124 new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplateToWrite);
126 LOGGER.debug("<-appendServiceTemplateFragment: returnServiceTempalate={}", serviceTemplateToWrite);
127 return serviceTemplateToWrite;
131 * Delete service template.
133 * @param dao the DAO to use to access the database
134 * @return the TOSCA service template that was deleted
135 * @throws PfModelException on errors deleting the service template
137 public JpaToscaServiceTemplate deleteServiceTemplate(@NonNull final PfDao dao) throws PfModelException {
138 LOGGER.debug("->deleteServiceTemplate");
140 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
142 dao.delete(serviceTemplate);
144 LOGGER.debug("->deleteServiceTemplate: serviceTemplate={}", serviceTemplate);
145 return serviceTemplate;
151 * @param dao the DAO to use to access the database
152 * @param name the name of the data type to get, set to null to get all policy types
153 * @param version the version of the data type to get, set to null to get all versions
154 * @return the data types found
155 * @throws PfModelException on errors getting data types
157 public JpaToscaServiceTemplate getDataTypes(@NonNull final PfDao dao, final String name, final String version)
158 throws PfModelException {
159 LOGGER.debug("->getDataTypes: name={}, version={}", name, version);
161 final JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
163 if (!ToscaUtils.doDataTypesExist(dbServiceTemplate)) {
164 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
165 "data types for " + name + ":" + version + DO_NOT_EXIST);
168 JpaToscaServiceTemplate serviceTemplate = getCascadedDataTypes(dbServiceTemplate, name, version);
170 LOGGER.debug("<-getDataTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
171 return serviceTemplate;
175 * Get the cascaded data types for a data type name and version.
177 * @param dbServiceTemplate the service template to search for the cascaded data types
178 * @param name the data type name we are searching for
179 * @param version the data type version we are searching for
180 * @return a service template containing the cascaded data types
181 * @throws PfModelException on errors getting the data types
183 public JpaToscaServiceTemplate getCascadedDataTypes(@NonNull final JpaToscaServiceTemplate dbServiceTemplate,
184 final String name, final String version) throws PfModelException {
186 var serviceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
187 serviceTemplate.setPolicyTypes(null);
188 serviceTemplate.setTopologyTemplate(null);
190 ToscaUtils.getEntityTree(serviceTemplate.getDataTypes(), name, version);
192 if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
193 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
194 "data types for " + name + ":" + version + DO_NOT_EXIST);
197 for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getConceptMap().values()) {
198 Collection<PfConceptKey> referencedDataTypeKeys = dataType.getReferencedDataTypes();
200 for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
201 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate = getCascadedDataTypes(dbServiceTemplate,
202 referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
205 ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeEntityTreeServiceTemplate);
208 return serviceTemplate;
214 * @param dao the DAO to use to access the database
215 * @param incomingServiceTemplate the service template containing the definition of the data types to be created
216 * @return the TOSCA service template containing the created data types
217 * @throws PfModelException on errors creating data types
219 public JpaToscaServiceTemplate createDataTypes(@NonNull final PfDao dao,
220 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
221 LOGGER.debug("->createDataTypes: incomingServiceTemplate={}", incomingServiceTemplate);
223 ToscaUtils.assertDataTypesExist(incomingServiceTemplate);
225 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
227 LOGGER.debug("<-createDataTypes: writtenServiceTemplate={}", writtenServiceTemplate);
228 return incomingServiceTemplate;
234 * @param dao the DAO to use to access the database
235 * @param serviceTemplate the service template containing the definition of the data types to be modified
236 * @return the TOSCA service template containing the modified data types
237 * @throws PfModelException on errors updating Data types
239 public JpaToscaServiceTemplate updateDataTypes(@NonNull final PfDao dao,
240 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
241 LOGGER.debug("->updateDataTypes: serviceTempalate={}", serviceTemplate);
243 ToscaUtils.assertDataTypesExist(serviceTemplate);
245 for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
246 dao.update(dataType);
249 // Return the created data types
250 var returnDataTypes = new JpaToscaDataTypes();
252 for (PfConceptKey dataTypeKey : serviceTemplate.getDataTypes().getConceptMap().keySet()) {
253 returnDataTypes.getConceptMap().put(dataTypeKey, dao.get(JpaToscaDataType.class, dataTypeKey));
256 var returnServiceTemplate = new JpaToscaServiceTemplate();
257 returnServiceTemplate.setDataTypes(returnDataTypes);
259 LOGGER.debug("<-updateDataTypes: returnServiceTempalate={}", returnServiceTemplate);
260 return returnServiceTemplate;
266 * @param dao the DAO to use to access the database
267 * @param dataTypeKey the data type key for the Data types to be deleted, if the version of the key is null, all
268 * versions of the data type are deleted.
269 * @return the TOSCA service template containing the data types that were deleted
270 * @throws PfModelException on errors deleting data types
272 public JpaToscaServiceTemplate deleteDataType(@NonNull final PfDao dao, @NonNull final PfConceptKey dataTypeKey)
273 throws PfModelException {
274 LOGGER.debug("->deleteDataType: key={}", dataTypeKey);
276 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
278 if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
279 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no data types found");
282 JpaToscaDataType dataType4Deletion = serviceTemplate.getDataTypes().get(dataTypeKey);
283 if (dataType4Deletion == null) {
284 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, DATA_TYPE + dataTypeKey.getId() + NOT_FOUND);
287 for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
288 if (dataType.getReferencedDataTypes().contains(dataTypeKey)) {
289 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE,
290 DATA_TYPE + dataTypeKey.getId() + " is in use, it is referenced in data type " + dataType.getId());
294 if (ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
295 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
296 if (policyType.getReferencedDataTypes().contains(dataTypeKey)) {
297 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, DATA_TYPE + dataTypeKey.getId()
298 + " is in use, it is referenced in policy type " + policyType.getId());
303 serviceTemplate.getDataTypes().getConceptMap().remove(dataTypeKey);
304 new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplate);
305 dao.delete(dataType4Deletion);
307 var deletedServiceTemplate = new JpaToscaServiceTemplate();
308 deletedServiceTemplate.setDataTypes(new JpaToscaDataTypes());
309 deletedServiceTemplate.getDataTypes().getConceptMap().put(dataTypeKey, dataType4Deletion);
311 LOGGER.debug("<-deleteDataType: key={}, serviceTempalate={}", dataTypeKey, deletedServiceTemplate);
312 return deletedServiceTemplate;
318 * @param dao the DAO to use to access the database
319 * @param name the name of the policy type to get, set to null to get all policy types
320 * @param version the version of the policy type to get, set to null to get all versions
321 * @return the policy types found
322 * @throws PfModelException on errors getting policy types
324 public JpaToscaServiceTemplate getPolicyTypes(@NonNull final PfDao dao, final String name, final String version)
325 throws PfModelException {
326 LOGGER.debug("->getPolicyTypes: name={}, version={}", name, version);
328 final JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
330 if (!ToscaUtils.doPolicyTypesExist(dbServiceTemplate)) {
331 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
332 "policy types for " + name + ":" + version + DO_NOT_EXIST);
335 JpaToscaServiceTemplate serviceTemplate = getCascadedPolicyTypes(dbServiceTemplate, name, version);
337 LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
338 return serviceTemplate;
342 * Get the cascaded policy types for a policy type name and version.
344 * @param dbServiceTemplate the service template to search for the cascaded policy types
345 * @param name the policy type name we are searching for
346 * @param version the policy type version we are searching for
347 * @return a service template containing the cascaded policy types
348 * @throws PfModelException on errors getting the policy types
350 public JpaToscaServiceTemplate getCascadedPolicyTypes(final JpaToscaServiceTemplate dbServiceTemplate,
351 final String name, final String version) throws PfModelException {
353 var serviceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
355 serviceTemplate.setDataTypes(null);
356 serviceTemplate.setTopologyTemplate(null);
358 ToscaUtils.getEntityTree(serviceTemplate.getPolicyTypes(), name, version);
360 if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
361 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
362 "policy types for " + name + ":" + version + DO_NOT_EXIST);
365 var dataTypeServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate);
366 dataTypeServiceTemplate.setPolicyTypes(null);
368 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getConceptMap().values()) {
369 Collection<PfConceptKey> referencedDataTypeKeys = policyType.getReferencedDataTypes();
371 for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
372 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate = getCascadedDataTypes(dbServiceTemplate,
373 referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
375 dataTypeServiceTemplate =
376 ToscaServiceTemplateUtils.addFragment(dataTypeServiceTemplate, dataTypeEntityTreeServiceTemplate);
380 serviceTemplate = ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeServiceTemplate);
381 return serviceTemplate;
385 * Create policy types.
387 * @param dao the DAO to use to access the database
388 * @param incomingServiceTemplate the service template containing the definition of the policy types to be created
389 * @return the TOSCA service template containing the created policy types
390 * @throws PfModelException on errors creating policy types
392 public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
393 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
394 LOGGER.debug("->createPolicyTypes: serviceTempalate={}", incomingServiceTemplate);
396 ToscaUtils.assertPolicyTypesExist(incomingServiceTemplate);
398 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
400 LOGGER.debug("<-createPolicyTypes: writtenServiceTemplate={}", writtenServiceTemplate);
401 return incomingServiceTemplate;
405 * Update policy types.
407 * @param dao the DAO to use to access the database
408 * @param serviceTemplate the service template containing the definition of the policy types to be modified
409 * @return the TOSCA service template containing the modified policy types
410 * @throws PfModelException on errors updating policy types
412 public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
413 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
414 LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
416 ToscaUtils.assertPolicyTypesExist(serviceTemplate);
418 // Update the data types on the policy type
419 if (ToscaUtils.doDataTypesExist(serviceTemplate)) {
420 updateDataTypes(dao, serviceTemplate);
423 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
424 dao.update(policyType);
427 // Return the created policy types
428 var returnPolicyTypes = new JpaToscaPolicyTypes();
430 for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
431 returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
434 var returnServiceTemplate = new JpaToscaServiceTemplate();
435 returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
437 LOGGER.debug("<-updatePolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
438 return returnServiceTemplate;
442 * Delete policy types.
444 * @param dao the DAO to use to access the database
445 * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
446 * all versions of the policy type are deleted.
447 * @return the TOSCA service template containing the policy types that were deleted
448 * @throws PfModelException on errors deleting policy types
450 public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
451 throws PfModelException {
452 LOGGER.debug("->deletePolicyType: key={}", policyTypeKey);
454 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
456 if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
457 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no policy types found");
460 JpaToscaPolicyType policyType4Deletion = serviceTemplate.getPolicyTypes().get(policyTypeKey);
461 if (policyType4Deletion == null) {
462 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
463 POLICY_TYPE + policyTypeKey.getId() + NOT_FOUND);
466 var result = new BeanValidationResult("policy types", serviceTemplate);
468 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
469 Collection<JpaToscaEntityType<ToscaEntity>> ancestorList = ToscaUtils
470 .getEntityTypeAncestors(serviceTemplate.getPolicyTypes(), policyType, result);
472 if (ancestorList.contains(policyType4Deletion)) {
473 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, POLICY_TYPE + policyTypeKey.getId()
474 + " is in use, it is referenced in policy type " + policyType.getId());
478 if (ToscaUtils.doPoliciesExist(serviceTemplate)) {
479 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
480 if (policyTypeKey.equals(policy.getType())) {
481 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, POLICY_TYPE
482 + policyTypeKey.getId() + " is in use, it is referenced in policy " + policy.getId());
487 serviceTemplate.getPolicyTypes().getConceptMap().remove(policyTypeKey);
488 new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplate);
489 dao.delete(policyType4Deletion);
491 var deletedServiceTemplate = new JpaToscaServiceTemplate();
492 deletedServiceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
493 deletedServiceTemplate.getPolicyTypes().getConceptMap().put(policyTypeKey, policyType4Deletion);
495 LOGGER.debug("<-deletePolicyType: key={}, serviceTemplate={}", policyTypeKey, deletedServiceTemplate);
496 return deletedServiceTemplate;
502 * @param dao the DAO to use to access the database
503 * @param name the name of the policy to get, set to null to get all policy types
504 * @param version the version of the policy to get, set to null to get all versions
505 * @return the policies found
506 * @throws PfModelException on errors getting policies
508 public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
509 throws PfModelException {
510 LOGGER.debug("->getPolicies: name={}, version={}", name, version);
512 JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
514 if (!ToscaUtils.doPoliciesExist(dbServiceTemplate)) {
515 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
516 "policies for " + name + ":" + version + DO_NOT_EXIST);
519 JpaToscaServiceTemplate returnServiceTemplate = getCascadedPolicies(dbServiceTemplate, name, version);
521 LOGGER.debug("<-getPolicies: name={}, version={}, serviceTemplate={}", name, version, returnServiceTemplate);
522 return returnServiceTemplate;
526 * Get the cascaded policies for a policy name and version.
528 * @param dbServiceTemplate the service template to search for the cascaded policy
529 * @param name the policy name we are searching for
530 * @param version the policy version we are searching for
531 * @return a service template containing the cascaded policy
532 * @throws PfModelException on errors getting the policy
534 public JpaToscaServiceTemplate getCascadedPolicies(final JpaToscaServiceTemplate dbServiceTemplate,
535 final String name, final String version) throws PfModelException {
537 var serviceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
538 serviceTemplate.setDataTypes(new JpaToscaDataTypes());
539 serviceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
541 ToscaUtils.getEntityTree(serviceTemplate.getTopologyTemplate().getPolicies(), name, version);
543 if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
544 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
545 "policies for " + name + ":" + version + DO_NOT_EXIST);
548 var returnServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate);
549 returnServiceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
551 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().values()) {
552 JpaToscaServiceTemplate referencedEntitiesServiceTemplate =
553 getCascadedPolicyTypes(dbServiceTemplate, policy.getType().getName(), policy.getType().getVersion());
555 returnServiceTemplate.getTopologyTemplate().getPolicies().getConceptMap().put(policy.getKey(), policy);
556 returnServiceTemplate =
557 ToscaServiceTemplateUtils.addFragment(returnServiceTemplate, referencedEntitiesServiceTemplate);
560 return returnServiceTemplate;
566 * @param dao the DAO to use to access the database
567 * @param incomingServiceTemplate the service template containing the definitions of the new policies to be created.
568 * @return the TOSCA service template containing the policy types that were created
569 * @throws PfModelException on errors creating policies
571 public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
572 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
573 LOGGER.debug("->createPolicies: incomingServiceTemplate={}", incomingServiceTemplate);
575 ToscaUtils.assertPoliciesExist(incomingServiceTemplate);
577 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
579 LOGGER.debug("<-createPolicies: writtenServiceTemplate={}", writtenServiceTemplate);
580 return incomingServiceTemplate;
586 * @param dao the DAO to use to access the database
587 * @param serviceTemplate the service template containing the definitions of the policies to be updated.
588 * @return the TOSCA service template containing the policies that were updated
589 * @throws PfModelException on errors updating policies
591 public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
592 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
593 LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
595 ToscaUtils.assertPoliciesExist(serviceTemplate);
597 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
598 verifyPolicyTypeForPolicy(dao, policy);
602 // Return the created policy types
603 var returnPolicies = new JpaToscaPolicies();
604 returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
606 for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
607 returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
610 serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
612 LOGGER.debug("<-updatePolicies: serviceTemplate={}", serviceTemplate);
613 return serviceTemplate;
619 * @param dao the DAO to use to access the database
620 * @param policyKey the policy key
621 * @return the TOSCA service template containing the policies that were deleted
622 * @throws PfModelException on errors deleting policies
624 public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
625 throws PfModelException {
626 LOGGER.debug("->deletePolicy: key={}", policyKey);
628 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
630 if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
631 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no policies found");
634 JpaToscaPolicy policy4Deletion = serviceTemplate.getTopologyTemplate().getPolicies().get(policyKey);
635 if (policy4Deletion == null) {
636 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "policy " + policyKey.getId() + NOT_FOUND);
639 serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().remove(policyKey);
640 new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplate);
641 dao.delete(policy4Deletion);
643 var deletedServiceTemplate = new JpaToscaServiceTemplate();
644 deletedServiceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate());
645 deletedServiceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
646 deletedServiceTemplate.getTopologyTemplate().getPolicies().getConceptMap().put(policyKey, policy4Deletion);
648 LOGGER.debug("<-deletePolicy: key={}, serviceTempalate={}", policyKey, deletedServiceTemplate);
649 return deletedServiceTemplate;
654 * Get metadata of tosca node templates.
656 * @param dao the DAO to use to access the database
657 * @param name the name of the nodeTemplate to get, set to null to get all node templates
658 * @param version the version of the metadataSet to get, set to null to get all versions
659 * @return the list of maps with node template key and metadata values found
660 * @throws PfModelException on errors getting metadataSets
662 public List<Map<ToscaEntityKey, Map<String, Object>>> getNodeTemplateMetadata(
663 @NonNull final PfDao dao, final String name, final String version)
664 throws PfModelException {
665 LOGGER.debug("->getNodeTemplateMetadataSet: name={}, version={}", name, version);
667 List<Map<ToscaEntityKey, Map<String, Object>>> metadataSets = new ArrayList<>();
669 JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
671 //Return empty list if no node templates present in db
672 if (!ToscaUtils.doNodeTemplatesExist(dbServiceTemplate)) {
675 var returnServiceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
676 List<ToscaNodeTemplate> toscaNodeTemplates = new ArrayList<>();
677 returnServiceTemplate.getTopologyTemplate()
678 .getNodeTemplates().getConceptMap().forEach((key, value) -> toscaNodeTemplates.add(value
681 //Filter metadataSet for specific node template
682 if (name != null && version != null) {
683 var filterKey = new ToscaEntityKey(name, version);
684 toscaNodeTemplates.removeIf(entity -> !entity.getKey().equals(filterKey));
686 toscaNodeTemplates.forEach(e -> metadataSets.add(Map.of(e.getKey(), e.getMetadata())));
687 LOGGER.debug("<-getNodeTemplateMetadataSet: name={}, version={}, metadataSets={}", name, version,
694 * Get tosca node templates.
696 * @param dao the DAO to use to access the database
697 * @param name the name of the node template to get, set to null to get all node templates
698 * @param version the version of the node template to get, set to null to get all versions
699 * @return the node templates with the specified key
700 * @throws PfModelException on errors getting node templates
702 public JpaToscaNodeTemplates getToscaNodeTemplates(@NonNull final PfDao dao, final String name,
703 final String version)
704 throws PfModelException {
705 LOGGER.debug("->getNodeTemplate: name={}, version={}", name, version);
707 var nodeTemplates = new JpaToscaNodeTemplates();
709 JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
711 //Return empty if no nodeTemplates present in db
712 if (!ToscaUtils.doNodeTemplatesExist(dbServiceTemplate)) {
713 return nodeTemplates;
715 var returnServiceTemplate = new JpaToscaServiceTemplate(dbServiceTemplate);
716 nodeTemplates = returnServiceTemplate.getTopologyTemplate().getNodeTemplates();
718 //Filter specific nodeTemplates
719 if (name != null && version != null) {
720 var filterKey = new PfConceptKey(name, version);
721 nodeTemplates.getConceptMap().entrySet().removeIf(entity -> !entity.getKey().equals(filterKey));
723 LOGGER.debug("<-getNodeTemplateMetadataSet: name={}, version={}, nodeTemplates={}", name, version,
726 return nodeTemplates;
731 * Update tosca node template.
733 * @param dao the DAO to use to access the database
734 * @param serviceTemplate the service template containing the definitions of the node templates to be updated.
735 * @return the TOSCA service template containing the node templates that were updated
736 * @throws PfModelRuntimeException on errors updating node templates
738 public JpaToscaServiceTemplate updateToscaNodeTemplates(@NonNull final PfDao dao,
739 @NonNull final JpaToscaServiceTemplate serviceTemplate)
740 throws PfModelException {
741 LOGGER.debug("->updateToscaNodeTemplates: serviceTemplate={}", serviceTemplate);
743 ToscaUtils.assertNodeTemplatesExist(serviceTemplate);
744 for (JpaToscaNodeTemplate nodeTemplate : serviceTemplate.getTopologyTemplate().getNodeTemplates()
747 //verify if the node template is referenced in the metadata of created policies
748 assertNodeTemplateNotUsedInPolicy(dao, nodeTemplate.getName(), nodeTemplate.getVersion());
749 verifyNodeTypeInDbTemplate(dao, nodeTemplate);
751 dao.update(nodeTemplate);
753 // Return the service template with updated node templates
754 var updatedNodeTemplates = new JpaToscaNodeTemplates();
755 updatedNodeTemplates.setKey(serviceTemplate.getTopologyTemplate().getNodeTemplates().getKey());
757 for (PfConceptKey metadataSetKey : serviceTemplate.getTopologyTemplate().getNodeTemplates().getConceptMap()
759 updatedNodeTemplates.getConceptMap().put(metadataSetKey, dao.get(JpaToscaNodeTemplate.class,
762 serviceTemplate.getTopologyTemplate().setNodeTemplates(updatedNodeTemplates);
764 LOGGER.debug("<-updatedToscaNodeTemplates: serviceTemplate={}", serviceTemplate);
765 return serviceTemplate;
769 * Delete a tosca node template.
771 * @param dao the DAO to use to access the database
772 * @param nodeTemplateKey the node template key
773 * @return the TOSCA service template containing the node templates that were deleted
774 * @throws PfModelException on errors deleting node templates
776 public JpaToscaServiceTemplate deleteToscaNodeTemplate(@NonNull final PfDao dao,
777 @NonNull final PfConceptKey nodeTemplateKey)
778 throws PfModelException {
779 LOGGER.debug("->deleteToscaNodeTemplate: key={}", nodeTemplateKey);
781 JpaToscaServiceTemplate dbServiceTemplate = getServiceTemplate(dao);
783 if (!ToscaUtils.doNodeTemplatesExist(dbServiceTemplate)) {
784 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "no node templates found");
786 JpaToscaNodeTemplate nodeTemplate4Deletion = dbServiceTemplate.getTopologyTemplate().getNodeTemplates()
787 .get(nodeTemplateKey);
788 if (nodeTemplate4Deletion == null) {
789 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, "node template " + nodeTemplateKey.getId()
793 //Verify if the node template is referenced in the metadata of created policies
794 assertNodeTemplateNotUsedInPolicy(dao, nodeTemplateKey.getName(), nodeTemplateKey.getVersion());
796 dbServiceTemplate.getTopologyTemplate().getNodeTemplates().getConceptMap().remove(nodeTemplateKey);
797 new SimpleToscaServiceTemplateProvider().write(dao, dbServiceTemplate);
798 dao.delete(nodeTemplate4Deletion);
800 var deletedServiceTemplate = new JpaToscaServiceTemplate();
801 deletedServiceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate());
802 deletedServiceTemplate.getTopologyTemplate().setNodeTemplates(new JpaToscaNodeTemplates());
803 deletedServiceTemplate.getTopologyTemplate().getNodeTemplates().getConceptMap()
804 .put(nodeTemplateKey, nodeTemplate4Deletion);
806 LOGGER.debug("<-deleteToscaNodeTemplate: key={}, serviceTemplate={}", nodeTemplateKey, deletedServiceTemplate);
807 return deletedServiceTemplate;
811 * Write a node template to the database.
813 * @param dao the DAO to use to access the database
814 * @param serviceTemplate the service template to be written
815 * @return the service template created by this method
816 * @throws PfModelException on errors writing the metadataSets
818 public JpaToscaServiceTemplate createToscaNodeTemplates(@NonNull final PfDao dao,
819 @NonNull final JpaToscaServiceTemplate serviceTemplate)
820 throws PfModelException {
822 LOGGER.debug("->write: tosca nodeTemplates={}", serviceTemplate);
824 ToscaUtils.assertNodeTemplatesExist(serviceTemplate);
826 Optional<JpaToscaNodeTypes> nodeTypes = Optional.ofNullable(serviceTemplate.getNodeTypes());
827 for (JpaToscaNodeTemplate nodeTemplate : serviceTemplate.getTopologyTemplate().getNodeTemplates()
830 // verify node types in the db if mismatch/empty entities in the template
831 if (! (nodeTypes.isPresent() && nodeTypes.get().getKeys().contains(nodeTemplate.getType()))) {
832 verifyNodeTypeInDbTemplate(dao, nodeTemplate);
835 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, serviceTemplate);
836 LOGGER.debug("<-createdToscaNodeTemplates: writtenServiceTemplate={}", writtenServiceTemplate);
838 return serviceTemplate;
842 * Verify the policy type for a policy exists.
844 * @param dao the DAO to use to access policy types in the database
845 * @param policy the policy to check the policy type for
847 private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
848 PfConceptKey policyTypeKey = policy.getType();
850 JpaToscaPolicyType policyType = null;
852 if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
853 policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
855 if (policyType != null) {
856 policy.getType().setVersion(policyType.getKey().getVersion());
859 policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
862 if (policyType == null) {
863 String errorMessage =
864 POLICY_TYPE + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
865 throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, errorMessage);
870 * Verify the node type for a toscaNodeTemplate metadataSet.
872 * @param dao the DAO to use to access toscaNodeTemplate types in the database
873 * @param toscaNodeTemplate the toscaNodeTemplate to check the toscaNodeTemplate type for
875 private void verifyNodeTypeInDbTemplate(final PfDao dao, final JpaToscaNodeTemplate toscaNodeTemplate) throws
877 PfConceptKey nodeTypeKey = toscaNodeTemplate.getType();
879 JpaToscaNodeType nodeType = null;
881 nodeType = dao.get(JpaToscaNodeType.class, nodeTypeKey);
883 if (nodeType == null) {
884 String errorMessage =
885 "NODE_TYPE " + nodeTypeKey + " for toscaNodeTemplate " + toscaNodeTemplate.getId()
887 throw new PfModelException(Response.Status.NOT_ACCEPTABLE, errorMessage);
892 * Get the latest version of the policy type for the given policy type name.
894 * @param dao the DAO to use to access policy types in the database
895 * @param policyTypeName the name of the policy type
896 * @return the latest policy type
898 private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
899 // Policy type version is not specified, get the latest version from the database
900 List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
902 if (CollectionUtils.isEmpty(jpaPolicyTypeList)) {
906 // Create a filter to get the latest version of the policy type
907 var pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
909 // FIlter the returned policy type list
910 List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
911 List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
913 // We should have one and only one returned entry
914 if (filterdPolicyTypeList.size() != 1) {
915 String errorMessage = "search for latest policy type " + policyTypeName + " returned more than one entry";
916 throw new PfModelRuntimeException(Response.Status.CONFLICT, errorMessage);
919 return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);
923 * Assert that the node template is not referenced in any Tosca policy.
925 * @param name the name of node template
926 * @param version the version of node template
927 * @throws PfModelException if node template referenced in a policy
929 private void assertNodeTemplateNotUsedInPolicy(PfDao dao, String name, String version)
930 throws PfModelException {
931 JpaToscaServiceTemplate dbTemplate;
933 //Retrieve all the policies from db, return if policies doesn't exist
934 dbTemplate = getPolicies(dao, null, null);
935 } catch (PfModelRuntimeException e) {
936 LOGGER.debug("Could not verify the node template reference in created policies ", e);
939 for (JpaToscaPolicy policy : dbTemplate.getTopologyTemplate().getPolicies().getConceptMap().values()) {
940 if (policy.getMetadata().getOrDefault("metadataSetName", "").equals(name)
941 && policy.getMetadata().getOrDefault("metadataSetVersion", "").equals(version)) {
942 throw new PfModelException(Response.Status.NOT_ACCEPTABLE,
943 "Node template is in use, it is referenced in Tosca Policy " + policy.getName() + " version "
944 + policy.getVersion());