2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2019-2021 Nordix Foundation.
7 * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * SPDX-License-Identifier: Apache-2.0
22 * ============LICENSE_END=========================================================
25 package org.onap.policy.api.main.startstop;
27 import java.util.LinkedHashMap;
28 import java.util.LinkedList;
29 import java.util.List;
30 import javax.annotation.PostConstruct;
31 import org.onap.policy.api.main.config.PolicyPreloadConfig;
32 import org.onap.policy.api.main.exception.PolicyApiException;
33 import org.onap.policy.common.utils.coder.CoderException;
34 import org.onap.policy.common.utils.coder.StandardYamlCoder;
35 import org.onap.policy.common.utils.resources.ResourceUtils;
36 import org.onap.policy.models.base.PfModelException;
37 import org.onap.policy.models.base.PfModelRuntimeException;
38 import org.onap.policy.models.provider.PolicyModelsProvider;
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntityFilter;
40 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45 import org.springframework.beans.factory.annotation.Autowired;
46 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
47 import org.springframework.stereotype.Component;
50 * This class creates initial policy types in the database.
52 * @author Chenfei Gao (cgao@research.att.com)
55 @ConditionalOnProperty(value = "database.initialize", havingValue = "true", matchIfMissing = true)
56 public class ApiDatabaseInitializer {
58 private static final Logger LOGGER = LoggerFactory.getLogger(ApiDatabaseInitializer.class);
60 private static final StandardYamlCoder coder = new StandardYamlCoder();
63 PolicyModelsProvider policyModelsProvider;
66 PolicyPreloadConfig policyPreloadConfig;
69 public void loadData() throws PolicyApiException {
70 initializeApiDatabase(policyPreloadConfig.getPolicyTypes(), policyPreloadConfig.getPolicies());
74 * Initializes database by preloading policy types and policies.
76 * @param policyTypes List of policy types to preload.
77 * @param policies List of policies to preload.
78 * @throws PolicyApiException in case of errors.
80 public void initializeApiDatabase(final List<String> policyTypes, final List<String> policies)
81 throws PolicyApiException {
83 if (alreadyExists()) {
84 LOGGER.warn("DB already contains policy data - skipping preload");
88 var serviceTemplate = new ToscaServiceTemplate();
89 serviceTemplate.setDataTypes(new LinkedHashMap<>());
90 serviceTemplate.setPolicyTypes(new LinkedHashMap<>());
91 serviceTemplate.setToscaDefinitionsVersion("tosca_simple_yaml_1_1_0");
93 ToscaServiceTemplate createdPolicyTypes =
94 preloadServiceTemplate(serviceTemplate, policyTypes, policyModelsProvider::createPolicyTypes);
95 preloadServiceTemplate(createdPolicyTypes, policies, policyModelsProvider::createPolicies);
96 } catch (final PolicyApiException | PfModelException | CoderException exp) {
97 throw new PolicyApiException(exp);
101 private boolean alreadyExists() throws PfModelException {
103 ToscaServiceTemplate serviceTemplate =
104 policyModelsProvider.getFilteredPolicyTypes(ToscaEntityFilter.<ToscaPolicyType>builder().build());
105 if (!serviceTemplate.getPolicyTypes().isEmpty()) {
108 } catch (PfModelRuntimeException e) {
109 LOGGER.trace("DB does not yet contain policy types", e);
114 private ToscaServiceTemplate preloadServiceTemplate(ToscaServiceTemplate serviceTemplate, List<String> entities,
115 FunctionWithEx<ToscaServiceTemplate, ToscaServiceTemplate> getter)
116 throws PolicyApiException, CoderException, PfModelException {
118 for (String entity : entities) {
119 var entityAsStringYaml = ResourceUtils.getResourceAsString(entity);
120 if (entityAsStringYaml == null) {
121 LOGGER.warn("Preloading entity cannot be found: {}", entity);
125 ToscaServiceTemplate singleEntity = coder.decode(entityAsStringYaml, ToscaServiceTemplate.class);
126 if (singleEntity == null) {
127 throw new PolicyApiException("Error deserializing entity from file: " + entity);
130 // Consolidate data types and policy types
131 if (singleEntity.getDataTypes() != null) {
132 serviceTemplate.getDataTypes().putAll(singleEntity.getDataTypes());
134 if (singleEntity.getPolicyTypes() != null) {
135 serviceTemplate.getPolicyTypes().putAll(singleEntity.getPolicyTypes());
138 // Consolidate policies
139 var topologyTemplate = singleEntity.getToscaTopologyTemplate();
140 if (topologyTemplate != null && topologyTemplate.getPolicies() != null) {
141 serviceTemplate.setToscaTopologyTemplate(new ToscaTopologyTemplate());
142 serviceTemplate.getToscaTopologyTemplate().setPolicies(new LinkedList<>());
143 serviceTemplate.getToscaTopologyTemplate().getPolicies()
144 .addAll(singleEntity.getToscaTopologyTemplate().getPolicies());
147 // Preload the specified entities
148 ToscaServiceTemplate createdServiceTemplate = getter.apply(serviceTemplate);
149 LOGGER.debug("Created initial tosca service template in DB - {}", createdServiceTemplate);
150 return createdServiceTemplate;
154 protected interface FunctionWithEx<T, R> {
155 public R apply(T value) throws PfModelException;