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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.models.tosca.simple.provider;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.List;
27 import javax.ws.rs.core.Response;
29 import lombok.NonNull;
31 import org.apache.commons.collections4.CollectionUtils;
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.base.PfValidationResult;
39 import org.onap.policy.models.dao.PfDao;
40 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType;
41 import org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes;
42 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies;
43 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy;
44 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType;
45 import org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes;
46 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
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;
53 * This class provides the provision of information on TOSCA concepts in the database to callers.
55 * @author Liam Fallon (liam.fallon@est.tech)
57 public class SimpleToscaProvider {
58 private static final Logger LOGGER = LoggerFactory.getLogger(SimpleToscaProvider.class);
60 // Recurring string constants
61 private static final String SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE = "service template not found in database";
62 private static final String DO_NOT_EXIST = " do not exist";
65 * Get Service Template.
67 * @param dao the DAO to use to access the database
68 * @return the service template
69 * @throws PfModelException on errors getting the service template
71 public JpaToscaServiceTemplate getServiceTemplate(@NonNull final PfDao dao) throws PfModelException {
72 LOGGER.debug("->getServiceTemplate");
74 JpaToscaServiceTemplate serviceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
75 if (serviceTemplate == null) {
76 throw new PfModelRuntimeException(Response.Status.NOT_FOUND, SERVICE_TEMPLATE_NOT_FOUND_IN_DATABASE);
79 LOGGER.debug("<-getServiceTemplate: serviceTemplate={}", serviceTemplate);
80 return serviceTemplate;
84 * Append a service template fragment to the service template in the database.
86 * @param dao the DAO to use to access the database
87 * @param incomingServiceTemplateFragment the service template containing the definition of the entities to be
89 * @return the TOSCA service template in the database after the operation
90 * @throws PfModelException on errors appending a service template to the template in the database
92 public JpaToscaServiceTemplate appendToServiceTemplate(@NonNull final PfDao dao,
93 @NonNull final JpaToscaServiceTemplate incomingServiceTemplateFragment) throws PfModelException {
94 LOGGER.debug("->appendServiceTemplateFragment: incomingServiceTemplateFragment={}",
95 incomingServiceTemplateFragment);
97 JpaToscaServiceTemplate dbServiceTemplate = new SimpleToscaServiceTemplateProvider().read(dao);
99 JpaToscaServiceTemplate serviceTemplateToWrite;
100 if (dbServiceTemplate == null) {
101 serviceTemplateToWrite = incomingServiceTemplateFragment;
103 serviceTemplateToWrite =
104 ToscaServiceTemplateUtils.addFragment(dbServiceTemplate, incomingServiceTemplateFragment);
107 PfValidationResult result = serviceTemplateToWrite.validate(new PfValidationResult());
108 if (!result.isValid()) {
109 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, result.toString());
112 new SimpleToscaServiceTemplateProvider().write(dao, serviceTemplateToWrite);
114 LOGGER.debug("<-appendServiceTemplateFragment: returnServiceTempalate={}", serviceTemplateToWrite);
115 return serviceTemplateToWrite;
121 * @param dao the DAO to use to access the database
122 * @param name the name of the data type to get, set to null to get all policy types
123 * @param version the version of the data type to get, set to null to get all versions
124 * @return the data types found
125 * @throws PfModelException on errors getting data types
127 public JpaToscaServiceTemplate getDataTypes(@NonNull final PfDao dao, final String name, final String version)
128 throws PfModelException {
129 LOGGER.debug("->getDataTypes: name={}, version={}", name, version);
131 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
133 if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
134 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
135 "data types for " + name + ":" + version + DO_NOT_EXIST);
138 serviceTemplate.setPolicyTypes(null);
139 serviceTemplate.setTopologyTemplate(null);
141 ToscaUtils.getEntityTree(serviceTemplate.getDataTypes(), name, version);
143 if (!ToscaUtils.doDataTypesExist(serviceTemplate)) {
144 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
145 "data types for " + name + ":" + version + DO_NOT_EXIST);
148 for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getConceptMap().values()) {
149 Collection<PfConceptKey> referencedDataTypeKeys = dataType.getReferencedDataTypes();
151 for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
152 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate =
153 getDataTypes(dao, referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
156 ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeEntityTreeServiceTemplate);
160 LOGGER.debug("<-getDataTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
161 return serviceTemplate;
167 * @param dao the DAO to use to access the database
168 * @param incomingServiceTemplate the service template containing the definition of the data types to be created
169 * @return the TOSCA service template containing the created data types
170 * @throws PfModelException on errors creating data types
172 public JpaToscaServiceTemplate createDataTypes(@NonNull final PfDao dao,
173 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
174 LOGGER.debug("->createDataTypes: incomingServiceTemplate={}", incomingServiceTemplate);
176 ToscaUtils.assertDataTypesExist(incomingServiceTemplate);
178 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
180 LOGGER.debug("<-createDataTypes: returnServiceTempalate={}", writtenServiceTemplate);
181 return writtenServiceTemplate;
187 * @param dao the DAO to use to access the database
188 * @param serviceTemplate the service template containing the definition of the data types to be modified
189 * @return the TOSCA service template containing the modified data types
190 * @throws PfModelException on errors updating Data types
192 public JpaToscaServiceTemplate updateDataTypes(@NonNull final PfDao dao,
193 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
194 LOGGER.debug("->updateDataTypes: serviceTempalate={}", serviceTemplate);
196 ToscaUtils.assertDataTypesExist(serviceTemplate);
198 for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
199 dao.update(dataType);
202 // Return the created data types
203 JpaToscaDataTypes returnDataTypes = new JpaToscaDataTypes();
205 for (PfConceptKey dataTypeKey : serviceTemplate.getDataTypes().getConceptMap().keySet()) {
206 returnDataTypes.getConceptMap().put(dataTypeKey, dao.get(JpaToscaDataType.class, dataTypeKey));
209 JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
210 returnServiceTemplate.setDataTypes(returnDataTypes);
212 LOGGER.debug("<-updateDataTypes: returnServiceTempalate={}", returnServiceTemplate);
213 return returnServiceTemplate;
219 * @param dao the DAO to use to access the database
220 * @param dataTypeKey the data type key for the Data types to be deleted, if the version of the key is null, all
221 * versions of the data type are deleted.
222 * @return the TOSCA service template containing the data types that were deleted
223 * @throws PfModelException on errors deleting data types
225 public JpaToscaServiceTemplate deleteDataType(@NonNull final PfDao dao, @NonNull final PfConceptKey dataTypeKey)
226 throws PfModelException {
227 LOGGER.debug("->deleteDataType: key={}", dataTypeKey);
229 JpaToscaServiceTemplate serviceTemplate = getDataTypes(dao, dataTypeKey.getName(), dataTypeKey.getVersion());
231 dao.delete(JpaToscaDataType.class, dataTypeKey);
233 LOGGER.debug("<-deleteDataType: key={}, serviceTempalate={}", dataTypeKey, serviceTemplate);
234 return serviceTemplate;
240 * @param dao the DAO to use to access the database
241 * @param name the name of the policy type to get, set to null to get all policy types
242 * @param version the version of the policy type to get, set to null to get all versions
243 * @return the policy types found
244 * @throws PfModelException on errors getting policy types
246 public JpaToscaServiceTemplate getPolicyTypes(@NonNull final PfDao dao, final String name, final String version)
247 throws PfModelException {
248 LOGGER.debug("->getPolicyTypes: name={}, version={}", name, version);
250 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
252 serviceTemplate.setDataTypes(null);
253 serviceTemplate.setTopologyTemplate(null);
255 if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
256 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
257 "policy types for " + name + ":" + version + DO_NOT_EXIST);
260 ToscaUtils.getEntityTree(serviceTemplate.getPolicyTypes(), name, version);
262 if (!ToscaUtils.doPolicyTypesExist(serviceTemplate)) {
263 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
264 "policy types for " + name + ":" + version + DO_NOT_EXIST);
267 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getConceptMap().values()) {
268 Collection<PfConceptKey> referencedDataTypeKeys = policyType.getReferencedDataTypes();
270 for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
271 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate =
272 getDataTypes(dao, referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
275 ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeEntityTreeServiceTemplate);
279 LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
280 return serviceTemplate;
284 * Create policy types.
286 * @param dao the DAO to use to access the database
287 * @param incomingServiceTemplate the service template containing the definition of the policy types to be created
288 * @return the TOSCA service template containing the created policy types
289 * @throws PfModelException on errors creating policy types
291 public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
292 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
293 LOGGER.debug("->createPolicyTypes: serviceTempalate={}", incomingServiceTemplate);
295 ToscaUtils.assertPolicyTypesExist(incomingServiceTemplate);
297 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
299 LOGGER.debug("<-createPolicyTypes: returnServiceTempalate={}", writtenServiceTemplate);
300 return writtenServiceTemplate;
304 * Update policy types.
306 * @param dao the DAO to use to access the database
307 * @param serviceTemplate the service template containing the definition of the policy types to be modified
308 * @return the TOSCA service template containing the modified policy types
309 * @throws PfModelException on errors updating policy types
311 public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
312 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
313 LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
315 ToscaUtils.assertPolicyTypesExist(serviceTemplate);
317 // Update the data types on the policy type
318 if (ToscaUtils.doDataTypesExist(serviceTemplate)) {
319 updateDataTypes(dao, serviceTemplate);
322 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
323 dao.update(policyType);
326 // Return the created policy types
327 JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
329 for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
330 returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
333 JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
334 returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
336 LOGGER.debug("<-updatePolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
337 return returnServiceTemplate;
341 * Delete policy types.
343 * @param dao the DAO to use to access the database
344 * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
345 * all versions of the policy type are deleted.
346 * @return the TOSCA service template containing the policy types that were deleted
347 * @throws PfModelException on errors deleting policy types
349 public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
350 throws PfModelException {
351 LOGGER.debug("->deletePolicyType: key={}", policyTypeKey);
353 JpaToscaServiceTemplate serviceTemplate =
354 getPolicyTypes(dao, policyTypeKey.getName(), policyTypeKey.getVersion());
356 dao.delete(JpaToscaPolicyType.class, policyTypeKey);
358 LOGGER.debug("<-deletePolicyType: key={}, serviceTempalate={}", policyTypeKey, serviceTemplate);
359 return serviceTemplate;
365 * @param dao the DAO to use to access the database
366 * @param name the name of the policy to get, set to null to get all policy types
367 * @param version the version of the policy to get, set to null to get all versions
368 * @return the policies found
369 * @throws PfModelException on errors getting policies
371 public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
372 throws PfModelException {
373 LOGGER.debug("->getPolicies: name={}, version={}", name, version);
375 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
377 if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
378 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
379 "policies for " + name + ":" + version + DO_NOT_EXIST);
382 ToscaUtils.getEntityTree(serviceTemplate.getTopologyTemplate().getPolicies(), name, version);
384 if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
385 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
386 "policies for " + name + ":" + version + DO_NOT_EXIST);
389 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().values()) {
390 if (policy.getDerivedFrom() != null) {
391 JpaToscaServiceTemplate referencedEntitiesServiceTemplate =
392 getPolicyTypes(dao, policy.getDerivedFrom().getName(), policy.getDerivedFrom().getVersion());
395 ToscaServiceTemplateUtils.addFragment(serviceTemplate, referencedEntitiesServiceTemplate);
399 LOGGER.debug("<-getPolicies: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
400 return serviceTemplate;
406 * @param dao the DAO to use to access the database
407 * @param incomingServiceTemplate the service template containing the definitions of the new policies to be created.
408 * @return the TOSCA service template containing the policy types that were created
409 * @throws PfModelException on errors creating policies
411 public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
412 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
413 LOGGER.debug("->createPolicies: incomingServiceTemplate={}", incomingServiceTemplate);
415 ToscaUtils.assertPoliciesExist(incomingServiceTemplate);
417 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
419 LOGGER.debug("<-createPolicies: serviceTemplate={}", writtenServiceTemplate);
420 return writtenServiceTemplate;
426 * @param dao the DAO to use to access the database
427 * @param serviceTemplate the service template containing the definitions of the policies to be updated.
428 * @return the TOSCA service template containing the policies that were updated
429 * @throws PfModelException on errors updating policies
431 public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
432 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
433 LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
435 ToscaUtils.assertPoliciesExist(serviceTemplate);
437 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
438 verifyPolicyTypeForPolicy(dao, policy);
442 // Return the created policy types
443 JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
444 returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
446 for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
447 returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
450 serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
452 LOGGER.debug("<-updatePolicies: serviceTemplate={}", serviceTemplate);
453 return serviceTemplate;
459 * @param dao the DAO to use to access the database
460 * @param policyKey the policy key
461 * @return the TOSCA service template containing the policies that were deleted
462 * @throws PfModelException on errors deleting policies
464 public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
465 throws PfModelException {
466 LOGGER.debug("->deletePolicy: key={}", policyKey);
468 JpaToscaServiceTemplate serviceTemplate = getPolicies(dao, policyKey.getName(), policyKey.getVersion());
470 dao.delete(JpaToscaPolicy.class, policyKey);
472 LOGGER.debug("<-deletePolicy: key={}, serviceTempalate={}", policyKey, serviceTemplate);
473 return serviceTemplate;
477 * Verify the policy type for a policy exists.
479 * @param dao the DAO to use to access policy types in the database
480 * @param policy the policy to check the policy type for
482 private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
483 PfConceptKey policyTypeKey = policy.getType();
485 JpaToscaPolicyType policyType = null;
487 if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
488 policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
490 if (policyType != null) {
491 policy.getType().setVersion(policyType.getKey().getVersion());
494 policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
497 if (policyType == null) {
498 String errorMessage =
499 "policy type " + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
500 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
505 * Get the latest version of the policy type for the given policy type name.
507 * @param dao the DAO to use to access policy types in the database
508 * @param policyTypeName the name of the policy type
509 * @return the latest policy type
511 private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
512 // Policy type version is not specified, get the latest version from the database
513 List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
515 if (CollectionUtils.isEmpty(jpaPolicyTypeList)) {
519 // Create a filter to get the latest version of the policy type
520 PfConceptFilter pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
522 // FIlter the returned policy type list
523 List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
524 List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
526 // We should have one and only one returned entry
527 if (filterdPolicyTypeList.size() != 1) {
528 String errorMessage = "search for latest policy type " + policyTypeName + " returned more than one entry";
529 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
532 return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);