/**
 * 
 */
package com.thinkbiganalytics.server.upgrade;

/*-
 * #%L
 * kylo-operational-metadata-upgrade-service
 * %%
 * Copyright (C) 2017 ThinkBig Analytics
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.thinkbiganalytics.KyloVersion;
import com.thinkbiganalytics.KyloVersionUtil;

/**
 * Performs all upgrade steps within a metadata transaction.
 */
public class KyloUpgrader {
    
    private static final Logger log = LoggerFactory.getLogger(KyloUpgrader.class);

    public static final String KYLO_UPGRADE = "kyloUpgrade";


    public void upgrade() {
        System.setProperty(SpringApplication.BANNER_LOCATION_PROPERTY, "upgrade-banner.txt");
        ConfigurableApplicationContext upgradeCxt = new SpringApplicationBuilder(KyloUpgradeConfig.class)
                        .web(true)
                        .profiles(KYLO_UPGRADE)
                        .run();
        try {
            KyloUpgradeService upgradeService = upgradeCxt.getBean(KyloUpgradeService.class);
            // Keep upgrading until upgrade() returns true, i.e. we are up-to-date;
            while (! upgradeService.upgradeNext());
        } finally {
            upgradeCxt.close();
        }
    }
    
    public boolean isUpgradeRequired() {
        KyloVersion buildVer = KyloVersionUtil.getBuildVersion();
        KyloVersion currentVer = getCurrentVersion();
        
        return currentVer == null || ! buildVer.matches(currentVer.getMajorVersion(), 
                                                        currentVer.getMinorVersion(), 
                                                        currentVer.getPointVersion());
    }

    /**
     * Return the database version for Kylo.
     *
     * @return the version of Kylo stored in the database
     */
    public KyloVersion getCurrentVersion() {
        String profiles = System.getProperty("spring.profiles.active", "");
        if (!profiles.contains("native")) {
            profiles = StringUtils.isEmpty(profiles) ? "native" : profiles + ",native";
            System.setProperty("spring.profiles.active", profiles);
        }
        //Spring is needed to load the Spring Cloud context so we can decrypt the passwords for the database connection
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("kylo-upgrade-check-application-context.xml");
        ctx.refresh();
        KyloUpgradeDatabaseVersionChecker upgradeDatabaseVersionChecker = (KyloUpgradeDatabaseVersionChecker) ctx.getBean("kyloUpgradeDatabaseVersionChecker");
        KyloVersion kyloVersion = upgradeDatabaseVersionChecker.getDatabaseVersion();
        ctx.close();
        return kyloVersion;
    }

}

@@ -1,15 +1,14 @@
 /**%0A *
- 
 %0A */%0Apac
@@ -729,16 +729,105 @@
 L%25%0A */%0A%0A
+import com.thinkbiganalytics.KyloVersion;%0Aimport com.thinkbiganalytics.KyloVersionUtil;%0A%0A
 import o
@@ -1183,95 +1183,123 @@
 xt;%0A
-%0A
 import 
-com.thinkbiganalytics.KyloVersion;%0Aimport com.thinkbiganalytics.KyloVersionUtil
+org.springframework.core.env.PropertiesPropertySource;%0A%0Aimport java.util.Arrays;%0Aimport java.util.Properties
 ;%0A%0A/
@@ -1394,20 +1394,16 @@
 rader %7B%0A
-    
 %0A    pri
@@ -1770,28 +1770,16 @@
 .class)%0A
-            
         
@@ -1805,28 +1805,16 @@
         
-      
-      
 .profile
@@ -1829,28 +1829,16 @@
 PGRADE)%0A
-            
         
@@ -2061,17 +2061,16 @@
 while (!
- 
 upgradeS
@@ -2090,17 +2090,50 @@
 eNext())
-;
+ %7B%0A                ;%0A            %7D
 %0A       
@@ -2193,20 +2193,16 @@
 %7D%0A    %7D%0A
-    
 %0A    pub
@@ -2355,24 +2355,16 @@
 sion();%0A
-        
 %0A       
@@ -2394,17 +2394,16 @@
 ull %7C%7C !
- 
 buildVer
@@ -2432,33 +2432,32 @@
 tMajorVersion(),
- 
 %0A               
@@ -2488,33 +2488,32 @@
                 
- 
 currentVer.getMi
@@ -2525,19 +2525,17 @@
 rsion(),
- %0A 
+%0A
         
@@ -3319,24 +3319,60 @@
 text.xml%22);%0A
+        loadProfileProperties(ctx);%0A
         ctx.
@@ -3684,10 +3684,765 @@
 %0A    %7D%0A%0A
+    private void loadProfileProperties(ClassPathXmlApplicationContext ctx) %7B%0A        Arrays.asList(ctx.getEnvironment().getActiveProfiles()).stream().filter(p -%3E !%22native%22.equalsIgnoreCase(p)).forEach(p -%3E %7B%0A            try %7B%0A                Properties properties = new Properties();%0A                properties.load(this.getClass().getClassLoader().getResourceAsStream(%22application-%22 + p + %22.properties%22));%0A%0A                PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource(p, properties);%0A                ctx.getEnvironment().getPropertySources().addLast(propertiesPropertySource);%0A            %7D catch (Exception e) %7B%0A                log.warn(%22Unable to load properties for profile %22 + p);%0A            %7D%0A        %7D);%0A    %7D%0A%0A
 %7D%0A

allow upgrader to work with application-profiles when debugging in IDE