jp.primecloud.auto.process.nifty.NiftyInstanceProcess.java Source code

Java tutorial

Introduction

Here is the source code for jp.primecloud.auto.process.nifty.NiftyInstanceProcess.java

Source

/*
 * Copyright 2014 by SCSK Corporation.
 *
 * This file is part of PrimeCloud Controller(TM).
 *
 * PrimeCloud Controller(TM) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * PrimeCloud Controller(TM) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PrimeCloud Controller(TM). If not, see <http://www.gnu.org/licenses/>.
 */
package jp.primecloud.auto.process.nifty;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import jp.primecloud.auto.config.Config;
import jp.primecloud.auto.entity.crud.Farm;
import jp.primecloud.auto.entity.crud.Image;
import jp.primecloud.auto.entity.crud.ImageNifty;
import jp.primecloud.auto.entity.crud.Instance;
import jp.primecloud.auto.entity.crud.NiftyInstance;
import jp.primecloud.auto.entity.crud.NiftyKeyPair;
import jp.primecloud.auto.entity.crud.Platform;
import jp.primecloud.auto.exception.AutoException;
import jp.primecloud.auto.log.EventLogger;
import jp.primecloud.auto.nifty.dto.InstanceDto;
import jp.primecloud.auto.nifty.process.NiftyProcessClient;
import jp.primecloud.auto.process.ProcessLogger;
import jp.primecloud.auto.puppet.PuppetClient;
import jp.primecloud.auto.service.ServiceSupport;
import jp.primecloud.auto.util.JSchUtils;
import jp.primecloud.auto.util.JSchUtils.JSchResult;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.jcraft.jsch.Session;

/**
 * <p>
 * TODO: 
 * </p>
 *
 */
public class NiftyInstanceProcess extends ServiceSupport {

    protected PuppetClient puppetClient;

    protected File imageDir;

    protected Long initTimeout;

    protected ProcessLogger processLogger;

    protected EventLogger eventLogger;

    private final static Object lock = new Object();

    public void createInstance(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);

        // ID????
        if (StringUtils.isNotEmpty(niftyInstance.getInstanceId())) {
            return;
        }

        // ???
        run(niftyProcessClient, instanceNo);

        // ?
        init(niftyProcessClient, instanceNo);

        // ??
        stop(niftyProcessClient, instanceNo);
    }

    public void startInstance(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);

        // ID?????
        if (StringUtils.isEmpty(niftyInstance.getInstanceId())) {
            // TODO: 
            throw new RuntimeException();
        }

        // Puppet??
        Instance instance = instanceDao.read(instanceNo);
        puppetClient.clearCa(instance.getFqdn());

        // ?
        start(niftyProcessClient, instanceNo);
    }

    public void stopInstance(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);

        // ID?????
        if (StringUtils.isEmpty(niftyInstance.getInstanceId())) {
            return;
        }

        // ??
        stop(niftyProcessClient, instanceNo);

        // ??????????
        niftyInstance = niftyInstanceDao.read(instanceNo);
        if (BooleanUtils.isNotTrue(niftyInstance.getInitialized())) {
            terminate(niftyProcessClient, instanceNo);
        }
    }

    public void deleteInstance(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);

        // ID?????
        if (StringUtils.isEmpty(niftyInstance.getInstanceId())) {
            return;
        }

        // ?
        terminate(niftyProcessClient, instanceNo);
    }

    protected void run(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);

        // ?
        Instance instance = instanceDao.read(instanceNo);
        ImageNifty imageNifty = imageNiftyDao.read(instance.getImageNo());

        // ?
        NiftyKeyPair niftyKeyPair = niftyKeyPairDao.read(niftyInstance.getKeyPairNo());

        // (api??????)
        synchronized (lock) {
            // 
            Platform platform = platformDao.read(niftyProcessClient.getPlatformNo());
            processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceCreate",
                    new Object[] { platform.getPlatformName() });

            // ?
            // TODO: root?
            InstanceDto instance2 = niftyProcessClient.runInstance(imageNifty.getImageId(),
                    niftyKeyPair.getKeyName(), "mini", "password");

            String instanceId = instance2.getInstanceId();

            // 
            niftyInstance = niftyInstanceDao.read(instanceNo);
            niftyInstance.setInstanceId(instanceId);
            niftyInstanceDao.update(niftyInstance);

            // ??
            instance2 = niftyProcessClient.waitRunInstance(instanceId);

            // 
            processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceCreateFinish",
                    new Object[] { platform.getPlatformName(), instance2.getInstanceId() });

            // 
            niftyInstance = niftyInstanceDao.read(instanceNo);
            niftyInstance.setStatus(instance2.getState().getName());
            niftyInstance.setDnsName(instance2.getDnsName());
            niftyInstance.setPrivateDnsName(instance2.getPrivateDnsName());
            niftyInstance.setIpAddress(instance2.getIpAddress());
            niftyInstance.setPrivateIpAddress(instance2.getPrivateIpAddress());
            niftyInstanceDao.update(niftyInstance);
        }
    }

    protected void start(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);
        String instanceId = niftyInstance.getInstanceId();

        // (api??????)
        synchronized (lock) {
            // 
            Instance instance = instanceDao.read(instanceNo);
            Platform platform = platformDao.read(niftyProcessClient.getPlatformNo());
            processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceStart",
                    new Object[] { platform.getPlatformName(), instanceId });

            // ?
            niftyProcessClient.startInstance(instanceId, niftyInstance.getInstanceType());

            // ??
            InstanceDto instance2 = niftyProcessClient.waitStartInstance(instanceId);

            // 
            processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceStartFinish",
                    new Object[] { platform.getPlatformName(), instanceId });

            // 
            niftyInstance = niftyInstanceDao.read(instanceNo);
            niftyInstance.setStatus(instance2.getState().getName());
            niftyInstance.setDnsName(instance2.getDnsName());
            niftyInstance.setPrivateDnsName(instance2.getPrivateDnsName());
            niftyInstance.setIpAddress(instance2.getIpAddress());
            niftyInstance.setPrivateIpAddress(instance2.getPrivateIpAddress());
            niftyInstanceDao.update(niftyInstance);
        }
    }

    protected void stop(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);
        String instanceId = niftyInstance.getInstanceId();

        // (api??????)
        synchronized (lock) {
            // 
            Instance instance = instanceDao.read(instanceNo);
            Platform platform = platformDao.read(niftyProcessClient.getPlatformNo());
            processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceStop",
                    new Object[] { platform.getPlatformName(), instanceId });

            // ??
            niftyProcessClient.stopInstance(instanceId);

            // ???
            InstanceDto instance2 = niftyProcessClient.waitStopInstance(instanceId);

            // 
            processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceStopFinish",
                    new Object[] { platform.getPlatformName(), instanceId });

            // 
            niftyInstance = niftyInstanceDao.read(instanceNo);
            niftyInstance.setStatus(instance2.getState().getName());
            niftyInstance.setDnsName(instance2.getDnsName());
            niftyInstance.setPrivateDnsName(instance2.getPrivateDnsName());
            niftyInstance.setIpAddress(instance2.getIpAddress());
            niftyInstance.setPrivateIpAddress(instance2.getPrivateIpAddress());
            niftyInstanceDao.update(niftyInstance);
        }
    }

    protected void terminate(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);
        String instanceId = niftyInstance.getInstanceId();

        synchronized (lock) {
            try {
                // 
                Instance instance = instanceDao.read(instanceNo);
                Platform platform = platformDao.read(niftyProcessClient.getPlatformNo());
                processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceDelete",
                        new Object[] { platform.getPlatformName(), instanceId });

                // ?
                niftyProcessClient.terminateInstance(instanceId);

                // ??
                niftyProcessClient.waitTerminateInstance(instanceId);

                // 
                processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceDeleteFinish",
                        new Object[] { platform.getPlatformName(), instanceId });

            } catch (AutoException ignore) {
                // ????????
                log.warn(ignore.getMessage());
            }

            // 
            niftyInstance = niftyInstanceDao.read(instanceNo);
            niftyInstance.setInstanceId(null);
            niftyInstance.setStatus(null);
            niftyInstance.setDnsName(null);
            niftyInstance.setPrivateDnsName(null);
            niftyInstance.setIpAddress(null);
            niftyInstance.setPrivateIpAddress(null);
            niftyInstance.setInitialized(null);
            niftyInstanceDao.update(niftyInstance);
        }
    }

    protected void init(NiftyProcessClient niftyProcessClient, Long instanceNo) {
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);
        NiftyKeyPair niftyKeyPair = niftyKeyPairDao.read(niftyInstance.getKeyPairNo());

        // 
        String instanceId = niftyInstance.getInstanceId();
        Instance instance = instanceDao.read(instanceNo);
        Platform platform = platformDao.read(niftyProcessClient.getPlatformNo());
        processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceInitialize",
                new Object[] { platform.getPlatformName(), instanceId });

        // SSH?
        Session session = JSchUtils.createSessionByPrivateKey("root", niftyKeyPair.getPrivateKey(),
                niftyKeyPair.getPassphrase(), niftyInstance.getIpAddress());

        try {
            // ??
            Image image = imageDao.read(instance.getImageNo());
            File imageFile = new File(imageDir, image.getImageName() + ".tar");
            FileInputStream input = null;
            try {
                input = new FileInputStream(imageFile);
                JSchUtils.sftpPut(session, input, "/tmp/image.tar");
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                IOUtils.closeQuietly(input);
            }

            // ?
            String userData = createUserData(instanceNo);

            // ?
            String command = "mkdir -p /tmp/image/ && tar xvf /tmp/image.tar -C /tmp/image/ && /tmp/image/init.sh \""
                    + userData + "\"";
            long timeout = 60 * 30 * 1000L;
            if (initTimeout != null) {
                timeout = initTimeout;
            }
            JSchResult result = JSchUtils.executeCommand(session, command, "UTF-8", timeout, true);

            if (result.getExitStatus() != 0) {
                // ???
                AutoException exception = new AutoException("EPROCESS-000616", instanceNo);
                exception.addDetailInfo(
                        "result=" + ReflectionToStringBuilder.toString(result, ToStringStyle.SHORT_PREFIX_STYLE));
                throw exception;
            }

        } finally {
            if (session != null) {
                session.disconnect();
            }
        }

        // 
        processLogger.writeLogSupport(ProcessLogger.LOG_DEBUG, null, instance, "NiftyInstanceInitializeFinish",
                new Object[] { platform.getPlatformName(), instanceId });

        // 
        niftyInstance = niftyInstanceDao.read(instanceNo);
        niftyInstance.setInitialized(true);
        niftyInstanceDao.update(niftyInstance);
    }

    protected String createUserData(Long instanceNo) {
        Map<String, String> map = createUserDataMap(instanceNo);

        if (map.isEmpty()) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        for (Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (key != null && value != null) {
                sb.append(key).append("=").append(value).append(";");
            }
        }
        sb.delete(sb.length() - 1, sb.length());

        return sb.toString();
    }

    protected Map<String, String> createUserDataMap(Long instanceNo) {
        Instance instance = instanceDao.read(instanceNo);
        Farm farm = farmDao.read(instance.getFarmNo());

        Map<String, String> map = new HashMap<String, String>();

        // DB
        map.put("instanceName", instance.getInstanceName());
        map.put("farmName", farm.getFarmName());

        // FQDN
        String fqdn = instance.getFqdn();
        map.put("hostname", fqdn);

        // ?
        map.put("scriptserver", Config.getProperty("script.server"));

        // DNS
        map.putAll(createDnsUserDataMap(instanceNo));

        // Puppet
        map.putAll(createPuppetUserDataMap(instanceNo));

        // VPN
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (platform.getInternal() == false) {
            // ????VPN??
            map.putAll(createVpnUserDataMap(instanceNo));
        }
        // OpenVPNURL
        map.put("vpnclienturl", Config.getProperty("vpn.clienturl"));

        return map;
    }

    protected Map<String, String> createDnsUserDataMap(Long instanceNo) {
        Map<String, String> map = new HashMap<String, String>();

        // Primary DNS?
        map.put("dns", Config.getProperty("dns.server"));

        // Secondry DNS?
        String dns2 = Config.getProperty("dns.server2");
        if (dns2 != null && dns2.length() > 0) {
            map.put("dns2", dns2);
        }

        // DNS
        map.put("dnsdomain", Config.getProperty("dns.domain"));

        return map;
    }

    protected Map<String, String> createPuppetUserDataMap(Long instanceNo) {
        Map<String, String> map = new HashMap<String, String>();

        // PuppetMaster
        map.put("puppetmaster", Config.getProperty("puppet.masterHost"));

        return map;
    }

    protected Map<String, String> createVpnUserDataMap(Long instanceNo) {
        Map<String, String> map = new HashMap<String, String>();

        // VPN???
        Instance instance = instanceDao.read(instanceNo);
        map.put("vpnuser", instance.getFqdn());
        map.put("vpnuserpass", instance.getInstanceCode());

        // VPN?
        map.put("vpnserver", Config.getProperty("vpn.server"));
        map.put("vpnport", Config.getProperty("vpn.port"));
        //map.put("vpnuser", Config.getProperty("vpn.user"));
        //map.put("vpnuserpass", Config.getProperty("vpn.userpass"));

        // ZIP
        map.put("vpnzippass", Config.getProperty("vpn.zippass"));

        return map;
    }

    /**
     * puppetClient???
     *
     * @param puppetClient puppetClient
     */
    public void setPuppetClient(PuppetClient puppetClient) {
        this.puppetClient = puppetClient;
    }

    /**
     * imageDir???
     *
     * @param imageDir imageDir
     */
    public void setImageDir(File imageDir) {
        this.imageDir = imageDir;
    }

    /**
     * initTimeout???
     *
     * @param initTimeout initTimeout
     */
    public void setInitTimeout(Long initTimeout) {
        this.initTimeout = initTimeout;
    }

    /**
     * eventLogger???
     *
     * @param eventLogger eventLogger
     */
    public void setEventLogger(EventLogger eventLogger) {
        this.eventLogger = eventLogger;
    }

    /**
     * processLogger???
     *
     * @param processLogger processLogger
     */
    public void setProcessLogger(ProcessLogger processLogger) {
        this.processLogger = processLogger;
    }
}