Migrate policy api startup & config, controller to springboot
[policy/api.git] / main / src / main / java / org / onap / policy / api / main / startstop / ApiDatabaseInitializer.java
index 3973e62..4aa2516 100644 (file)
@@ -2,7 +2,9 @@
  * ============LICENSE_START=======================================================
  * ONAP Policy API
  * ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.policy.api.main.startstop;
 
-import java.util.ArrayList;
-import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import org.onap.policy.api.main.config.PolicyPreloadConfig;
 import org.onap.policy.api.main.exception.PolicyApiException;
 import org.onap.policy.common.utils.coder.CoderException;
-import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.coder.StandardYamlCoder;
 import org.onap.policy.common.utils.resources.ResourceUtils;
 import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.provider.PolicyModelsProvider;
-import org.onap.policy.models.provider.PolicyModelsProviderFactory;
-import org.onap.policy.models.provider.PolicyModelsProviderParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaEntityFilter;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
 
 /**
  * This class creates initial policy types in the database.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  */
+@Component
+@ConditionalOnProperty(value = "database.initialize", havingValue = "true", matchIfMissing = true)
 public class ApiDatabaseInitializer {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ApiDatabaseInitializer.class);
 
-    private StandardCoder standardCoder;
-    private PolicyModelsProviderFactory factory;
-
-    private static final String[] PRELOAD_POLICYTYPES = {
-        "preloadedPolicyTypes/onap.policies.monitoring.cdap.tca.hi.lo.app.json",
-        "preloadedPolicyTypes/onap.policies.monitoring.dcaegen2.collectors.datafile.datafile-app-server.json",
-        "preloadedPolicyTypes/onap.policies.optimization.AffinityPolicy.json",
-        "preloadedPolicyTypes/onap.policies.optimization.DistancePolicy.json",
-        "preloadedPolicyTypes/onap.policies.optimization.HpaPolicy.json",
-        "preloadedPolicyTypes/onap.policies.optimization.OptimizationPolicy.json",
-        "preloadedPolicyTypes/onap.policies.optimization.PciPolicy.json",
-        "preloadedPolicyTypes/onap.policies.optimization.QueryPolicy.json",
-        "preloadedPolicyTypes/onap.policies.optimization.SubscriberPolicy.json",
-        "preloadedPolicyTypes/onap.policies.optimization.Vim_fit.json",
-        "preloadedPolicyTypes/onap.policies.optimization.VnfPolicy.json"
-    };
+    private static final StandardYamlCoder coder = new StandardYamlCoder();
 
-    /**
-     * Constructs the object.
-     */
-    public ApiDatabaseInitializer() {
-        factory = new PolicyModelsProviderFactory();
-        standardCoder = new StandardCoder();
+    @Autowired
+    PolicyModelsProvider policyModelsProvider;
+
+    @Autowired
+    PolicyPreloadConfig policyPreloadConfig;
+
+    @PostConstruct
+    public void loadData() throws PolicyApiException {
+        initializeApiDatabase(policyPreloadConfig.getPolicyTypes(), policyPreloadConfig.getPolicies());
     }
 
     /**
-     * Initializes database by preloading policy types.
+     * Initializes database by preloading policy types and policies.
      *
-     * @param policyModelsProviderParameters the database parameters
+     * @param policyTypes List of policy types to preload.
+     * @param policies List of policies to preload.
      * @throws PolicyApiException in case of errors.
      */
-    public void initializeApiDatabase(final PolicyModelsProviderParameters policyModelsProviderParameters)
-            throws PolicyApiException {
-
-        try (PolicyModelsProvider databaseProvider =
-                factory.createPolicyModelsProvider(policyModelsProviderParameters)) {
-            ToscaServiceTemplate policyTypes = new ToscaServiceTemplate();
-            policyTypes.setPolicyTypes(new ArrayList<Map<String,ToscaPolicyType>>());
-            policyTypes.setToscaDefinitionsVersion("tosca_simple_yaml_1_0_0");
-            for (String pt : PRELOAD_POLICYTYPES) {
-                String policyTypeAsString = ResourceUtils.getResourceAsString(pt);
-                if (policyTypeAsString == null) {
-                    throw new PolicyApiException("Preloading policy type cannot be found: " + pt);
-                }
-                ToscaServiceTemplate singlePolicyType = standardCoder.decode(policyTypeAsString,
-                        ToscaServiceTemplate.class);
-                if (singlePolicyType == null) {
-                    throw new PolicyApiException("Error deserializing policy type from file: " + pt);
-                }
-                // Consolidate policy types
-                for (Map<String, ToscaPolicyType> eachPolicyType : singlePolicyType.getPolicyTypes()) {
-                    policyTypes.getPolicyTypes().add(eachPolicyType);
-                }
+    public void initializeApiDatabase(final List<String> policyTypes, final List<String> policies)
+        throws PolicyApiException {
+        try {
+            if (alreadyExists()) {
+                LOGGER.warn("DB already contains policy data - skipping preload");
+                return;
             }
-            ToscaServiceTemplate createdPolicyTypes = databaseProvider.createPolicyTypes(policyTypes);
-            if (createdPolicyTypes == null) {
-                throw new PolicyApiException("Error preloading policy types: " + policyTypes);
-            } else {
-                LOGGER.debug("Created initial policy types in DB - {}", createdPolicyTypes);
-            }
-        } catch (final PfModelException | CoderException exp) {
+
+            var serviceTemplate = new ToscaServiceTemplate();
+            serviceTemplate.setDataTypes(new LinkedHashMap<>());
+            serviceTemplate.setPolicyTypes(new LinkedHashMap<>());
+            serviceTemplate.setToscaDefinitionsVersion("tosca_simple_yaml_1_1_0");
+
+            ToscaServiceTemplate createdPolicyTypes =
+                    preloadServiceTemplate(serviceTemplate, policyTypes, policyModelsProvider::createPolicyTypes);
+            preloadServiceTemplate(createdPolicyTypes, policies, policyModelsProvider::createPolicies);
+        } catch (final PolicyApiException | PfModelException | CoderException exp) {
             throw new PolicyApiException(exp);
         }
     }
-}
+
+    private boolean alreadyExists() throws PfModelException {
+        try {
+            ToscaServiceTemplate serviceTemplate =
+                    policyModelsProvider.getFilteredPolicyTypes(ToscaEntityFilter.<ToscaPolicyType>builder().build());
+            if (!serviceTemplate.getPolicyTypes().isEmpty()) {
+                return true;
+            }
+        } catch (PfModelRuntimeException e) {
+            LOGGER.trace("DB does not yet contain policy types", e);
+        }
+        return false;
+    }
+
+    private ToscaServiceTemplate preloadServiceTemplate(ToscaServiceTemplate serviceTemplate, List<String> entities,
+            FunctionWithEx<ToscaServiceTemplate, ToscaServiceTemplate> getter)
+            throws PolicyApiException, CoderException, PfModelException {
+
+        for (String entity : entities) {
+            var entityAsStringYaml = ResourceUtils.getResourceAsString(entity);
+            if (entityAsStringYaml == null) {
+                LOGGER.warn("Preloading entity cannot be found: {}", entity);
+                continue;
+            }
+
+            ToscaServiceTemplate singleEntity = coder.decode(entityAsStringYaml, ToscaServiceTemplate.class);
+            if (singleEntity == null) {
+                throw new PolicyApiException("Error deserializing entity from file: " + entity);
+            }
+
+            // Consolidate data types and policy types
+            if (singleEntity.getDataTypes() != null) {
+                serviceTemplate.getDataTypes().putAll(singleEntity.getDataTypes());
+            }
+            if (singleEntity.getPolicyTypes() != null) {
+                serviceTemplate.getPolicyTypes().putAll(singleEntity.getPolicyTypes());
+            }
+
+            // Consolidate policies
+            var topologyTemplate = singleEntity.getToscaTopologyTemplate();
+            if (topologyTemplate != null && topologyTemplate.getPolicies() != null) {
+                serviceTemplate.setToscaTopologyTemplate(new ToscaTopologyTemplate());
+                serviceTemplate.getToscaTopologyTemplate().setPolicies(new LinkedList<>());
+                serviceTemplate.getToscaTopologyTemplate().getPolicies()
+                        .addAll(singleEntity.getToscaTopologyTemplate().getPolicies());
+            }
+        }
+        // Preload the specified entities
+        ToscaServiceTemplate createdServiceTemplate = getter.apply(serviceTemplate);
+        LOGGER.debug("Created initial tosca service template in DB - {}", createdServiceTemplate);
+        return createdServiceTemplate;
+    }
+
+    @FunctionalInterface
+    protected interface FunctionWithEx<T, R> {
+        public R apply(T value) throws PfModelException;
+    }
+}
\ No newline at end of file