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.LinkedHashMap;
25 import java.util.List;
28 import javax.ws.rs.core.Response;
30 import lombok.NonNull;
32 import org.apache.commons.collections4.CollectionUtils;
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.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.simple.concepts.JpaToscaTopologyTemplate;
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);
63 * @param dao the DAO to use to access the database
64 * @param name the name of the data type to get, set to null to get all policy types
65 * @param version the version of the data type to get, set to null to get all versions
66 * @return the data types found
67 * @throws PfModelException on errors getting data types
69 public JpaToscaServiceTemplate getDataTypes(@NonNull final PfDao dao, final String name, final String version)
70 throws PfModelException {
71 LOGGER.debug("->getDataTypes: name={}, version={}", name, version);
73 // Create the structure of the TOSCA service template to contain the data type
74 JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate();
75 serviceTemplate.setDataTypes(new JpaToscaDataTypes());
77 // Add the data type to the TOSCA service template
78 List<JpaToscaDataType> jpaDataTypeList = dao.getFiltered(JpaToscaDataType.class, name, version);
79 serviceTemplate.getDataTypes().getConceptMap().putAll(asConceptMap(jpaDataTypeList));
81 LOGGER.debug("<-getDataTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
82 return serviceTemplate;
88 * @param dao the DAO to use to access the database
89 * @param serviceTemplate the service template containing the definition of the data types to be created
90 * @return the TOSCA service template containing the created data types
91 * @throws PfModelException on errors creating data types
93 public JpaToscaServiceTemplate createDataTypes(@NonNull final PfDao dao,
94 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
95 LOGGER.debug("->createDataTypes: serviceTempalate={}", serviceTemplate);
97 ToscaUtils.assertDataTypesExist(serviceTemplate);
99 for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
100 dao.create(dataType);
103 // Return the created Data types
104 JpaToscaDataTypes returnDataTypes = new JpaToscaDataTypes();
106 for (PfConceptKey dataTypeKey : serviceTemplate.getDataTypes().getConceptMap().keySet()) {
107 returnDataTypes.getConceptMap().put(dataTypeKey, dao.get(JpaToscaDataType.class, dataTypeKey));
110 JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
111 returnServiceTemplate.setDataTypes(returnDataTypes);
113 LOGGER.debug("<-createDataTypes: returnServiceTempalate={}", returnServiceTemplate);
114 return returnServiceTemplate;
120 * @param dao the DAO to use to access the database
121 * @param serviceTemplate the service template containing the definition of the data types to be modified
122 * @return the TOSCA service template containing the modified data types
123 * @throws PfModelException on errors updating Data types
125 public JpaToscaServiceTemplate updateDataTypes(@NonNull final PfDao dao,
126 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
127 LOGGER.debug("->updateDataTypes: serviceTempalate={}", serviceTemplate);
129 ToscaUtils.assertDataTypesExist(serviceTemplate);
131 for (JpaToscaDataType dataType : serviceTemplate.getDataTypes().getAll(null)) {
132 dao.update(dataType);
135 // Return the created data types
136 JpaToscaDataTypes returnDataTypes = new JpaToscaDataTypes();
138 for (PfConceptKey dataTypeKey : serviceTemplate.getDataTypes().getConceptMap().keySet()) {
139 returnDataTypes.getConceptMap().put(dataTypeKey, dao.get(JpaToscaDataType.class, dataTypeKey));
142 JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
143 returnServiceTemplate.setDataTypes(returnDataTypes);
145 LOGGER.debug("<-updateDataTypes: returnServiceTempalate={}", returnServiceTemplate);
146 return returnServiceTemplate;
152 * @param dao the DAO to use to access the database
153 * @param dataTypeKey the data type key for the Data types to be deleted, if the version of the key is null, all
154 * versions of the data type are deleted.
155 * @return the TOSCA service template containing the data types that were deleted
156 * @throws PfModelException on errors deleting data types
158 public JpaToscaServiceTemplate deleteDataType(@NonNull final PfDao dao, @NonNull final PfConceptKey dataTypeKey)
159 throws PfModelException {
160 LOGGER.debug("->deleteDataType: key={}", dataTypeKey);
162 JpaToscaServiceTemplate serviceTemplate = getDataTypes(dao, dataTypeKey.getName(), dataTypeKey.getVersion());
164 dao.delete(JpaToscaDataType.class, dataTypeKey);
166 LOGGER.debug("<-deleteDataType: key={}, serviceTempalate={}", dataTypeKey, serviceTemplate);
167 return serviceTemplate;
173 * @param dao the DAO to use to access the database
174 * @param name the name of the policy type to get, set to null to get all policy types
175 * @param version the version of the policy type to get, set to null to get all versions
176 * @return the policy types found
177 * @throws PfModelException on errors getting policy types
179 public JpaToscaServiceTemplate getPolicyTypes(@NonNull final PfDao dao, final String name, final String version)
180 throws PfModelException {
181 LOGGER.debug("->getPolicyTypes: name={}, version={}", name, version);
183 // Create the structure of the TOSCA service template to contain the policy type
184 JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate();
185 serviceTemplate.setPolicyTypes(new JpaToscaPolicyTypes());
187 // Add the policy type to the TOSCA service template
188 List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, name, version);
189 serviceTemplate.getPolicyTypes().getConceptMap().putAll(asConceptMap(jpaPolicyTypeList));
191 // Return all data types
192 // TODO: In an upcoming review, return just the data types used by the policy types on the policy type list
193 List<JpaToscaDataType> jpaDataTypeList = dao.getFiltered(JpaToscaDataType.class, null, null);
194 if (!CollectionUtils.isEmpty(jpaDataTypeList)) {
195 serviceTemplate.setDataTypes(new JpaToscaDataTypes());
196 serviceTemplate.getDataTypes().getConceptMap().putAll(asConceptMap(jpaDataTypeList));
199 LOGGER.debug("<-getPolicyTypes: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
200 return serviceTemplate;
204 * Create policy types.
206 * @param dao the DAO to use to access the database
207 * @param serviceTemplate the service template containing the definition of the policy types to be created
208 * @return the TOSCA service template containing the created policy types
209 * @throws PfModelException on errors creating policy types
211 public JpaToscaServiceTemplate createPolicyTypes(@NonNull final PfDao dao,
212 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
213 LOGGER.debug("->createPolicyTypes: serviceTempalate={}", serviceTemplate);
215 ToscaUtils.assertPolicyTypesExist(serviceTemplate);
217 // Create the data types on the policy type
218 if (ToscaUtils.doDataTypesExist(serviceTemplate)) {
219 createDataTypes(dao, serviceTemplate);
222 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
223 dao.create(policyType);
226 // Return the created policy types
227 JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
229 for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
230 returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
233 JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
234 returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
236 LOGGER.debug("<-createPolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
237 return returnServiceTemplate;
241 * Update policy types.
243 * @param dao the DAO to use to access the database
244 * @param serviceTemplate the service template containing the definition of the policy types to be modified
245 * @return the TOSCA service template containing the modified policy types
246 * @throws PfModelException on errors updating policy types
248 public JpaToscaServiceTemplate updatePolicyTypes(@NonNull final PfDao dao,
249 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
250 LOGGER.debug("->updatePolicyTypes: serviceTempalate={}", serviceTemplate);
252 ToscaUtils.assertPolicyTypesExist(serviceTemplate);
254 // Update the data types on the policy type
255 if (ToscaUtils.doDataTypesExist(serviceTemplate)) {
256 updateDataTypes(dao, serviceTemplate);
259 for (JpaToscaPolicyType policyType : serviceTemplate.getPolicyTypes().getAll(null)) {
260 dao.update(policyType);
263 // Return the created policy types
264 JpaToscaPolicyTypes returnPolicyTypes = new JpaToscaPolicyTypes();
266 for (PfConceptKey policyTypeKey : serviceTemplate.getPolicyTypes().getConceptMap().keySet()) {
267 returnPolicyTypes.getConceptMap().put(policyTypeKey, dao.get(JpaToscaPolicyType.class, policyTypeKey));
270 JpaToscaServiceTemplate returnServiceTemplate = new JpaToscaServiceTemplate();
271 returnServiceTemplate.setPolicyTypes(returnPolicyTypes);
273 LOGGER.debug("<-updatePolicyTypes: returnServiceTempalate={}", returnServiceTemplate);
274 return returnServiceTemplate;
278 * Delete policy types.
280 * @param dao the DAO to use to access the database
281 * @param policyTypeKey the policy type key for the policy types to be deleted, if the version of the key is null,
282 * all versions of the policy type are deleted.
283 * @return the TOSCA service template containing the policy types that were deleted
284 * @throws PfModelException on errors deleting policy types
286 public JpaToscaServiceTemplate deletePolicyType(@NonNull final PfDao dao, @NonNull final PfConceptKey policyTypeKey)
287 throws PfModelException {
288 LOGGER.debug("->deletePolicyType: key={}", policyTypeKey);
290 JpaToscaServiceTemplate serviceTemplate =
291 getPolicyTypes(dao, policyTypeKey.getName(), policyTypeKey.getVersion());
293 dao.delete(JpaToscaPolicyType.class, policyTypeKey);
295 LOGGER.debug("<-deletePolicyType: key={}, serviceTempalate={}", policyTypeKey, serviceTemplate);
296 return serviceTemplate;
302 * @param dao the DAO to use to access the database
303 * @param name the name of the policy to get, set to null to get all policy types
304 * @param version the version of the policy to get, set to null to get all versions
305 * @return the policies found
306 * @throws PfModelException on errors getting policies
308 public JpaToscaServiceTemplate getPolicies(@NonNull final PfDao dao, final String name, final String version)
309 throws PfModelException {
310 LOGGER.debug("->getPolicies: name={}, version={}", name, version);
312 // Create the structure of the TOSCA service template to contain the policy type
313 JpaToscaServiceTemplate serviceTemplate = new JpaToscaServiceTemplate();
314 serviceTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate());
315 serviceTemplate.getTopologyTemplate().setPolicies(new JpaToscaPolicies());
317 // Add the policy type to the TOSCA service template
318 List<JpaToscaPolicy> jpaPolicyList = dao.getFiltered(JpaToscaPolicy.class, name, version);
319 serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().putAll(asConceptMap(jpaPolicyList));
321 LOGGER.debug("<-getPolicies: name={}, version={}, serviceTemplate={}", name, version, serviceTemplate);
322 return serviceTemplate;
328 * @param dao the DAO to use to access the database
329 * @param serviceTemplate the service template containing the definitions of the new policies to be created.
330 * @return the TOSCA service template containing the policy types that were created
331 * @throws PfModelException on errors creating policies
333 public JpaToscaServiceTemplate createPolicies(@NonNull final PfDao dao,
334 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
335 LOGGER.debug("->createPolicies: serviceTempalate={}", serviceTemplate);
337 ToscaUtils.assertPoliciesExist(serviceTemplate);
339 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
340 verifyPolicyTypeForPolicy(dao, policy);
344 // Return the created policy types
345 JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
346 returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
348 for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
349 returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
352 serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
354 LOGGER.debug("<-createPolicies: serviceTemplate={}", serviceTemplate);
355 return serviceTemplate;
361 * @param dao the DAO to use to access the database
362 * @param serviceTemplate the service template containing the definitions of the policies to be updated.
363 * @return the TOSCA service template containing the policies that were updated
364 * @throws PfModelException on errors updating policies
366 public JpaToscaServiceTemplate updatePolicies(@NonNull final PfDao dao,
367 @NonNull final JpaToscaServiceTemplate serviceTemplate) throws PfModelException {
368 LOGGER.debug("->updatePolicies: serviceTempalate={}", serviceTemplate);
370 ToscaUtils.assertPoliciesExist(serviceTemplate);
372 for (JpaToscaPolicy policy : serviceTemplate.getTopologyTemplate().getPolicies().getAll(null)) {
373 verifyPolicyTypeForPolicy(dao, policy);
377 // Return the created policy types
378 JpaToscaPolicies returnPolicies = new JpaToscaPolicies();
379 returnPolicies.setKey(serviceTemplate.getTopologyTemplate().getPolicies().getKey());
381 for (PfConceptKey policyKey : serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().keySet()) {
382 returnPolicies.getConceptMap().put(policyKey, dao.get(JpaToscaPolicy.class, policyKey));
385 serviceTemplate.getTopologyTemplate().setPolicies(returnPolicies);
387 LOGGER.debug("<-updatePolicies: serviceTemplate={}", serviceTemplate);
388 return serviceTemplate;
394 * @param dao the DAO to use to access the database
395 * @param policyKey the policy key
396 * @return the TOSCA service template containing the policies that were deleted
397 * @throws PfModelException on errors deleting policies
399 public JpaToscaServiceTemplate deletePolicy(@NonNull final PfDao dao, @NonNull final PfConceptKey policyKey)
400 throws PfModelException {
401 LOGGER.debug("->deletePolicy: key={}", policyKey);
403 JpaToscaServiceTemplate serviceTemplate = getPolicies(dao, policyKey.getName(), policyKey.getVersion());
405 dao.delete(JpaToscaPolicy.class, policyKey);
407 LOGGER.debug("<-deletePolicy: key={}, serviceTempalate={}", policyKey, serviceTemplate);
408 return serviceTemplate;
412 * Convert a list of concepts to a map of concepts.
414 * @param conceptList the concept list
415 * @return the concept map
417 private <T extends PfConcept> Map<PfConceptKey, T> asConceptMap(List<T> conceptList) {
418 Map<PfConceptKey, T> conceptMap = new LinkedHashMap<>();
419 for (T concept : conceptList) {
420 conceptMap.put((PfConceptKey) concept.getKey(), concept);
427 * Verify the policy type for a policy exists.
429 * @param dao the DAO to use to access policy types in the database
430 * @param policy the policy to check the policy type for
432 private void verifyPolicyTypeForPolicy(final PfDao dao, final JpaToscaPolicy policy) {
433 PfConceptKey policyTypeKey = policy.getType();
435 JpaToscaPolicyType policyType = null;
437 if (PfKey.NULL_KEY_VERSION.equals(policyTypeKey.getVersion())) {
438 policyType = getLatestPolicyTypeVersion(dao, policyTypeKey.getName());
440 if (policyType != null) {
441 policy.getType().setVersion(policyType.getKey().getVersion());
444 policyType = dao.get(JpaToscaPolicyType.class, policyTypeKey);
447 if (policyType == null) {
448 String errorMessage =
449 "policy type " + policyTypeKey.getId() + " for policy " + policy.getId() + " does not exist";
450 LOGGER.warn(errorMessage);
451 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
456 * Get the latest version of the policy type for the given policy type name.
458 * @param dao the DAO to use to access policy types in the database
459 * @param policyTypeName the name of the policy type
460 * @return the latest policy type
462 private JpaToscaPolicyType getLatestPolicyTypeVersion(final PfDao dao, final String policyTypeName) {
463 // Policy type version is not specified, get the latest version from the database
464 List<JpaToscaPolicyType> jpaPolicyTypeList = dao.getFiltered(JpaToscaPolicyType.class, policyTypeName, null);
466 if (CollectionUtils.isEmpty(jpaPolicyTypeList)) {
470 // Create a filter to get the latest version of the policy type
471 PfConceptFilter pfConceptFilter = PfConceptFilter.builder().version(PfConceptFilter.LATEST_VERSION).build();
473 // FIlter the returned policy type list
474 List<PfConcept> policyTypeKeyList = new ArrayList<>(jpaPolicyTypeList);
475 List<PfConcept> filterdPolicyTypeList = pfConceptFilter.filter(policyTypeKeyList);
477 // We should have one and only one returned entry
478 if (filterdPolicyTypeList.size() != 1) {
479 String errorMessage = "search for lates policy type " + policyTypeName + " returned more than one entry";
480 LOGGER.warn(errorMessage);
481 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
484 return (JpaToscaPolicyType) filterdPolicyTypeList.get(0);