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 JpaToscaServiceTemplate dataTypeServiceTemplate = new JpaToscaServiceTemplate(serviceTemplate);
268 dataTypeServiceTemplate.setPolicyTypes(null);
270 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getConceptMap().values()) {
271 Collection<PfConceptKey> referencedDataTypeKeys = policyType.getReferencedDataTypes();
273 for (PfConceptKey referencedDataTypeKey : referencedDataTypeKeys) {
274 JpaToscaServiceTemplate dataTypeEntityTreeServiceTemplate =
275 getDataTypes(dao, referencedDataTypeKey.getName(), referencedDataTypeKey.getVersion());
277 dataTypeServiceTemplate = ToscaServiceTemplateUtils.addFragment(dataTypeServiceTemplate,
278 dataTypeEntityTreeServiceTemplate);
282 serviceTemplate = ToscaServiceTemplateUtils.addFragment(serviceTemplate, dataTypeServiceTemplate);
284 LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
285 return serviceTemplate;
289 * Create policy types.
291 * @param dao the DAO to use to access the database
292 * @param incomingServiceTemplate the service template containing the definition of the policy types to be created
293 * @return the TOSCA service template containing the created policy types
294 * @throws PfModelException on errors creating policy types
296 public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
297 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
298 LOGGER.debug("->createPolicyTypes: serviceTempalate={}", incomingServiceTemplate);
300 ToscaUtils.assertPolicyTypesExist(incomingServiceTemplate);
302 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
304 LOGGER.debug("<-createPolicyTypes: returnServiceTempalate={}", writtenServiceTemplate);
305 return writtenServiceTemplate;
309 * Update policy types.
311 * @param dao the DAO to use to access the database
312 * @param serviceTemplate the service template containing the definition of the policy types to be modified
313 * @return the TOSCA service template containing the modified policy types
314 * @throws PfModelException on errors updating policy types
316 public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
317 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
318 LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
320 ToscaUtils.assertPolicyTypesExist(serviceTemplate);
322 // Update the data types on the policy type
323 if (ToscaUtils.doDataTypesExist(serviceTemplate)) {
324 updateDataTypes(dao, serviceTemplate);
327 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
328 dao.update(policyType);
331 // Return the created policy types
332 JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
334 for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
335 returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
338 JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
339 returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
341 LOGGER.debug("<-updatePolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
342 return returnServiceTemplate;
346 * Delete policy types.
348 * @param dao the DAO to use to access the database
349 * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
350 * all versions of the policy type are deleted.
351 * @return the TOSCA service template containing the policy types that were deleted
352 * @throws PfModelException on errors deleting policy types
354 public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
355 throws PfModelException {
356 LOGGER.debug("->deletePolicyType: key={}", policyTypeKey);
358 JpaToscaServiceTemplate serviceTemplate =
359 getPolicyTypes(dao, policyTypeKey.getName(), policyTypeKey.getVersion());
361 dao.delete(JpaToscaPolicyType.class, policyTypeKey);
363 LOGGER.debug("<-deletePolicyType: key={}, serviceTempalate={}", policyTypeKey, serviceTemplate);
364 return serviceTemplate;
370 * @param dao the DAO to use to access the database
371 * @param name the name of the policy to get, set to null to get all policy types
372 * @param version the version of the policy to get, set to null to get all versions
373 * @return the policies found
374 * @throws PfModelException on errors getting policies
376 public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
377 throws PfModelException {
378 LOGGER.debug("->getPolicies: name={}, version={}", name, version);
380 JpaToscaServiceTemplate serviceTemplate = getServiceTemplate(dao);
382 if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
383 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
384 "policies for " + name + ":" + version + DO_NOT_EXIST);
387 ToscaUtils.getEntityTree(serviceTemplate.getTopologyTemplate().getPolicies(), name, version);
389 if (!ToscaUtils.doPoliciesExist(serviceTemplate)) {
390 throw new PfModelRuntimeException(Response.Status.NOT_FOUND,
391 "policies for " + name + ":" + version + DO_NOT_EXIST);
394 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().values()) {
395 if (policy.getDerivedFrom() != null) {
396 JpaToscaServiceTemplate referencedEntitiesServiceTemplate =
397 getPolicyTypes(dao, policy.getDerivedFrom().getName(), policy.getDerivedFrom().getVersion());
400 ToscaServiceTemplateUtils.addFragment(serviceTemplate, referencedEntitiesServiceTemplate);
404 LOGGER.debug("<-getPolicies: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
405 return serviceTemplate;
411 * @param dao the DAO to use to access the database
412 * @param incomingServiceTemplate the service template containing the definitions of the new policies to be created.
413 * @return the TOSCA service template containing the policy types that were created
414 * @throws PfModelException on errors creating policies
416 public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
417 @NonNull final JpaToscaServiceTemplate incomingServiceTemplate) throws PfModelException {
418 LOGGER.debug("->createPolicies: incomingServiceTemplate={}", incomingServiceTemplate);
420 ToscaUtils.assertPoliciesExist(incomingServiceTemplate);
422 JpaToscaServiceTemplate writtenServiceTemplate = appendToServiceTemplate(dao, incomingServiceTemplate);
424 LOGGER.debug("<-createPolicies: serviceTemplate={}", writtenServiceTemplate);
425 return writtenServiceTemplate;
431 * @param dao the DAO to use to access the database
432 * @param serviceTemplate the service template containing the definitions of the policies to be updated.
433 * @return the TOSCA service template containing the policies that were updated
434 * @throws PfModelException on errors updating policies
436 public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
437 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
438 LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
440 ToscaUtils.assertPoliciesExist(serviceTemplate);
442 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
443 verifyPolicyTypeForPolicy(dao, policy);
447 // Return the created policy types
448 JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
449 returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
451 for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
452 returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
455 serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
457 LOGGER.debug("<-updatePolicies: serviceTemplate={}", serviceTemplate);
458 return serviceTemplate;
464 * @param dao the DAO to use to access the database
465 * @param policyKey the policy key
466 * @return the TOSCA service template containing the policies that were deleted
467 * @throws PfModelException on errors deleting policies
469 public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
470 throws PfModelException {
471 LOGGER.debug("->deletePolicy: key={}", policyKey);
473 JpaToscaServiceTemplate serviceTemplate = getPolicies(dao, policyKey.getName(), policyKey.getVersion());
475 dao.delete(JpaToscaPolicy.class, policyKey);
477 LOGGER.debug("<-deletePolicy: key={}, serviceTempalate={}", policyKey, serviceTemplate);
478 return serviceTemplate;
482 * Verify the policy type for a policy exists.
484 * @param dao the DAO to use to access policy types in the database
485 * @param policy the policy to check the policy type for
487 private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
488 PfConceptKey policyTypeKey = policy.getType();
490 JpaToscaPolicyType policyType = null;
492 if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
493 policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
495 if (policyType != null) {
496 policy.getType().setVersion(policyType.getKey().getVersion());
499 policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
502 if (policyType == null) {
503 String errorMessage =
504 "policy type " + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
505 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
510 * Get the latest version of the policy type for the given policy type name.
512 * @param dao the DAO to use to access policy types in the database
513 * @param policyTypeName the name of the policy type
514 * @return the latest policy type
516 private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
517 // Policy type version is not specified, get the latest version from the database
518 List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
520 if (CollectionUtils.isEmpty(jpaPolicyTypeList)) {
524 // Create a filter to get the latest version of the policy type
525 PfConceptFilter pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
527 // FIlter the returned policy type list
528 List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
529 List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
531 // We should have one and only one returned entry
532 if (filterdPolicyTypeList.size() != 1) {
533 String errorMessage = "search for latest policy type " + policyTypeName + " returned more than one entry";
534 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
537 return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);