jp.primecloud.auto.service.impl.InstanceServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for jp.primecloud.auto.service.impl.InstanceServiceImpl.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.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import jp.primecloud.auto.common.component.PasswordGenerator;
import jp.primecloud.auto.common.constant.PCCConstant;
import jp.primecloud.auto.common.status.ComponentInstanceStatus;
import jp.primecloud.auto.common.status.InstanceCoodinateStatus;
import jp.primecloud.auto.common.status.InstanceStatus;
import jp.primecloud.auto.common.status.ZabbixInstanceStatus;
import jp.primecloud.auto.component.mysql.MySQLConstants;
import jp.primecloud.auto.config.Config;
import jp.primecloud.auto.entity.crud.AwsAddress;
import jp.primecloud.auto.entity.crud.AwsCertificate;
import jp.primecloud.auto.entity.crud.AwsInstance;
import jp.primecloud.auto.entity.crud.AwsVolume;
import jp.primecloud.auto.entity.crud.AzureCertificate;
import jp.primecloud.auto.entity.crud.AzureDisk;
import jp.primecloud.auto.entity.crud.AzureInstance;
import jp.primecloud.auto.entity.crud.CloudstackAddress;
import jp.primecloud.auto.entity.crud.CloudstackCertificate;
import jp.primecloud.auto.entity.crud.CloudstackInstance;
import jp.primecloud.auto.entity.crud.CloudstackVolume;
import jp.primecloud.auto.entity.crud.Component;
import jp.primecloud.auto.entity.crud.ComponentInstance;
import jp.primecloud.auto.entity.crud.ComponentType;
import jp.primecloud.auto.entity.crud.Farm;
import jp.primecloud.auto.entity.crud.Image;
import jp.primecloud.auto.entity.crud.ImageAws;
import jp.primecloud.auto.entity.crud.ImageAzure;
import jp.primecloud.auto.entity.crud.ImageCloudstack;
import jp.primecloud.auto.entity.crud.ImageNifty;
import jp.primecloud.auto.entity.crud.ImageOpenstack;
import jp.primecloud.auto.entity.crud.ImageVcloud;
import jp.primecloud.auto.entity.crud.ImageVmware;
import jp.primecloud.auto.entity.crud.Instance;
import jp.primecloud.auto.entity.crud.InstanceConfig;
import jp.primecloud.auto.entity.crud.LoadBalancer;
import jp.primecloud.auto.entity.crud.NiftyInstance;
import jp.primecloud.auto.entity.crud.NiftyKeyPair;
import jp.primecloud.auto.entity.crud.NiftyVolume;
import jp.primecloud.auto.entity.crud.OpenstackCertificate;
import jp.primecloud.auto.entity.crud.OpenstackInstance;
import jp.primecloud.auto.entity.crud.OpenstackVolume;
import jp.primecloud.auto.entity.crud.Platform;
import jp.primecloud.auto.entity.crud.PlatformAws;
import jp.primecloud.auto.entity.crud.PlatformAzure;
import jp.primecloud.auto.entity.crud.PlatformCloudstack;
import jp.primecloud.auto.entity.crud.PlatformNifty;
import jp.primecloud.auto.entity.crud.PlatformOpenstack;
import jp.primecloud.auto.entity.crud.PlatformVcloud;
import jp.primecloud.auto.entity.crud.PlatformVcloudStorageType;
import jp.primecloud.auto.entity.crud.PlatformVmware;
import jp.primecloud.auto.entity.crud.PuppetInstance;
import jp.primecloud.auto.entity.crud.VcloudDisk;
import jp.primecloud.auto.entity.crud.VcloudInstance;
import jp.primecloud.auto.entity.crud.VcloudInstanceNetwork;
import jp.primecloud.auto.entity.crud.VcloudKeyPair;
import jp.primecloud.auto.entity.crud.VmwareAddress;
import jp.primecloud.auto.entity.crud.VmwareDisk;
import jp.primecloud.auto.entity.crud.VmwareInstance;
import jp.primecloud.auto.entity.crud.VmwareKeyPair;
import jp.primecloud.auto.entity.crud.ZabbixData;
import jp.primecloud.auto.entity.crud.ZabbixInstance;
import jp.primecloud.auto.exception.AutoApplicationException;
import jp.primecloud.auto.exception.AutoException;
import jp.primecloud.auto.iaasgw.IaasGatewayFactory;
import jp.primecloud.auto.iaasgw.IaasGatewayWrapper;
import jp.primecloud.auto.log.EventLogLevel;
import jp.primecloud.auto.log.EventLogger;
import jp.primecloud.auto.nifty.process.NiftyProcessClient;
import jp.primecloud.auto.nifty.process.NiftyProcessClientFactory;
import jp.primecloud.auto.process.nifty.NiftyVolumeProcess;
import jp.primecloud.auto.process.vmware.VmwareDiskProcess;
import jp.primecloud.auto.process.vmware.VmwareMachineProcess;
import jp.primecloud.auto.process.vmware.VmwareProcessClient;
import jp.primecloud.auto.process.vmware.VmwareProcessClientFactory;
import jp.primecloud.auto.process.zabbix.ZabbixHostProcess;
import jp.primecloud.auto.process.zabbix.ZabbixProcessClient;
import jp.primecloud.auto.process.zabbix.ZabbixProcessClientFactory;
import jp.primecloud.auto.service.IaasDescribeService;
import jp.primecloud.auto.service.InstanceService;
import jp.primecloud.auto.service.ServiceSupport;
import jp.primecloud.auto.service.VmwareDescribeService;
import jp.primecloud.auto.service.dto.ComponentInstanceDto;
import jp.primecloud.auto.service.dto.DataDiskDto;
import jp.primecloud.auto.service.dto.ImageDto;
import jp.primecloud.auto.service.dto.InstanceDto;
import jp.primecloud.auto.service.dto.InstanceNetworkDto;
import jp.primecloud.auto.service.dto.KeyPairDto;
import jp.primecloud.auto.service.dto.NetworkDto;
import jp.primecloud.auto.service.dto.PlatformDto;
import jp.primecloud.auto.service.dto.SecurityGroupDto;
import jp.primecloud.auto.service.dto.SubnetDto;
import jp.primecloud.auto.service.dto.VmwareAddressDto;
import jp.primecloud.auto.service.dto.ZoneDto;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;

import com.amazonaws.services.ec2.model.InstanceType;
import com.vmware.vim25.mo.ComputeResource;

/**
 * <p>
 * InstanceService?
 * </p>
 *
 */
public class InstanceServiceImpl extends ServiceSupport implements InstanceService {

    protected IaasGatewayFactory iaasGatewayFactory;

    protected IaasDescribeService iaasDescribeService;

    protected VmwareDescribeService vmwareDescribeService;

    protected VmwareMachineProcess vmwareMachineProcess;

    protected VmwareDiskProcess vmwareDiskProcess;

    protected VmwareProcessClientFactory vmwareProcessClientFactory;

    protected NiftyProcessClientFactory niftyProcessClientFactory;

    protected ZabbixProcessClientFactory zabbixProcessClientFactory;

    protected ZabbixHostProcess zabbixHostProcess;

    protected PasswordGenerator passwordGenerator = new PasswordGenerator();

    protected EventLogger eventLogger;

    protected NiftyVolumeProcess niftyVolumeProcess;

    /**
     * {@inheritDoc}
     */
    @Override
    public InstanceDto getInstance(Long instanceNo) {
        // ?
        Instance instance = instanceDao.read(instanceNo);

        // ZabbixInstance?
        ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);

        // ?
        Platform platform = platformDao.read(instance.getPlatformNo());

        // ?
        Image image = imageDao.read(instance.getImageNo());

        // ??????
        Map<Long, List<ComponentInstance>> componentInstanceMap = new LinkedHashMap<Long, List<ComponentInstance>>();
        componentInstanceMap.put(instanceNo, new ArrayList<ComponentInstance>());
        List<ComponentInstance> tmpComponentInstances = componentInstanceDao.readByInstanceNo(instanceNo);
        for (ComponentInstance componentInstance : tmpComponentInstances) {
            // ?????????
            if (BooleanUtils.isNotTrue(componentInstance.getAssociate())) {
                ComponentInstanceStatus status = ComponentInstanceStatus.fromStatus(componentInstance.getStatus());
                if (status == ComponentInstanceStatus.STOPPED) {
                    continue;
                }
            }
            componentInstanceMap.get(componentInstance.getInstanceNo()).add(componentInstance);
        }

        // ???
        Map<Long, Component> componentMap = new HashMap<Long, Component>();
        Set<Long> componentNos = new HashSet<Long>();
        for (ComponentInstance componentInstance : tmpComponentInstances) {
            componentNos.add(componentInstance.getComponentNo());
        }
        List<Component> components = componentDao.readInComponentNos(componentNos);
        for (Component component : components) {
            componentMap.put(component.getComponentNo(), component);
        }

        // ??????
        Farm farm = farmDao.read(instance.getFarmNo());
        PlatformDto platformDto = new PlatformDto();
        platformDto.setPlatform(platform);
        ImageDto imageDto = new ImageDto();
        imageDto.setImage(image);

        AwsInstance awsInstance = null;
        AwsAddress awsAddress = null;
        List<AwsVolume> awsVolumes = null;
        AwsCertificate awsCertificate = null;

        CloudstackInstance cloudstackInstance = null;
        CloudstackAddress cloudstackAddress = null;
        List<CloudstackVolume> cloudstackVolumes = null;

        VmwareInstance vmwareInstance = null;
        VmwareAddress vmwareAddress = null;
        VmwareKeyPair vmwareKeyPair = null;
        List<VmwareDisk> vmwareDisks = null;

        NiftyInstance niftyInstance = null;
        NiftyKeyPair niftyKeyPair = null;

        VcloudInstance vcloudInstance = null;
        List<VcloudDisk> vcloudDisks = null;
        VcloudKeyPair vcloudKeyPair = null;
        List<VcloudInstanceNetwork> vcloudInstanceNetworks = null;
        PlatformVcloudStorageType platformVcloudStorageType = null;

        AzureCertificate azureCertificate = null;
        AzureInstance azureInstance = null;
        List<AzureDisk> azureDisks = null;
        // List<AzureNetwork> azureNetworks = null;
        // List<AzureStorage> azureStorages = null;

        OpenstackCertificate openstackCertificate = null;
        OpenstackInstance openstackInstance = null;

        // TODO CLOUD BRANCHING
        if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
            PlatformAws platformAws = platformAwsDao.read(platform.getPlatformNo());
            ImageAws imageAws = imageAwsDao.read(instance.getImageNo());
            platformDto.setPlatformAws(platformAws);
            imageDto.setImageAws(imageAws);

            // AWS?
            awsInstance = awsInstanceDao.read(instanceNo);

            // AWS?
            List<AwsAddress> awsAddresses = awsAddressDao.readByInstanceNo(instanceNo);
            for (AwsAddress address : awsAddresses) {
                awsAddress = address;
                break;
            }

            // AWS?
            awsVolumes = awsVolumeDao.readByInstanceNo(instanceNo);

            // AWS??
            awsCertificate = awsCertificateDao.read(farm.getUserNo(), instance.getPlatformNo());

        } else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType())) {
            PlatformCloudstack platformCloudstack = platformCloudstackDao.read(platform.getPlatformNo());
            ImageCloudstack imageCloudstack = imageCloudstackDao.read(instance.getImageNo());
            platformDto.setPlatformCloudstack(platformCloudstack);
            imageDto.setImageCloudstack(imageCloudstack);

            // CloudStack?
            cloudstackInstance = cloudstackInstanceDao.read(instanceNo);

            // CloudStack?
            List<CloudstackAddress> cloudstackAddresses = cloudstackAddressDao.readByInstanceNo(instanceNo);
            for (CloudstackAddress address : cloudstackAddresses) {
                cloudstackAddress = address;
                break;
            }

            // CloudStack?
            cloudstackVolumes = cloudstackVolumeDao.readByInstanceNo(instanceNo);

        } else if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType())) {
            PlatformVmware platformVmware = platformVmwareDao.read(platform.getPlatformNo());
            ImageVmware imageVmware = imageVmwareDao.read(instance.getImageNo());
            platformDto.setPlatformVmware(platformVmware);
            imageDto.setImageVmware(imageVmware);

            // VMware?
            vmwareInstance = vmwareInstanceDao.read(instanceNo);

            // VMwareAddress?
            vmwareAddress = vmwareAddressDao.readByInstanceNo(instanceNo);

            // VMware?
            vmwareKeyPair = vmwareKeyPairDao.read(vmwareInstance.getKeyPairNo());

            // VMware?
            vmwareDisks = vmwareDiskDao.readByInstanceNo(instanceNo);

        } else if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatformType())) {
            PlatformNifty platformNiftie = platformNiftyDao.read(platform.getPlatformNo());
            ImageNifty imageNiftie = imageNiftyDao.read(instance.getImageNo());
            platformDto.setPlatformNifty(platformNiftie);
            imageDto.setImageNifty(imageNiftie);

            // Nifty?
            niftyInstance = niftyInstanceDao.read(instanceNo);

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

        } else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())) {
            PlatformVcloud platformVcloud = platformVcloudDao.read(platform.getPlatformNo());
            ImageVcloud imageVcloud = imageVcloudDao.read(instance.getImageNo());
            platformDto.setPlatformVcloud(platformVcloud);
            imageDto.setImageVcloud(imageVcloud);

            // VCloudInstance?
            vcloudInstance = vcloudInstanceDao.read(instanceNo);

            // VCloudDisks?
            vcloudDisks = vcloudDiskDao.readByInstanceNo(instanceNo);

            // VCloudKeyPair?
            vcloudKeyPair = vcloudKeyPairDao.read(vcloudInstance.getKeyPairNo());

            // VCloudInstanceNetwork?
            vcloudInstanceNetworks = vcloudInstanceNetworkDao.readByInstanceNo(instanceNo);
            Collections.sort(vcloudInstanceNetworks, Comparators.COMPARATOR_VCLOUD_INSTANCE_NETWORK);

            // PlatformVCloudStrogeType?
            platformVcloudStorageType = platformVcloudStorageTypeDao.read(vcloudInstance.getStorageTypeNo());

        } else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
            PlatformAzure platformAzure = platformAzureDao.read(platform.getPlatformNo());
            ImageAzure imageAzure = imageAzureDao.read(instance.getImageNo());
            platformDto.setPlatformAzure(platformAzure);
            imageDto.setImageAzure(imageAzure);

            // AzureInstance?
            azureInstance = azureInstanceDao.read(instanceNo);

            // AzureDisks?
            azureDisks = azureDiskDao.readByInstanceNo(instanceNo);

            // Azure??
            azureCertificate = azureCertificateDao.read(farm.getUserNo(), instance.getPlatformNo());

            // AzureInstance?
            // vcloudKeyPair = vcloudKeyPairDao.read(vcloudInstance.getKeyPairNo());

            // AzureStroge?
            // platformVcloudStorageType = platformVcloudStorageTypeDao.read(vcloudInstance.getStorageTypeNo());

        } else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
            PlatformOpenstack platformOpenstack = platformOpenstackDao.read(platform.getPlatformNo());
            ImageOpenstack imageOpenstack = imageOpenstackDao.read(instance.getImageNo());
            platformDto.setPlatformOpenstack(platformOpenstack);
            imageDto.setImageOpenstack(imageOpenstack);

            // OpenstackInstance?
            openstackInstance = openstackInstanceDao.read(instanceNo);

            // Openstack??
            openstackCertificate = openstackCertificateDao.read(farm.getUserNo(), instance.getPlatformNo());
        }

        List<InstanceConfig> instanceConfigs = instanceConfigDao.readByInstanceNo(instance.getInstanceNo());

        List<ComponentInstanceDto> componentInstances = new ArrayList<ComponentInstanceDto>();
        for (ComponentInstance componentInstance : componentInstanceMap.get(instance.getInstanceNo())) {
            ComponentInstanceDto componentInstanceDto = new ComponentInstanceDto();
            componentInstanceDto.setComponentInstance(componentInstance);

            Component component = componentMap.get(componentInstance.getComponentNo());
            String url;
            Boolean showPublicIp = BooleanUtils.toBooleanObject(Config.getProperty("ui.showPublicIp"));
            if (BooleanUtils.isTrue(showPublicIp)) {
                //ui.showPublicIp = true ???URL?PublicIp
                url = createUrl(instance.getPublicIp(), component.getComponentTypeNo());
            } else {
                //ui.showPublicIp = false ???URL?PrivateIp
                url = createUrl(instance.getPrivateIp(), component.getComponentTypeNo());
            }
            componentInstanceDto.setUrl(url);
            componentInstances.add(componentInstanceDto);
        }

        // ?????
        InstanceStatus instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
        if (BooleanUtils.isTrue(instance.getEnabled())) {
            if (instanceStatus == InstanceStatus.STOPPED) {
                instance.setStatus(InstanceStatus.STARTING.toString());
            }
        } else {
            if (instanceStatus == InstanceStatus.RUNNING || instanceStatus == InstanceStatus.WARNING) {
                instance.setStatus(InstanceStatus.STOPPING.toString());
            }
        }

        // ???
        //    ? ?   ??
        //        Running         Coodinating            Configuring
        //        Running         Warning                Warning
        instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
        InstanceCoodinateStatus insCoodiStatus = InstanceCoodinateStatus.fromStatus(instance.getCoodinateStatus());
        // ?(Running)???(Coodinating)Configuring?
        if (instanceStatus == InstanceStatus.RUNNING && insCoodiStatus == InstanceCoodinateStatus.COODINATING) {
            instance.setStatus(InstanceStatus.CONFIGURING.toString());
            // ?(Running)???(Warning)Warning?
        } else if (instanceStatus == InstanceStatus.RUNNING && insCoodiStatus == InstanceCoodinateStatus.WARNING) {
            instance.setStatus(InstanceStatus.WARNING.toString());
        }

        // ????????
        instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
        for (ComponentInstanceDto componentInstanceDto : componentInstances) {
            ComponentInstance componentInstance = componentInstanceDto.getComponentInstance();
            ComponentInstanceStatus status = ComponentInstanceStatus.fromStatus(componentInstance.getStatus());
            if (BooleanUtils.isTrue(componentInstance.getEnabled())) {
                if (status == ComponentInstanceStatus.STOPPED) {
                    if (instanceStatus == InstanceStatus.WARNING) {
                        // ?Waring??????Warning??
                        componentInstance.setStatus(ComponentInstanceStatus.WARNING.toString());
                    } else if (BooleanUtils.isTrue(farm.getScheduled())) {
                        componentInstance.setStatus(ComponentInstanceStatus.STARTING.toString());
                    }
                }
            } else {
                if (status == ComponentInstanceStatus.RUNNING || status == ComponentInstanceStatus.WARNING) {
                    if (BooleanUtils.isTrue(farm.getScheduled())) {
                        // ??????Stopping??
                        componentInstance.setStatus(ComponentInstanceStatus.STOPPING.toString());
                    }
                }
            }
        }

        // 
        Collections.sort(componentInstances, Comparators.COMPARATOR_COMPONENT_INSTANCE_DTO);

        //?
        // TODO CLOUD BRANCHING
        InstanceDto dto = new InstanceDto();
        dto.setInstance(instance);
        dto.setZabbixInstance(zabbixInstance);
        dto.setPlatform(platformDto);
        dto.setImage(imageDto);
        dto.setInstanceConfigs(instanceConfigs);
        dto.setComponentInstances(componentInstances);

        dto.setAwsInstance(awsInstance);
        dto.setAwsAddress(awsAddress);
        dto.setAwsVolumes(awsVolumes);
        dto.setAwsCertificate(awsCertificate);

        dto.setCloudstackInstance(cloudstackInstance);
        dto.setCloudstackAddress(cloudstackAddress);
        dto.setCloudstackVolumes(cloudstackVolumes);

        dto.setVmwareInstance(vmwareInstance);
        dto.setVmwareAddress(vmwareAddress);
        dto.setVmwareKeyPair(vmwareKeyPair);
        dto.setVmwareDisks(vmwareDisks);

        dto.setNiftyInstance(niftyInstance);
        dto.setNiftyKeyPair(niftyKeyPair);

        dto.setVcloudInstance(vcloudInstance);
        dto.setVcloudDisks(vcloudDisks);
        dto.setVcloudKeyPair(vcloudKeyPair);
        dto.setVcloudInstanceNetworks(vcloudInstanceNetworks);
        dto.setPlatformVcloudStorageType(platformVcloudStorageType);

        dto.setAzureCertificate(azureCertificate);
        dto.setAzureInstance(azureInstance);
        dto.setAzureDisks(azureDisks);

        dto.setOpenstackInstance(openstackInstance);
        dto.setOpenstackCertificate(openstackCertificate);

        return dto;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<InstanceDto> getInstances(Long farmNo) {
        // ?
        List<Instance> instances = new ArrayList<Instance>();
        List<Instance> allInstances = instanceDao.readByFarmNo(farmNo);
        for (Instance instance : allInstances) {
            // ???
            if (BooleanUtils.isTrue(instance.getLoadBalancer())) {
                continue;
            }
            instances.add(instance);
        }

        // ????
        List<Long> instanceNos = new ArrayList<Long>();
        for (Instance instance : instances) {
            instanceNos.add(instance.getInstanceNo());
        }

        // ZabbixInstance?
        List<ZabbixInstance> zabbixInstances = zabbixInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, ZabbixInstance> zabbixInstanceMap = new LinkedHashMap<Long, ZabbixInstance>();
        for (ZabbixInstance zabbixInstance : zabbixInstances) {
            zabbixInstanceMap.put(zabbixInstance.getInstanceNo(), zabbixInstance);
        }

        // ?
        List<Platform> platforms = platformDao.readAll();
        Map<Long, Platform> platformMap = new LinkedHashMap<Long, Platform>();
        for (Platform platform : platforms) {
            platformMap.put(platform.getPlatformNo(), platform);
        }

        // ?
        List<Image> images = imageDao.readAll();
        Map<Long, Image> imageMap = new LinkedHashMap<Long, Image>();
        for (Image image : images) {
            imageMap.put(image.getImageNo(), image);
        }

        // ??????
        Map<Long, List<ComponentInstance>> componentInstanceMap = new LinkedHashMap<Long, List<ComponentInstance>>();
        for (Long instanceNo : instanceNos) {
            componentInstanceMap.put(instanceNo, new ArrayList<ComponentInstance>());
        }
        List<ComponentInstance> tmpComponentInstances = componentInstanceDao.readInInstanceNos(instanceNos);
        for (ComponentInstance componentInstance : tmpComponentInstances) {
            // ?????????
            if (BooleanUtils.isNotTrue(componentInstance.getAssociate())) {
                ComponentInstanceStatus status = ComponentInstanceStatus.fromStatus(componentInstance.getStatus());
                if (status == ComponentInstanceStatus.STOPPED) {
                    continue;
                }
            }
            componentInstanceMap.get(componentInstance.getInstanceNo()).add(componentInstance);
        }

        // ???
        Map<Long, Component> componentMap = new HashMap<Long, Component>();
        Set<Long> componentNos = new HashSet<Long>();
        for (ComponentInstance componentInstance : tmpComponentInstances) {
            componentNos.add(componentInstance.getComponentNo());
        }
        List<Component> components = componentDao.readInComponentNos(componentNos);
        for (Component component : components) {
            componentMap.put(component.getComponentNo(), component);
        }

        // TODO CLOUD BRANCHING
        // AWS 
        // AWS?
        List<PlatformAws> platformAwss = platformAwsDao.readAll();
        Map<Long, PlatformAws> platformAwsMap = new LinkedHashMap<Long, PlatformAws>();
        for (PlatformAws platformAws : platformAwss) {
            platformAwsMap.put(platformAws.getPlatformNo(), platformAws);
        }

        // AWS?
        List<ImageAws> imageAwss = imageAwsDao.readAll();
        Map<Long, ImageAws> imageAwsMap = new LinkedHashMap<Long, ImageAws>();
        for (ImageAws imageAws : imageAwss) {
            imageAwsMap.put(imageAws.getImageNo(), imageAws);
        }

        // AWS?
        List<AwsInstance> awsInstances = awsInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, AwsInstance> awsInstanceMap = new LinkedHashMap<Long, AwsInstance>();
        for (AwsInstance awsInstance : awsInstances) {
            awsInstanceMap.put(awsInstance.getInstanceNo(), awsInstance);
        }

        // AWS?
        Farm farm = farmDao.read(farmNo);
        List<AwsAddress> awsAddresses = awsAddressDao.readByUserNo(farm.getUserNo());
        Map<Long, AwsAddress> awsAddressMap = new LinkedHashMap<Long, AwsAddress>();
        for (AwsAddress awsAddress : awsAddresses) {
            if (awsAddress.getInstanceNo() != null) {
                awsAddressMap.put(awsAddress.getInstanceNo(), awsAddress);
            }
        }

        // AWS?
        List<AwsVolume> farmAwsVolumes = awsVolumeDao.readByFarmNo(farmNo);
        Map<Long, List<AwsVolume>> awsVolumesMap = new LinkedHashMap<Long, List<AwsVolume>>();
        for (AwsVolume awsVolume : farmAwsVolumes) {
            Long instanceNo = awsVolume.getInstanceNo();
            if (instanceNo != null) {
                List<AwsVolume> awsVolumes = awsVolumesMap.get(instanceNo);
                if (awsVolumes == null) {
                    awsVolumes = new ArrayList<AwsVolume>();
                    awsVolumesMap.put(instanceNo, awsVolumes);
                }
                awsVolumes.add(awsVolume);
            }
        }

        // AWS??
        List<AwsCertificate> awsCertificates = awsCertificateDao.readByUserNo(farm.getUserNo());
        Map<Long, AwsCertificate> awsCertificateMap = new LinkedHashMap<Long, AwsCertificate>();
        for (AwsCertificate awsCertificate : awsCertificates) {
            awsCertificateMap.put(awsCertificate.getPlatformNo(), awsCertificate);
        }

        // CloudStack 
        // CloudStack?
        List<PlatformCloudstack> platformCloudstacks = platformCloudstackDao.readAll();
        Map<Long, PlatformCloudstack> platformCloudstackMap = new LinkedHashMap<Long, PlatformCloudstack>();
        for (PlatformCloudstack platformCloudstack : platformCloudstacks) {
            platformCloudstackMap.put(platformCloudstack.getPlatformNo(), platformCloudstack);
        }

        // CloudStack?
        List<ImageCloudstack> imageCloudstacks = imageCloudstackDao.readAll();
        Map<Long, ImageCloudstack> imageCloudstackMap = new LinkedHashMap<Long, ImageCloudstack>();
        for (ImageCloudstack imageCloudstack : imageCloudstacks) {
            imageCloudstackMap.put(imageCloudstack.getImageNo(), imageCloudstack);
        }

        // CloudStack?
        List<CloudstackInstance> cloudstackInstances = cloudstackInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, CloudstackInstance> cloudstackInstanceMap = new LinkedHashMap<Long, CloudstackInstance>();
        for (CloudstackInstance cloudstackInstance : cloudstackInstances) {
            cloudstackInstanceMap.put(cloudstackInstance.getInstanceNo(), cloudstackInstance);
        }

        // CloudStack?
        List<CloudstackAddress> cloudstackAddresses = cloudstackAddressDao.readByAccount(farm.getUserNo());
        Map<Long, CloudstackAddress> cloudstackAddressMap = new LinkedHashMap<Long, CloudstackAddress>();
        for (CloudstackAddress cloudstackAddress : cloudstackAddresses) {
            if (cloudstackAddress.getInstanceNo() != null) {
                cloudstackAddressMap.put(cloudstackAddress.getInstanceNo(), cloudstackAddress);
            }
        }

        // CloudStack?
        List<CloudstackVolume> farmCloudstackVolumes = cloudstackVolumeDao.readByFarmNo(farmNo);
        Map<Long, List<CloudstackVolume>> cloudstackVolumesMap = new LinkedHashMap<Long, List<CloudstackVolume>>();
        for (CloudstackVolume cloudstackVolume : farmCloudstackVolumes) {
            Long instanceNo = cloudstackVolume.getInstanceNo();
            if (instanceNo != null) {
                List<CloudstackVolume> cloudstackVolumes = cloudstackVolumesMap.get(instanceNo);
                if (cloudstackVolumes == null) {
                    cloudstackVolumes = new ArrayList<CloudstackVolume>();
                    cloudstackVolumesMap.put(instanceNo, cloudstackVolumes);
                }
                cloudstackVolumes.add(cloudstackVolume);
            }
        }

        // VMware 
        // VMWare?
        List<PlatformVmware> platformVmwares = platformVmwareDao.readAll();
        Map<Long, PlatformVmware> platformVmwareMap = new LinkedHashMap<Long, PlatformVmware>();
        for (PlatformVmware platformVmware : platformVmwares) {
            platformVmwareMap.put(platformVmware.getPlatformNo(), platformVmware);
        }

        // VMware?
        List<ImageVmware> imageVmwares = imageVmwareDao.readAll();
        Map<Long, ImageVmware> imageVmwareMap = new LinkedHashMap<Long, ImageVmware>();
        for (ImageVmware imageVmware : imageVmwares) {
            imageVmwareMap.put(imageVmware.getImageNo(), imageVmware);
        }

        // VMware?
        List<VmwareInstance> vmwareInstances = vmwareInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, VmwareInstance> vmwareInstanceMap = new LinkedHashMap<Long, VmwareInstance>();
        for (VmwareInstance vmwareInstance : vmwareInstances) {
            vmwareInstanceMap.put(vmwareInstance.getInstanceNo(), vmwareInstance);
        }

        // VMwareAddress?
        Map<Long, VmwareAddress> vmwareAddressMap = new LinkedHashMap<Long, VmwareAddress>();
        List<VmwareAddress> vmwareAddresses = vmwareAddressDao.readByUserNo(farm.getUserNo());
        for (VmwareAddress vmwareAddress : vmwareAddresses) {
            if (vmwareAddress.getInstanceNo() != null) {
                vmwareAddressMap.put(vmwareAddress.getInstanceNo(), vmwareAddress);
            }
        }

        // VMware?
        Map<Long, VmwareKeyPair> vmwareKeyPairMap = new LinkedHashMap<Long, VmwareKeyPair>();
        if (!vmwareInstanceMap.isEmpty()) {
            List<VmwareKeyPair> vmwareKeyPairs = vmwareKeyPairDao.readByUserNo(farm.getUserNo());
            for (VmwareKeyPair vmwareKeyPair : vmwareKeyPairs) {
                vmwareKeyPairMap.put(vmwareKeyPair.getKeyNo(), vmwareKeyPair);
            }
        }

        // VMware?
        List<VmwareDisk> farmVmwareDisks = vmwareDiskDao.readByFarmNo(farmNo);
        Map<Long, List<VmwareDisk>> vmwareDisksMap = new LinkedHashMap<Long, List<VmwareDisk>>();
        for (VmwareDisk vmwareDisk : farmVmwareDisks) {
            Long instanceNo = vmwareDisk.getInstanceNo();
            if (instanceNo != null) {
                List<VmwareDisk> vmwareDisks = vmwareDisksMap.get(instanceNo);
                if (vmwareDisks == null) {
                    vmwareDisks = new ArrayList<VmwareDisk>();
                    vmwareDisksMap.put(instanceNo, vmwareDisks);
                }
                vmwareDisks.add(vmwareDisk);
            }
        }

        // Nifty 
        // Nifty?
        List<PlatformNifty> platformNifties = platformNiftyDao.readAll();
        Map<Long, PlatformNifty> platformNiftyMap = new LinkedHashMap<Long, PlatformNifty>();
        for (PlatformNifty platformNifty : platformNifties) {
            platformNiftyMap.put(platformNifty.getPlatformNo(), platformNifty);
        }

        // Nifty?
        List<ImageNifty> imageNifties = imageNiftyDao.readAll();
        Map<Long, ImageNifty> imageNiftyMap = new LinkedHashMap<Long, ImageNifty>();
        for (ImageNifty imageNifty : imageNifties) {
            imageNiftyMap.put(imageNifty.getImageNo(), imageNifty);
        }

        // Nifty?
        List<NiftyInstance> niftyInstances = niftyInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, NiftyInstance> niftyInstanceMap = new LinkedHashMap<Long, NiftyInstance>();
        for (NiftyInstance niftyInstance : niftyInstances) {
            niftyInstanceMap.put(niftyInstance.getInstanceNo(), niftyInstance);
        }

        // Nifty?
        Map<Long, NiftyKeyPair> niftyKeyPairMap = new LinkedHashMap<Long, NiftyKeyPair>();
        if (!niftyInstanceMap.isEmpty()) {
            List<NiftyKeyPair> niftyKeyPairs = niftyKeyPairDao.readByUserNo(farm.getUserNo());
            for (NiftyKeyPair niftyKeyPair : niftyKeyPairs) {
                niftyKeyPairMap.put(niftyKeyPair.getKeyNo(), niftyKeyPair);
            }
        }

        // Nifty?
        List<NiftyVolume> farmNiftyVolumes = niftyVolumeDao.readByFarmNo(farmNo);
        Map<Long, List<NiftyVolume>> niftyVolumesMap = new LinkedHashMap<Long, List<NiftyVolume>>();
        for (NiftyVolume niftyVolume : farmNiftyVolumes) {
            Long instanceNo = niftyVolume.getInstanceNo();
            if (instanceNo != null) {
                List<NiftyVolume> niftyVolumes = niftyVolumesMap.get(instanceNo);
                if (niftyVolumes == null) {
                    niftyVolumes = new ArrayList<NiftyVolume>();
                    niftyVolumesMap.put(instanceNo, niftyVolumes);
                }
                niftyVolumes.add(niftyVolume);
            }
        }

        // VCloud 
        // VCloudPlatform?
        List<PlatformVcloud> platformVclouds = platformVcloudDao.readAll();
        Map<Long, PlatformVcloud> platformVcloudMap = new LinkedHashMap<Long, PlatformVcloud>();
        for (PlatformVcloud platformVcloud : platformVclouds) {
            platformVcloudMap.put(platformVcloud.getPlatformNo(), platformVcloud);
        }

        // VCloudImage?
        List<ImageVcloud> imageVclouds = imageVcloudDao.readAll();
        Map<Long, ImageVcloud> imageVcloudMap = new LinkedHashMap<Long, ImageVcloud>();
        for (ImageVcloud imageVcloud : imageVclouds) {
            imageVcloudMap.put(imageVcloud.getImageNo(), imageVcloud);
        }

        // VCloudInstance?
        List<VcloudInstance> vcloudInstances = vcloudInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, VcloudInstance> vcloudInstanceMap = new LinkedHashMap<Long, VcloudInstance>();
        for (VcloudInstance vcloudInstance : vcloudInstances) {
            vcloudInstanceMap.put(vcloudInstance.getInstanceNo(), vcloudInstance);
        }

        // VCloudKeyPair?
        Map<Long, VcloudKeyPair> vcloudKeyPairMap = new LinkedHashMap<Long, VcloudKeyPair>();
        List<VcloudKeyPair> vcloudKeyPairs = vcloudKeyPairDao.readByUserNo(farm.getUserNo());
        for (VcloudKeyPair vcloudKeyPair : vcloudKeyPairs) {
            vcloudKeyPairMap.put(vcloudKeyPair.getKeyNo(), vcloudKeyPair);
        }

        // VCloudDisk?
        List<VcloudDisk> farmVcloudDisks = vcloudDiskDao.readByFarmNo(farmNo);
        Map<Long, List<VcloudDisk>> vcloudDiskMap = new LinkedHashMap<Long, List<VcloudDisk>>();
        for (VcloudDisk vcloudDisk : farmVcloudDisks) {
            Long instanceNo = vcloudDisk.getInstanceNo();
            if (instanceNo != null) {
                List<VcloudDisk> vcloudDisks = vcloudDiskMap.get(instanceNo);
                if (vcloudDisks == null) {
                    vcloudDisks = new ArrayList<VcloudDisk>();
                }
                vcloudDisks.add(vcloudDisk);
                vcloudDiskMap.put(instanceNo, vcloudDisks);
            }
        }

        //VCloudNetwork?
        List<VcloudInstanceNetwork> allVcloudInstanceNetworks = vcloudInstanceNetworkDao.readByFarmNo(farmNo);
        Map<Long, List<VcloudInstanceNetwork>> vcloudInstanceNetworkMap = new LinkedHashMap<Long, List<VcloudInstanceNetwork>>();
        for (VcloudInstanceNetwork vcloudInstanceNetwork : allVcloudInstanceNetworks) {
            List<VcloudInstanceNetwork> instanceNetworks = vcloudInstanceNetworkMap
                    .get(vcloudInstanceNetwork.getInstanceNo());
            if (instanceNetworks == null) {
                instanceNetworks = new ArrayList<VcloudInstanceNetwork>();
            }
            instanceNetworks.add(vcloudInstanceNetwork);
            vcloudInstanceNetworkMap.put(vcloudInstanceNetwork.getInstanceNo(), instanceNetworks);
        }

        //PlatformVcloudStorageType?
        List<PlatformVcloudStorageType> platformVcloudStorageTypes = platformVcloudStorageTypeDao.readAll();
        Map<Long, PlatformVcloudStorageType> platformVcloudStorageTypeMap = new LinkedHashMap<Long, PlatformVcloudStorageType>();
        for (PlatformVcloudStorageType platformVcloudStorageType : platformVcloudStorageTypes) {
            platformVcloudStorageTypeMap.put(platformVcloudStorageType.getStorageTypeNo(),
                    platformVcloudStorageType);
        }

        // Azure 
        // Azure?
        List<PlatformAzure> platformAzures = platformAzureDao.readAll();
        Map<Long, PlatformAzure> platformAzureMap = new LinkedHashMap<Long, PlatformAzure>();
        for (PlatformAzure platformAzure : platformAzures) {
            platformAzureMap.put(platformAzure.getPlatformNo(), platformAzure);
        }

        // Azure?
        List<ImageAzure> imageAzures = imageAzureDao.readAll();
        Map<Long, ImageAzure> imageAzureMap = new LinkedHashMap<Long, ImageAzure>();
        for (ImageAzure imageAzure : imageAzures) {
            imageAzureMap.put(imageAzure.getImageNo(), imageAzure);
        }

        // Azure?
        List<AzureInstance> azureInstances = azureInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, AzureInstance> azureInstanceMap = new LinkedHashMap<Long, AzureInstance>();
        for (AzureInstance azureInstance : azureInstances) {
            azureInstanceMap.put(azureInstance.getInstanceNo(), azureInstance);
        }

        // Azure??   ??????????
        //        List<AzureSubnet> azureAddresses = azureSubnetDao.readByAccount(farm.getUserNo());
        //        Map<Long, AzureSubnet> azureAddressMap = new LinkedHashMap<Long, AzureSubnet>();
        //        for (CloudstackAddress azureAddress : azureAddresses) {
        //            if (azureAddress.getInstanceNo() != null) {
        //                cloudstackAddressMap.put(azureAddress.getInstanceNo(), azureAddress);
        //            }
        //        }

        // Azure?
        List<AzureDisk> farmAzureDisks = azureDiskDao.readByFarmNo(farmNo);
        Map<Long, List<AzureDisk>> azureDisksMap = new LinkedHashMap<Long, List<AzureDisk>>();
        for (AzureDisk azureDisk : farmAzureDisks) {
            Long instanceNo = azureDisk.getInstanceNo();
            if (instanceNo != null) {
                List<AzureDisk> azureDisks = azureDisksMap.get(instanceNo);
                if (azureDisks == null) {
                    azureDisks = new ArrayList<AzureDisk>();
                    azureDisksMap.put(instanceNo, azureDisks);
                }
                azureDisks.add(azureDisk);
            }
        }

        // OpenStack 
        // OpenStack?
        List<PlatformOpenstack> platformOpenstacks = platformOpenstackDao.readAll();
        Map<Long, PlatformOpenstack> platformOpenstackMap = new LinkedHashMap<Long, PlatformOpenstack>();
        for (PlatformOpenstack platformOpenstack : platformOpenstacks) {
            platformOpenstackMap.put(platformOpenstack.getPlatformNo(), platformOpenstack);
        }

        // OpenStack?
        List<ImageOpenstack> imageOpenstacks = imageOpenstackDao.readAll();
        Map<Long, ImageOpenstack> imageOpenstackMap = new LinkedHashMap<Long, ImageOpenstack>();
        for (ImageOpenstack imageOpenstack : imageOpenstacks) {
            imageOpenstackMap.put(imageOpenstack.getImageNo(), imageOpenstack);
        }

        // OpenStack?
        List<OpenstackInstance> openstackInstances = openstackInstanceDao.readInInstanceNos(instanceNos);
        Map<Long, OpenstackInstance> openstackInstanceMap = new LinkedHashMap<Long, OpenstackInstance>();
        for (OpenstackInstance openstackInstance : openstackInstances) {
            openstackInstanceMap.put(openstackInstance.getInstanceNo(), openstackInstance);
        }

        // ????????
        List<InstanceDto> dtos = new ArrayList<InstanceDto>();
        for (Instance instance : instances) {
            ZabbixInstance zabbixInstance = zabbixInstanceMap.get(instance.getInstanceNo());

            PlatformDto platformDto = new PlatformDto();
            ImageDto imageDto = new ImageDto();

            Platform platform = platformMap.get(instance.getPlatformNo());
            platformDto.setPlatform(platform);

            Image image = imageMap.get(instance.getImageNo());
            imageDto.setImage(image);
            // TODO CLOUD BRANCHING
            if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
                platformDto.setPlatformAws(platformAwsMap.get(instance.getPlatformNo()));
                imageDto.setImageAws(imageAwsMap.get(instance.getImageNo()));
            } else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType())) {
                platformDto.setPlatformCloudstack(platformCloudstackMap.get(instance.getPlatformNo()));
                imageDto.setImageCloudstack(imageCloudstackMap.get(instance.getImageNo()));
            } else if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType())) {
                platformDto.setPlatformVmware(platformVmwareMap.get(instance.getPlatformNo()));
                imageDto.setImageVmware(imageVmwareMap.get(instance.getImageNo()));
            } else if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatformType())) {
                platformDto.setPlatformNifty(platformNiftyMap.get(instance.getPlatformNo()));
                imageDto.setImageNifty(imageNiftyMap.get(instance.getImageNo()));
            } else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())) {
                platformDto.setPlatformVcloud(platformVcloudMap.get(instance.getPlatformNo()));
                imageDto.setImageVcloud(imageVcloudMap.get(instance.getImageNo()));
            } else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
                platformDto.setPlatformAzure(platformAzureMap.get(instance.getPlatformNo()));
                imageDto.setImageAzure(imageAzureMap.get(instance.getImageNo()));
            } else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
                platformDto.setPlatformOpenstack(platformOpenstackMap.get(instance.getPlatformNo()));
                imageDto.setImageOpenstack(imageOpenstackMap.get(instance.getImageNo()));
            }

            List<InstanceConfig> instanceConfigs = instanceConfigDao.readByInstanceNo(instance.getInstanceNo());

            List<ComponentInstanceDto> componentInstances = new ArrayList<ComponentInstanceDto>();
            for (ComponentInstance componentInstance : componentInstanceMap.get(instance.getInstanceNo())) {
                ComponentInstanceDto componentInstanceDto = new ComponentInstanceDto();
                componentInstanceDto.setComponentInstance(componentInstance);

                Component component = componentMap.get(componentInstance.getComponentNo());
                String url;
                Boolean showPublicIp = BooleanUtils.toBooleanObject(Config.getProperty("ui.showPublicIp"));
                if (BooleanUtils.isTrue(showPublicIp)) {
                    //ui.showPublicIp = true ???URL?PublicIp
                    url = createUrl(instance.getPublicIp(), component.getComponentTypeNo());
                } else {
                    //ui.showPublicIp = false ???URL?PrivateIp
                    url = createUrl(instance.getPrivateIp(), component.getComponentTypeNo());
                }
                componentInstanceDto.setUrl(url);
                componentInstances.add(componentInstanceDto);
            }

            // ?????
            InstanceStatus instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
            if (BooleanUtils.isTrue(instance.getEnabled())) {
                if (instanceStatus == InstanceStatus.STOPPED) {
                    instance.setStatus(InstanceStatus.STARTING.toString());
                }
            } else {
                if (instanceStatus == InstanceStatus.RUNNING || instanceStatus == InstanceStatus.WARNING) {
                    instance.setStatus(InstanceStatus.STOPPING.toString());
                }
            }

            // ???
            //    ? ?   ??
            //        Running         Coodinating            Configuring
            //        Running         Warning                Warning
            instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
            InstanceCoodinateStatus insCoodiStatus = InstanceCoodinateStatus
                    .fromStatus(instance.getCoodinateStatus());
            // ?(Running)???(Coodinating)Configuring?
            if (instanceStatus == InstanceStatus.RUNNING && insCoodiStatus == InstanceCoodinateStatus.COODINATING) {
                instance.setStatus(InstanceStatus.CONFIGURING.toString());
                // ?(Running)???(Warning)Warning?
            } else if (instanceStatus == InstanceStatus.RUNNING
                    && insCoodiStatus == InstanceCoodinateStatus.WARNING) {
                instance.setStatus(InstanceStatus.WARNING.toString());
            }

            // ????????
            instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
            for (ComponentInstanceDto componentInstanceDto : componentInstances) {
                ComponentInstance componentInstance = componentInstanceDto.getComponentInstance();
                ComponentInstanceStatus status = ComponentInstanceStatus.fromStatus(componentInstance.getStatus());
                if (BooleanUtils.isTrue(componentInstance.getEnabled())) {
                    if (status == ComponentInstanceStatus.STOPPED) {
                        if (instanceStatus == InstanceStatus.WARNING) {
                            // ?Waring??????Warning??
                            componentInstance.setStatus(ComponentInstanceStatus.WARNING.toString());
                        } else if (BooleanUtils.isTrue(farm.getScheduled())) {
                            componentInstance.setStatus(ComponentInstanceStatus.STARTING.toString());
                        }
                    }
                } else {
                    if (status == ComponentInstanceStatus.RUNNING || status == ComponentInstanceStatus.WARNING) {
                        if (BooleanUtils.isTrue(farm.getScheduled())) {
                            // ??????Stopping??
                            componentInstance.setStatus(ComponentInstanceStatus.STOPPING.toString());
                        }
                    }
                }
            }

            AwsInstance awsInstance = awsInstanceMap.get(instance.getInstanceNo());
            AwsAddress awsAddress = awsAddressMap.get(instance.getInstanceNo());
            List<AwsVolume> awsVolumes = awsVolumesMap.get(instance.getInstanceNo());
            AwsCertificate awsCertificate = awsCertificateMap.get(instance.getPlatformNo());

            CloudstackInstance cloudstackInstance = cloudstackInstanceMap.get(instance.getInstanceNo());
            CloudstackAddress cloudstackAddress = cloudstackAddressMap.get(instance.getInstanceNo());
            List<CloudstackVolume> cloudstackVolumes = cloudstackVolumesMap.get(instance.getInstanceNo());

            VmwareInstance vmwareInstance = vmwareInstanceMap.get(instance.getInstanceNo());
            VmwareAddress vmwareAddress = vmwareAddressMap.get(instance.getInstanceNo());
            VmwareKeyPair vmwareKeyPair = null;
            if (vmwareInstance != null) {
                vmwareKeyPair = vmwareKeyPairMap.get(vmwareInstance.getKeyPairNo());
            }
            List<VmwareDisk> vmwareDisks = vmwareDisksMap.get(instance.getInstanceNo());

            NiftyInstance niftyInstance = niftyInstanceMap.get(instance.getInstanceNo());
            NiftyKeyPair niftyKeyPair = null;
            if (niftyInstance != null) {
                niftyKeyPair = niftyKeyPairMap.get(niftyInstance.getKeyPairNo());
            }
            List<NiftyVolume> niftyVolumes = niftyVolumesMap.get(instance.getInstanceNo());

            VcloudInstance vcloudInstance = vcloudInstanceMap.get(instance.getInstanceNo());
            VcloudKeyPair vcloudKeyPair = null;
            if (vcloudInstance != null) {
                vcloudKeyPair = vcloudKeyPairMap.get(vcloudInstance.getKeyPairNo());
            }
            List<VcloudDisk> vcloudDisks = vcloudDiskMap.get(instance.getInstanceNo());
            List<VcloudInstanceNetwork> vcloudInstanceNetworks = vcloudInstanceNetworkMap
                    .get(instance.getInstanceNo());
            if (vcloudInstanceNetworks != null) {
                Collections.sort(vcloudInstanceNetworks, Comparators.COMPARATOR_VCLOUD_INSTANCE_NETWORK);
            }
            PlatformVcloudStorageType platformVcloudStorageType = null;
            if (vcloudInstance != null) {
                platformVcloudStorageType = platformVcloudStorageTypeMap.get(vcloudInstance.getStorageTypeNo());
            }

            AzureInstance azureInstance = azureInstanceMap.get(instance.getInstanceNo());
            List<AzureDisk> azureDisks = azureDisksMap.get(instance.getInstanceNo());

            OpenstackInstance openstackInstance = openstackInstanceMap.get(instance.getInstanceNo());

            // 
            Collections.sort(componentInstances, Comparators.COMPARATOR_COMPONENT_INSTANCE_DTO);

            InstanceDto dto = new InstanceDto();
            dto.setInstance(instance);
            dto.setZabbixInstance(zabbixInstance);
            dto.setPlatform(platformDto);
            dto.setImage(imageDto);
            dto.setInstanceConfigs(instanceConfigs);
            dto.setComponentInstances(componentInstances);

            dto.setAwsInstance(awsInstance);
            dto.setAwsAddress(awsAddress);
            dto.setAwsVolumes(awsVolumes);
            dto.setAwsCertificate(awsCertificate);

            dto.setCloudstackInstance(cloudstackInstance);
            dto.setCloudstackAddress(cloudstackAddress);
            dto.setCloudstackVolumes(cloudstackVolumes);

            dto.setVmwareInstance(vmwareInstance);
            dto.setVmwareAddress(vmwareAddress);
            dto.setVmwareKeyPair(vmwareKeyPair);
            dto.setVmwareDisks(vmwareDisks);

            dto.setNiftyInstance(niftyInstance);
            dto.setNiftyKeyPair(niftyKeyPair);
            dto.setNiftyVolumes(niftyVolumes);

            dto.setVcloudInstance(vcloudInstance);
            dto.setVcloudKeyPair(vcloudKeyPair);
            dto.setVcloudDisks(vcloudDisks);
            dto.setVcloudInstanceNetworks(vcloudInstanceNetworks);
            dto.setPlatformVcloudStorageType(platformVcloudStorageType);

            dto.setAzureInstance(azureInstance);
            dto.setAzureDisks(azureDisks);

            dto.setOpenstackInstance(openstackInstance);

            dtos.add(dto);
        }

        // 
        Collections.sort(dtos, Comparators.COMPARATOR_INSTANCE_DTO);

        return dtos;
    }

    protected Long createInstance(Long farmNo, String instanceName, Long platformNo, String comment, Long imageNo) {
        // ?
        if (farmNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "farmNo");
        }
        if (instanceName == null || instanceName.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceName");
        }
        if (platformNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "platformNo");
        }
        if (imageNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "imageNo");
        }

        // ??
        if (!Pattern.matches("^[0-9a-z]|[0-9a-z][0-9a-z-]*[0-9a-z]$", instanceName)) {
            throw new AutoApplicationException("ECOMMON-000012", "instanceName");
        }

        // ???
        Image image = imageDao.read(imageNo);
        Platform platform = platformDao.read(platformNo);
        if (platformNo.equals(image.getPlatformNo()) == false) {
            throw new AutoApplicationException("ESERVICE-000405", imageNo, platform.getPlatformName());
        }

        // TODO: ??

        // ?????
        Instance checkInstance = instanceDao.readByFarmNoAndInstanceName(farmNo, instanceName);
        if (checkInstance != null) {
            // ???????
            throw new AutoApplicationException("ESERVICE-000401", instanceName);
        }

        // ?????
        LoadBalancer checkLoadBalancer = loadBalancerDao.readByFarmNoAndLoadBalancerName(farmNo, instanceName);
        if (checkLoadBalancer != null) {
            // ????????
            throw new AutoApplicationException("ESERVICE-000417", instanceName);
        }

        // ??
        Farm farm = farmDao.read(farmNo);
        if (farm == null) {
            throw new AutoApplicationException("ESERVICE-000406", farmNo);
        }

        // fqdn???
        String fqdn = instanceName + "." + farm.getDomainName();
        if (fqdn.length() > 63) {
            throw new AutoApplicationException("ESERVICE-000418", fqdn);
        }

        // TODO: ??

        // VMware??Windows???VMware??????Windows????????
        // TODO: OS??
        if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType())
                && StringUtils.startsWithIgnoreCase(image.getOs(), PCCConstant.OS_NAME_WIN)) {
            List<Instance> allInstances = instanceDao.readAll();
            for (Instance instance2 : allInstances) {
                if (StringUtils.equals(instanceName, instance2.getInstanceName())) {
                    Platform platform2 = platformDao.read(instance2.getPlatformNo());
                    if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform2.getPlatformType())) {
                        Image image2 = imageDao.read(instance2.getImageNo());
                        if (StringUtils.startsWithIgnoreCase(image2.getOs(), PCCConstant.OS_NAME_WIN)) {
                            // VMware?????Windows???
                            throw new AutoApplicationException("ESERVICE-000419", instanceName);
                        }
                    }
                }
            }
        }

        // ??
        String instanceCode = passwordGenerator.generate(20);

        // ??
        Instance instance = new Instance();
        instance.setFarmNo(farmNo);
        instance.setInstanceName(instanceName);
        instance.setPlatformNo(platformNo);
        instance.setImageNo(imageNo);
        instance.setEnabled(false);
        instance.setComment(comment);
        instance.setFqdn(fqdn);
        instance.setInstanceCode(instanceCode);
        instance.setStatus(InstanceStatus.STOPPED.toString());
        instanceDao.create(instance);

        // TODO: OS??
        if (!StringUtils.startsWithIgnoreCase(image.getOs(), PCCConstant.OS_NAME_WIN)
                || (StringUtils.startsWithIgnoreCase(image.getOs(), PCCConstant.OS_NAME_WIN)
                        && PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType()))
                || (StringUtils.startsWithIgnoreCase(image.getOs(), PCCConstant.OS_NAME_WIN)
                        && PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType()))
                || (StringUtils.startsWithIgnoreCase(image.getOs(), PCCConstant.OS_NAME_WIN)
                        && PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType()))) {
            // OpenStack?Puppet?????
            //if (!PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
            // Puppet??
            PuppetInstance puppetInstance = new PuppetInstance();
            puppetInstance.setInstanceNo(instance.getInstanceNo());
            puppetInstanceDao.create(puppetInstance);
            //}
        }

        Boolean useZabbix = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useZabbix"));
        if (BooleanUtils.isTrue(useZabbix)) {
            // Zabbix??
            ZabbixInstance zabbixInstance = new ZabbixInstance();
            zabbixInstance.setInstanceNo(instance.getInstanceNo());
            zabbixInstanceDao.create(zabbixInstance);
        }

        return instance.getInstanceNo();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Long createIaasInstance(Long farmNo, String instanceName, Long platformNo, String comment, Long imageNo,
            String instanceType) {
        // ??
        Long instanceNo = createInstance(farmNo, instanceName, platformNo, comment, imageNo);

        // ??
        Platform platform = platformDao.read(platformNo);
        if (!PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())
                && !PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType())
                && !PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())
                && !PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())
                && !PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
            throw new AutoApplicationException("ESERVICE-000404", instanceName);
        }

        //??
        Farm farm = farmDao.read(farmNo);
        // TODO CLOUD BRANCHING
        if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
            PlatformAws platformAws = platformAwsDao.read(platformNo);
            makeAwsData(farm, instanceNo, instanceType, platformAws);
        } else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType())) {
            PlatformCloudstack platformCloudstack = platformCloudstackDao.read(platformNo);
            makeCloudStackData(farm, instanceNo, instanceType, platformCloudstack);
        } else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())) {
            PlatformVcloud platformVcloud = platformVcloudDao.read(platformNo);
            makeVcloudData(farm, instanceNo, instanceName, instanceType, platformVcloud);
        } else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
            PlatformAzure platformAzure = platformAzureDao.read(platformNo);
            makeAzureData(farm, instanceNo, instanceType, platformAzure);
        } else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
            PlatformOpenstack platformOpenstack = platformOpenstackDao.read(platformNo);
            makeOpenstackData(farm, instanceNo, instanceType, platformOpenstack);
        }

        // 
        eventLogger.log(EventLogLevel.INFO, farmNo, farm.getFarmName(), null, null, instanceNo, instanceName,
                "InstanceCreate", instanceType, platformNo, new Object[] { platform.getPlatformName() });

        return instanceNo;
    }

    private void makeAwsData(Farm farm, Long instanceNo, String instanceType, PlatformAws platformAws) {

        // ?
        try {
            InstanceType.fromValue(instanceType);
        } catch (IllegalArgumentException e) {
            throw new AutoApplicationException("ECOMMON-000001", "instanceType");
        }

        // AWS??
        AwsInstance awsInstance = new AwsInstance();
        awsInstance.setInstanceNo(instanceNo);
        awsInstance.setInstanceType(instanceType);

        //KeyName
        AwsCertificate awsCertificate = awsCertificateDao.read(farm.getUserNo(), platformAws.getPlatformNo());
        //??
        List<KeyPairDto> keyPairInfos = iaasDescribeService.getKeyPairs(farm.getUserNo(),
                platformAws.getPlatformNo());
        String keyName = null;
        // AWS?????
        for (KeyPairDto keyPairDto : keyPairInfos) {
            if (StringUtils.equals(awsCertificate.getDefKeypair(), keyPairDto.getKeyName())) {
                keyName = keyPairDto.getKeyName();
                break;
            }
        }
        if (keyName == null && keyPairInfos.size() > 0) {
            //??????1
            keyName = keyPairInfos.get(0).getKeyName();
        }
        awsInstance.setKeyName(keyName);

        String subnetId = null;
        if (platformAws.getEuca() == false && platformAws.getVpc()) {
            // VPC??
            // SubnetId & AvailabilityZone
            List<SubnetDto> subnets = iaasDescribeService.getSubnets(farm.getUserNo(), platformAws.getPlatformNo(),
                    platformAws.getVpcId());
            SubnetDto subnet = null;
            for (SubnetDto subnetDto : subnets) {
                //?
                if (StringUtils.equals(awsCertificate.getDefSubnet(), subnetDto.getSubnetId())
                        && StringUtils.equals(platformAws.getAvailabilityZone(), subnetDto.getZoneid())) {
                    //?????
                    subnet = subnetDto;
                    break;
                }
            }
            if (subnet != null) {
                subnetId = subnet.getSubnetId();
                awsInstance.setSubnetId(subnetId);
                awsInstance.setAvailabilityZone(subnet.getZoneid());
            }
        } else {
            // VPC????
            // AvailabilityZone
            String zoneName = platformAws.getAvailabilityZone();
            if (StringUtils.isEmpty(zoneName) && platformAws.getEuca()) {
                // ?????????Eucalyptus????API?????
                List<ZoneDto> availabilityZones = iaasDescribeService.getAvailabilityZones(farm.getUserNo(),
                        platformAws.getPlatformNo());

                zoneName = availabilityZones.get(0).getZoneName();
            }
            awsInstance.setAvailabilityZone(zoneName);
        }

        // SecurityGroup
        String groupName = null;
        List<SecurityGroupDto> securityGroups = null;
        if (platformAws.getEuca() == false && platformAws.getVpc()) {
            // VPC??
            securityGroups = iaasDescribeService.getSecurityGroups(farm.getUserNo(), platformAws.getPlatformNo(),
                    platformAws.getVpcId());
        } else {
            // VPC????
            securityGroups = iaasDescribeService.getSecurityGroups(farm.getUserNo(), platformAws.getPlatformNo(),
                    null);
        }

        groupName = setSecurityGroup(securityGroups, "aws.defaultSecurityGroup");

        awsInstance.setSecurityGroups(groupName);

        awsInstanceDao.create(awsInstance);
    }

    /**
     * 
     *
     * ??????????
     *
     * ?configKey??????????
     * ??????
     * ?configKey?????(?????????)?
     * ??"default"?????"default"?
     * ???????????????
     * ??
     *
     * @param securityGroups ????
     * @param configKey config.properties???
     * @return
     */
    protected String setSecurityGroup(List<SecurityGroupDto> securityGroups, String configKey) {

        String groupName = null;
        String defaultSecurityGroup = StringUtils.defaultIfEmpty(Config.getProperty(configKey), "default");

        // ?
        if (!defaultSecurityGroup.equals("default")) {
            for (SecurityGroupDto securityGroup : securityGroups) {
                if (defaultSecurityGroup.equals(securityGroup.getGroupName())) {
                    groupName = securityGroup.getGroupName();
                    break;
                }
            }
        }

        // ?("groupName == null"????)
        if (groupName == null) {
            for (SecurityGroupDto securityGroup : securityGroups) {
                if ("default".equals(securityGroup.getGroupName())) {
                    groupName = securityGroup.getGroupName();
                    break;
                }
            }
        }

        // ?
        if (groupName == null && securityGroups.size() > 0) {
            groupName = securityGroups.get(0).getGroupName();
        }
        return groupName;
    }

    private void makeCloudStackData(Farm farm, Long instanceNo, String instanceType,
            PlatformCloudstack platformCloudstack) {

        // AWS??
        CloudstackInstance cloudstackInstance = new CloudstackInstance();
        cloudstackInstance.setInstanceNo(instanceNo);
        cloudstackInstance.setInstanceType(instanceType);

        //KeyName
        //Cloudstack???
        CloudstackCertificate cloudstackCertificate = cloudstackCertificateDao.read(farm.getUserNo(),
                platformCloudstack.getPlatformNo());
        //??
        List<KeyPairDto> keyPairInfos = iaasDescribeService.getKeyPairs(farm.getUserNo(),
                platformCloudstack.getPlatformNo());
        String keyName = null;
        // CLOUDSTACK?????
        for (KeyPairDto keyPairDto : keyPairInfos) {
            if (StringUtils.equals(cloudstackCertificate.getDefKeypair(), keyPairDto.getKeyName())) {
                keyName = keyPairDto.getKeyName();
                break;
            }
        }
        if (keyName == null && keyPairInfos.size() > 0) {
            //??????1
            keyName = keyPairInfos.get(0).getKeyName();
        }
        cloudstackInstance.setKeyName(keyName);

        //TODO ZONEID, NETWORKID, SECURITYGROUP ???????@@???????
        String zoneId = platformCloudstack.getZoneId();
        String[] networks = platformCloudstack.getNetworkId().split(",");
        String netId = networks[0];

        cloudstackInstance.setZoneid(zoneId);
        cloudstackInstance.setNetworkid(netId);

        String groupName = null;
        List<SecurityGroupDto> securityGroups = iaasDescribeService.getSecurityGroups(farm.getUserNo(),
                platformCloudstack.getPlatformNo(), null);

        groupName = setSecurityGroup(securityGroups, "cloudStack.defaultSecurityGroup");

        cloudstackInstance.setSecuritygroup(groupName);

        cloudstackInstanceDao.create(cloudstackInstance);
    }

    private void makeVcloudData(Farm farm, Long instanceNo, String instanceName, String instanceType,
            PlatformVcloud platformVcloud) {

        // VCloud??
        VcloudInstance vcloudInstance = new VcloudInstance();
        vcloudInstance.setInstanceNo(instanceNo);

        //VM??
        //????????????NULL
        //(VCloud???????????)
        vcloudInstance.setVmName(null);

        //
        //???????
        List<VcloudKeyPair> vcloudKeyPairs = vcloudKeyPairDao.readByUserNoAndPlatformNo(farm.getUserNo(),
                platformVcloud.getPlatformNo());
        Long keyPairNo = vcloudKeyPairs.get(0).getKeyNo();
        vcloudInstance.setKeyPairNo(keyPairNo);

        //
        List<PlatformVcloudStorageType> storageTypes = platformVcloudStorageTypeDao
                .readByPlatformNo(platformVcloud.getPlatformNo());
        Collections.sort(storageTypes, Comparators.COMPARATOR_PLATFORM_VCLOUD_STORAGE_TYPE);
        vcloudInstance.setStorageTypeNo(storageTypes.get(0).getStorageTypeNo());

        //
        vcloudInstance.setInstanceType(instanceType);

        //VCLOUD_INSTANCE?
        vcloudInstanceDao.create(vcloudInstance);

        //?
        //???PCC??????
        //IaasGateWay???PCC????
        //VCLOUD_INSTANCE_NETWORKPCC???
        Boolean showPublicIp = BooleanUtils.toBooleanObject(Config.getProperty("ui.showPublicIp"));
        List<NetworkDto> networkDtos = iaasDescribeService.getNetworks(farm.getUserNo(),
                platformVcloud.getPlatformNo());
        for (int i = 0; i < networkDtos.size(); i++) {
            NetworkDto networkDto = networkDtos.get(i);
            //PCC?? ????
            //???IaasGateWay?????NULL
            //IP???????IaasGateWay?????NULL
            //PCC?????????1???
            if (networkDto.isPcc() || (!networkDto.isPcc()
                    && StringUtils.equals(networkDto.getNetworkName(), platformVcloud.getDefNetwork()))) {
                VcloudInstanceNetwork vcloudInstanceNetwork = new VcloudInstanceNetwork();
                vcloudInstanceNetwork.setPlatformNo(platformVcloud.getPlatformNo());
                vcloudInstanceNetwork.setInstanceNo(instanceNo);
                vcloudInstanceNetwork.setFarmNo(farm.getFarmNo());
                vcloudInstanceNetwork.setNetworkName(networkDto.getNetworkName());
                vcloudInstanceNetwork.setNetworkIndex(null);
                vcloudInstanceNetwork.setIpMode("POOL");
                vcloudInstanceNetwork.setIpAddress(null);
                //config.properties?showPublicIp?= true   PCC??
                //config.properties?showPublicIp?= false  ?(?)?
                if (networkDto.isPcc()) {
                    vcloudInstanceNetwork.setIsPrimary(BooleanUtils.isTrue(showPublicIp));
                } else if (StringUtils.equals(networkDto.getNetworkName(), platformVcloud.getDefNetwork())) {
                    vcloudInstanceNetwork.setIsPrimary(BooleanUtils.isNotTrue(showPublicIp));
                }
                //VCLOUD_INSTANCE_NETWORK?
                vcloudInstanceNetworkDao.create(vcloudInstanceNetwork);
            }
        }
    }

    private void makeAzureData(Farm farm, Long instanceNo, String instanceType, PlatformAzure platformAzure) {

        // Azure??
        AzureInstance azureInstance = new AzureInstance();
        azureInstance.setInstanceNo(instanceNo);

        // AFFINITY_GROUP_NAME
        String affinityGroupName = platformAzure.getAffinityGroupName();
        azureInstance.setAffinityGroupName(affinityGroupName);
        // CLOUD_SERVICE_NAME
        String cloudServiceName = platformAzure.getCloudServiceName();
        azureInstance.setCloudServiceName(cloudServiceName);
        // STORAGE_ACCOUNT_NAME
        String storageAccountName = platformAzure.getStorageAccountName();
        azureInstance.setStorageAccountName(storageAccountName);
        // NETWORK_NAME
        String networkName = platformAzure.getNetworkName();
        azureInstance.setNetworkName(networkName);
        // INSTANCE_TYPE
        azureInstance.setInstanceType(instanceType);
        // SUBNET_ID
        String subnetId = null;
        // AzureCertificate?
        AzureCertificate azureCertificate = azureCertificateDao.read(farm.getUserNo(),
                platformAzure.getPlatformNo());
        // SubnetId
        List<SubnetDto> subnets = iaasDescribeService.getAzureSubnets(farm.getUserNo(),
                platformAzure.getPlatformNo(), platformAzure.getNetworkName());
        SubnetDto subnet = null;
        for (SubnetDto subnetDto : subnets) {
            // ?
            if (StringUtils.equals(azureCertificate.getDefaultSubnetId(), subnetDto.getSubnetId())) {
                // ????
                subnet = subnetDto;
                break;
            }
        }
        if (subnet == null && subnets.size() > 0) {
            //???????1
            subnet = subnets.get(0);
        }
        if (subnet != null) {
            subnetId = subnet.getSubnetId();
            azureInstance.setSubnetId(subnetId);
        }
        // ?
        // DB??????1??
        if (StringUtils.isNotEmpty(platformAzure.getAvailabilitySets())) {
            String[] availabilitySets = StringUtils.split(platformAzure.getAvailabilitySets(), ",");
            azureInstance.setAvailabilitySet(availabilitySets[0].trim());
        }
        azureInstanceDao.create(azureInstance);
    }

    private void makeOpenstackData(Farm farm, Long instanceNo, String instanceType,
            PlatformOpenstack platformOpenstack) {

        // Openstack??
        OpenstackInstance openstackInstance = new OpenstackInstance();
        //INSTANCE_NO
        openstackInstance.setInstanceNo(instanceNo);
        //KEY_NAME
        OpenstackCertificate openstackCertificate = openstackCertificateDao.read(farm.getUserNo(),
                platformOpenstack.getPlatformNo());
        openstackInstance.setKeyName(openstackCertificate.getDefKeypair());
        //INSTANCE_TYPE
        openstackInstance.setInstanceType(instanceType);
        //SECURITY_GROUPS
        String groupName = null;
        List<SecurityGroupDto> securityGroups = iaasDescribeService.getSecurityGroups(farm.getUserNo(),
                platformOpenstack.getPlatformNo(), null);
        groupName = setSecurityGroup(securityGroups, "openStack.defaultSecurityGroup");
        openstackInstance.setSecurityGroups(groupName);
        //AVAILABILITY_ZONE
        String zoneName = platformOpenstack.getAvailabilityZone();
        if (StringUtils.isEmpty(zoneName)) {
            // ??????????
            List<ZoneDto> availabilityZones = iaasDescribeService.getAvailabilityZones(farm.getUserNo(),
                    platformOpenstack.getPlatformNo());
            zoneName = availabilityZones.get(0).getZoneName();
        }
        openstackInstance.setAvailabilityZone(zoneName);
        //NETWORK_ID
        String[] networks = platformOpenstack.getNetworkId().split(",");
        String netId = networks[0];
        openstackInstance.setNetworkId(netId);

        openstackInstanceDao.create(openstackInstance);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Long createVmwareInstance(Long farmNo, String instanceName, Long platformNo, String comment,
            Long imageNo, String instanceType) {
        // ??
        Long instanceNo = createInstance(farmNo, instanceName, platformNo, comment, imageNo);

        // ?
        if (instanceType == null || instanceType.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceType");
        }

        // ??
        Platform platform = platformDao.read(platformNo);
        if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000408", instanceName);
        }
        PlatformVmware platformVmware = platformVmwareDao.read(platformNo);

        // VMware??
        VmwareInstance vmwareInstance = new VmwareInstance();
        vmwareInstance.setInstanceNo(instanceNo);

        // ??
        Farm farm = farmDao.read(farmNo);
        String machineName = farm.getFarmName() + "_" + instanceName;
        vmwareInstance.setMachineName(machineName);

        // InstanceType
        vmwareInstance.setInstanceType(instanceType);

        // ?
        String computeResource = platformVmware.getComputeResource();
        if (StringUtils.isEmpty(computeResource)) {
            List<ComputeResource> computeResources = vmwareDescribeService.getComputeResources(platformNo);
            computeResource = computeResources.get(0).getName();
        }
        vmwareInstance.setComputeResource(computeResource);

        // 
        // TODO: ?????
        String resourcePool = null;
        vmwareInstance.setResourcePool(resourcePool);

        // ???????
        String datastore = null;
        vmwareInstance.setDatastore(datastore);

        // 
        List<VmwareKeyPair> vmwareKeyPairs = vmwareKeyPairDao.readByUserNoAndPlatformNo(farm.getUserNo(),
                platformNo);
        Long keyPairNo = vmwareKeyPairs.get(0).getKeyNo();
        vmwareInstance.setKeyPairNo(keyPairNo);

        vmwareInstanceDao.create(vmwareInstance);

        // 
        eventLogger.log(EventLogLevel.INFO, farmNo, farm.getFarmName(), null, null, instanceNo, instanceName,
                "InstanceCreate", instanceType, platformNo, new Object[] { platform.getPlatformName() });

        return instanceNo;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Long createNiftyInstance(Long farmNo, String instanceName, Long platformNo, String comment, Long imageNo,
            String instanceType) {
        // ??
        Long instanceNo = createInstance(farmNo, instanceName, platformNo, comment, imageNo);

        // ?
        if (instanceType == null || instanceType.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceType");
        }

        // ??
        Platform platform = platformDao.read(platformNo);
        if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000410", instanceName);
        }

        // Nifty??
        NiftyInstance niftyInstance = new NiftyInstance();
        niftyInstance.setInstanceNo(instanceNo);
        niftyInstance.setInstanceType(instanceType);

        Farm farm = farmDao.read(farmNo);
        List<NiftyKeyPair> niftyKeyPairs = niftyKeyPairDao.readByUserNoAndPlatformNo(farm.getUserNo(), platformNo);
        niftyInstance.setKeyPairNo(niftyKeyPairs.get(0).getKeyNo());

        niftyInstanceDao.create(niftyInstance);

        // 
        eventLogger.log(EventLogLevel.INFO, farmNo, farm.getFarmName(), null, null, instanceNo, instanceName,
                "InstanceCreate", instanceType, platformNo, new Object[] { platform.getPlatformName() });

        return instanceNo;
    }

    protected void updateInstance(Long instanceNo, String instanceName, String comment) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }
        if (instanceName == null || instanceName.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceName");
        }

        // ??
        if (!Pattern.matches("^[0-9a-z]|[0-9a-z][0-9a-z-]*[0-9a-z]$", instanceName)) {
            throw new AutoApplicationException("ECOMMON-000012", "instanceName");
        }

        // TODO: ??

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            // ?????
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??????
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!StringUtils.equals(instance.getInstanceName(), instanceName)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
        }

        // ????
        if (!StringUtils.equals(instance.getInstanceName(), instanceName)) {
            // ?????
            Instance checkInstance = instanceDao.readByFarmNoAndInstanceName(instance.getFarmNo(), instanceName);
            if (checkInstance != null && !instanceNo.equals(checkInstance.getInstanceNo())) {
                // ???????
                throw new AutoApplicationException("ESERVICE-000401", instanceName);
            }

            // ?????
            LoadBalancer checkLoadBalancer = loadBalancerDao.readByFarmNoAndLoadBalancerName(instance.getFarmNo(),
                    instanceName);
            if (checkLoadBalancer != null) {
                // ????????
                throw new AutoApplicationException("ESERVICE-000417", instanceName);
            }
        }

        // ?
        Farm farm = farmDao.read(instance.getFarmNo());

        instance.setInstanceName(instanceName);
        instance.setComment(comment);
        instance.setFqdn(instanceName + "." + farm.getDomainName());
        instanceDao.update(instance);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateAwsInstance(Long instanceNo, String instanceName, String comment, String keyName,
            String instanceType, String securityGroupName, String availabilityZoneName, Long addressNo,
            String subnetId, String privateIpAddress) {
        // ?
        updateInstance(instanceNo, instanceName, comment);

        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }
        if (keyName == null || keyName.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "keyName");
        }
        try {
            InstanceType.fromValue(instanceType);
        } catch (IllegalArgumentException e) {
            throw new AutoApplicationException("ECOMMON-000001", "instanceType");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000404", instance.getInstanceName());
        }

        //?
        Farm farm = farmDao.read(instance.getFarmNo());

        // ??????
        AwsInstance awsInstance = awsInstanceDao.read(instanceNo);
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!StringUtils.equals(awsInstance.getKeyName(), keyName)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!StringUtils.equals(awsInstance.getInstanceType(), instanceType)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (StringUtils.isEmpty(awsInstance.getSecurityGroups()) ? StringUtils.isNotEmpty(securityGroupName)
                    : !StringUtils.equals(awsInstance.getSecurityGroups(), securityGroupName)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (StringUtils.isEmpty(awsInstance.getAvailabilityZone())
                    ? StringUtils.isNotEmpty(availabilityZoneName)
                    : !StringUtils.equals(awsInstance.getAvailabilityZone(), availabilityZoneName)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (StringUtils.isEmpty(awsInstance.getSubnetId()) ? StringUtils.isNotEmpty(subnetId)
                    : !StringUtils.equals(awsInstance.getSubnetId(), subnetId)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (StringUtils.isEmpty(awsInstance.getPrivateIpAddress()) ? StringUtils.isNotEmpty(privateIpAddress)
                    : !StringUtils.equals(awsInstance.getPrivateIpAddress(), privateIpAddress)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
        }

        // ??
        if (StringUtils.isEmpty(awsInstance.getSubnetId()) && StringUtils.isEmpty(securityGroupName)) {
            throw new AutoApplicationException("ECOMMON-000003", "securityGroupName");
        }

        // ??
        PlatformAws platformAws = platformAwsDao.read(instance.getPlatformNo());
        if (platformAws.getEuca() == false && platformAws.getVpc()) {
            if (StringUtils.equals(awsInstance.getSubnetId(), subnetId) == false) {
                //VPC????????????
                if (awsVolumeDao.countByInstanceNo(instanceNo) > 0) {
                    // EBS???()?????
                    throw new AutoApplicationException("ESERVICE-000421");
                }
            }
        } else {
            if (StringUtils.isEmpty(awsInstance.getAvailabilityZone())
                    ? StringUtils.isNotEmpty(availabilityZoneName)
                    : !StringUtils.equals(awsInstance.getAvailabilityZone(), availabilityZoneName)) {
                if (awsVolumeDao.countByInstanceNo(instanceNo) > 0) {
                    // EBS???????
                    throw new AutoApplicationException("ESERVICE-000412");
                }
            }
        }

        //???
        if (StringUtils.isNotEmpty(subnetId) && StringUtils.isNotEmpty(privateIpAddress)) {
            //AWS_INSTANCE?subnet??
            List<Instance> instances = instanceDao.readByFarmNo(farm.getFarmNo());
            List<Long> instanceNos = new ArrayList<Long>();
            for (Instance tmpInstance : instances) {
                if (instanceNo.equals(tmpInstance.getInstanceNo()) == false) {
                    instanceNos.add(tmpInstance.getInstanceNo());
                }
            }
            List<AwsInstance> awsInstances = awsInstanceDao.readInInstanceNos(instanceNos);
            for (AwsInstance tmpAwsInstance : awsInstances) {
                if (subnetId.equals(tmpAwsInstance.getSubnetId())
                        && privateIpAddress.equals(tmpAwsInstance.getPrivateIpAddress())) {
                    //??subnetId???privateIpAddress??AWS_INSTANCE???
                    throw new AutoApplicationException("ESERVICE-000420", privateIpAddress);
                }
            }
        }

        // AWS??
        AwsAddress awsAddress = null;
        if (addressNo != null) {
            // AWS??
            awsAddress = awsAddressDao.read(addressNo);
            if (awsAddress == null) {
                throw new AutoApplicationException("ESERVICE-000415", addressNo);
            }

            // ????????????
            if (awsAddress.getInstanceNo() != null && !instanceNo.equals(awsAddress.getInstanceNo())) {
                // ??????
                throw new AutoApplicationException("ESERVICE-000416", awsAddress.getPublicIp());
            }
        }

        // AWS?
        awsInstance.setKeyName(keyName);
        awsInstance.setInstanceType(instanceType);
        awsInstance.setSecurityGroups(securityGroupName);
        awsInstance.setAvailabilityZone(availabilityZoneName);
        awsInstance.setSubnetId(subnetId);
        awsInstance.setPrivateIpAddress(privateIpAddress);
        awsInstanceDao.update(awsInstance);

        // ?AWS????????
        List<AwsAddress> awsAddresses = awsAddressDao.readByInstanceNo(instanceNo);
        for (AwsAddress address : awsAddresses) {
            if (address.getAddressNo().equals(addressNo)) {
                continue;
            }
            address.setInstanceNo(null);
            awsAddressDao.update(address);
        }

        // AWS??
        if (addressNo != null && !instanceNo.equals(awsAddress.getInstanceNo())) {
            awsAddress.setInstanceNo(instanceNo);
            awsAddressDao.update(awsAddress);
        }

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instanceName, "InstanceUpdate", instanceType, instance.getPlatformNo(), null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateCloudstackInstance(Long instanceNo, String instanceName, String comment, String keyName,
            String instanceType, String securityGroupName, String zoneid, Long addressNo) {
        // ?
        updateInstance(instanceNo, instanceName, comment);

        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000404", instance.getInstanceName());
        }

        // ??????
        CloudstackInstance cloudstackInstance = cloudstackInstanceDao.read(instanceNo);
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!StringUtils.equals(cloudstackInstance.getKeyName(), keyName)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!StringUtils.equals(cloudstackInstance.getInstanceType(), instanceType)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (StringUtils.isEmpty(cloudstackInstance.getSecuritygroup())
                    ? StringUtils.isNotEmpty(securityGroupName)
                    : !StringUtils.equals(cloudstackInstance.getSecuritygroup(), securityGroupName)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (StringUtils.isEmpty(cloudstackInstance.getZoneid()) ? StringUtils.isNotEmpty(zoneid)
                    : !StringUtils.equals(cloudstackInstance.getZoneid(), zoneid)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
        }

        // ??
        if (StringUtils.isEmpty(cloudstackInstance.getZoneid()) ? StringUtils.isNotEmpty(zoneid)
                : !StringUtils.equals(cloudstackInstance.getZoneid(), zoneid)) {
            if (cloudstackVolumeDao.countByInstanceNo(instanceNo) > 0) {
                // EBS???????
                throw new AutoApplicationException("ESERVICE-000412", instance.getInstanceName());
            }
        }

        //??
        CloudstackAddress cloudstackAddress = null;
        if (addressNo != null) {
            // ??
            cloudstackAddress = cloudstackAddressDao.read(addressNo);
            if (cloudstackAddress == null) {
                throw new AutoApplicationException("ESERVICE-000415", addressNo);
            }

            // ????????????
            if (cloudstackAddress.getInstanceNo() != null
                    && !instanceNo.equals(cloudstackAddress.getInstanceNo())) {
                // ??????
                throw new AutoApplicationException("ESERVICE-000416", cloudstackAddress.getIpaddress());
            }
        }

        // ?
        cloudstackInstance.setKeyName(keyName);
        cloudstackInstance.setInstanceType(instanceType);
        cloudstackInstance.setSecuritygroup(securityGroupName);
        cloudstackInstance.setZoneid(zoneid);
        cloudstackInstanceDao.update(cloudstackInstance);

        // ?????????
        List<CloudstackAddress> cloudstackAddresses = cloudstackAddressDao.readByInstanceNo(instanceNo);
        for (CloudstackAddress address : cloudstackAddresses) {
            if (address.getAddressNo().equals(addressNo)) {
                continue;
            }
            address.setInstanceNo(null);
            cloudstackAddressDao.update(address);
        }

        // ??
        if (addressNo != null && !instanceNo.equals(cloudstackAddress.getInstanceNo())) {
            cloudstackAddress.setInstanceNo(instanceNo);
            cloudstackAddressDao.update(cloudstackAddress);
        }

        // 
        Farm farm = farmDao.read(instance.getFarmNo());
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instanceName, "InstanceUpdate", instanceType, instance.getPlatformNo(), null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateVcloudInstance(Long instanceNo, String instanceName, String comment, Long storageTypeNo,
            Long keyPairNo, String instanceType, List<InstanceNetworkDto> instanceNetworkDtos) {
        // ?
        updateInstance(instanceNo, instanceName, comment);

        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (!PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())) {
            throw new AutoApplicationException("ESERVICE-000428", instance.getInstanceName());
        }

        // ??????
        VcloudInstance vcloudInstance = vcloudInstanceDao.read(instanceNo);
        List<VcloudInstanceNetwork> vcloudInstanceNetworks = vcloudInstanceNetworkDao.readByInstanceNo(instanceNo);
        Map<Long, VcloudInstanceNetwork> vcloudInstanceNetworkMap = new LinkedHashMap<Long, VcloudInstanceNetwork>();
        for (VcloudInstanceNetwork vcloudInstanceNetwork : vcloudInstanceNetworks) {
            vcloudInstanceNetworkMap.put(vcloudInstanceNetwork.getNetworkNo(), vcloudInstanceNetwork);
        }
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!vcloudInstance.getStorageTypeNo().equals(storageTypeNo)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!vcloudInstance.getKeyPairNo().equals(keyPairNo)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!StringUtils.equals(vcloudInstance.getInstanceType(), instanceType)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            for (InstanceNetworkDto instanceNetworkDto : instanceNetworkDtos) {
                if (instanceNetworkDto.isNew()) {
                    //?????
                    throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
                } else if (instanceNetworkDto.isDelete()) {
                    //????
                    throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
                } else {
                    VcloudInstanceNetwork oldVcloudInstanceNetwork = vcloudInstanceNetworkMap
                            .get(instanceNetworkDto.getNetworkNo());
                    if (!StringUtils.equals(oldVcloudInstanceNetwork.getIpMode(), instanceNetworkDto.getIpMode())
                            || !StringUtils.equals(oldVcloudInstanceNetwork.getIpAddress(),
                                    instanceNetworkDto.getIpAddress())) {
                        //????
                        throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
                    }
                }
            }
        }

        Farm farm = farmDao.read(instance.getFarmNo());

        // VCloud?
        vcloudInstance.setStorageTypeNo(storageTypeNo);
        vcloudInstance.setKeyPairNo(keyPairNo);
        vcloudInstance.setInstanceType(instanceType);
        vcloudInstanceDao.update(vcloudInstance);

        //VCloudInstanceNetwork?
        for (InstanceNetworkDto instanceNetworkDto : instanceNetworkDtos) {
            if (instanceNetworkDto.isNew()) {
                //?
                VcloudInstanceNetwork vcloudInstanceNetwork = new VcloudInstanceNetwork();
                vcloudInstanceNetwork.setNetworkName(instanceNetworkDto.getNetworkName());
                // ??IaasGateWay???????????NULL
                vcloudInstanceNetwork.setNetworkIndex(null);
                vcloudInstanceNetwork.setPlatformNo(platform.getPlatformNo());
                vcloudInstanceNetwork.setFarmNo(instance.getFarmNo());
                vcloudInstanceNetwork.setInstanceNo(instanceNo);
                vcloudInstanceNetwork.setIpMode(instanceNetworkDto.getIpMode());
                vcloudInstanceNetwork.setIpAddress(instanceNetworkDto.getIpAddress());
                vcloudInstanceNetwork.setIsPrimary(instanceNetworkDto.isPrimary());
                vcloudInstanceNetworkDao.create(vcloudInstanceNetwork);
            } else if (instanceNetworkDto.isDelete()) {
                //
                VcloudInstanceNetwork vcloudInstanceNetwork = vcloudInstanceNetworkMap
                        .get(instanceNetworkDto.getNetworkNo());
                vcloudInstanceNetworkDao.delete(vcloudInstanceNetwork);
            } else {
                //
                VcloudInstanceNetwork vcloudInstanceNetwork = vcloudInstanceNetworkMap
                        .get(instanceNetworkDto.getNetworkNo());
                vcloudInstanceNetwork.setIpMode(instanceNetworkDto.getIpMode());
                vcloudInstanceNetwork.setIpAddress(instanceNetworkDto.getIpAddress());
                vcloudInstanceNetwork.setIsPrimary(instanceNetworkDto.isPrimary());
                vcloudInstanceNetworkDao.update(vcloudInstanceNetwork);
            }
        }

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instanceName, "InstanceUpdate", instanceType, instance.getPlatformNo(), null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateAzureInstance(Long instanceNo, String instanceName, String comment, String instanceType,
            String availabilitySet, String subnetId) {
        // ?
        updateInstance(instanceNo, instanceName, comment);

        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000404", instance.getInstanceName());
        }

        //?
        Farm farm = farmDao.read(instance.getFarmNo());

        // ??????
        AzureInstance azureInstance = azureInstanceDao.read(instanceNo);
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!StringUtils.equals(azureInstance.getInstanceType(), instanceType)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!StringUtils.equals(azureInstance.getAvailabilitySet(), availabilitySet)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!StringUtils.equals(azureInstance.getSubnetId(), subnetId)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
        }

        // Azure?
        azureInstance.setInstanceType(instanceType);
        azureInstance.setAvailabilitySet(availabilitySet);
        azureInstance.setSubnetId(subnetId);
        azureInstanceDao.update(azureInstance);

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instanceName, "InstanceUpdate", instanceType, instance.getPlatformNo(), null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateOpenStackInstance(Long instanceNo, String instanceName, String comment, String instanceType,
            String availabilityZoneName, String securityGroupName, String keyName) {
        // ?
        updateInstance(instanceNo, instanceName, comment);

        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000404", instance.getInstanceName());
        }

        //?
        Farm farm = farmDao.read(instance.getFarmNo());

        // ??????
        OpenstackInstance openstackInstance = openstackInstanceDao.read(instanceNo);
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!StringUtils.equals(openstackInstance.getInstanceType(), instanceType)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
        }

        // Openstack?
        openstackInstance.setInstanceType(instanceType);
        openstackInstance.setAvailabilityZone(availabilityZoneName);
        openstackInstance.setKeyName(keyName);
        openstackInstance.setSecurityGroups(securityGroupName);
        openstackInstanceDao.update(openstackInstance);

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instanceName, "InstanceUpdate", instanceType, instance.getPlatformNo(), null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Long createDataDisk(Long instanceNo, DataDiskDto dataDiskDto) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        //?
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED
                && InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.RUNNING) {
            //??? or ????
            throw new AutoApplicationException("ESERVICE-000429", instance.getInstanceName());
        }

        //?
        VcloudDisk vcloudDisk = new VcloudDisk();
        vcloudDisk.setFarmNo(instance.getFarmNo());
        vcloudDisk.setPlatformNo(instance.getPlatformNo());
        vcloudDisk.setComponentNo(null);
        vcloudDisk.setInstanceNo(instanceNo);
        vcloudDisk.setSize(dataDiskDto.getDiskSize());
        //UNIT NO?IaasGateWay??????????NULL?
        vcloudDisk.setUnitNo(null);
        vcloudDisk.setAttached(false);
        vcloudDisk.setDataDisk(true);
        vcloudDiskDao.create(vcloudDisk);

        return vcloudDisk.getDiskNo();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateDataDisk(Long instanceNo, DataDiskDto dataDiskDto) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        //?
        VcloudDisk vcloudDisk = vcloudDiskDao.read(dataDiskDto.getDiskNo());
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED
                && InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.RUNNING) {
            //??? or ????
            if (!vcloudDisk.getSize().equals(dataDiskDto.getDiskSize())) {
                //????
                throw new AutoApplicationException("ESERVICE-000429", instance.getInstanceName());
            }
        }

        //
        vcloudDisk.setSize(dataDiskDto.getDiskSize());
        vcloudDiskDao.update(vcloudDisk);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void attachDataDisk(Long instanceNo, Long diskNo) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        //?
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED
                && InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.RUNNING) {
            //??? or ????
            throw new AutoApplicationException("ESERVICE-000429", instance.getInstanceName());
        }

        //IaasGateWay?
        VcloudDisk vcloudDisk = vcloudDiskDao.read(diskNo);
        VcloudInstance vcloudInstance = vcloudInstanceDao.read(instanceNo);
        if (StringUtils.isNotEmpty(vcloudInstance.getVmName())) {
            //VCloud???????????
            Farm farm = farmDao.read(instance.getFarmNo());
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    instance.getPlatformNo());

            //IaasGateWay?
            gateway.startVolume(instanceNo, vcloudDisk.getDiskNo());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void detachDataDisk(Long instanceNo, Long diskNo) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        //?
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED
                && InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.RUNNING) {
            //??? or ????
            throw new AutoApplicationException("ESERVICE-000429", instance.getInstanceName());
        }

        //IaasGateWay?
        VcloudDisk vcloudDisk = vcloudDiskDao.read(diskNo);
        if (BooleanUtils.isTrue(vcloudDisk.getAttached())) {
            //???????????
            Farm farm = farmDao.read(instance.getFarmNo());
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    instance.getPlatformNo());
            // ?
            // VCloud??DiskNo
            gateway.deleteVolume(String.valueOf(vcloudDisk.getDiskNo()));
        }

        //
        vcloudDiskDao.delete(vcloudDisk);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateVmwareInstance(Long instanceNo, String instanceName, String comment, String instanceType,
            String computeResource, String resourcePool, Long keyPairNo) {
        updateVmwareInstance(instanceNo, instanceName, comment, instanceType, computeResource, resourcePool,
                keyPairNo, null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateVmwareInstance(Long instanceNo, String instanceName, String comment, String instanceType,
            String computeResource, String resourcePool, Long keyPairNo, VmwareAddressDto vmwareAddressDto) {
        // ?
        updateInstance(instanceNo, instanceName, comment);

        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }
        if (instanceType == null || instanceType.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceType");
        }
        if (computeResource == null || computeResource.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "computeResource");
        }
        if (keyPairNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "keyPairNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000408", instance.getInstanceName());
        }

        // ??????
        VmwareInstance vmwareInstance = vmwareInstanceDao.read(instanceNo);
        VmwareAddress vmwareAddress = vmwareAddressDao.readByInstanceNo(instanceNo);
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!StringUtils.equals(vmwareInstance.getInstanceType(), instanceType)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!StringUtils.equals(vmwareInstance.getComputeResource(), computeResource)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (StringUtils.isEmpty(vmwareInstance.getResourcePool()) ? StringUtils.isNotEmpty(resourcePool)
                    : !StringUtils.equals(vmwareInstance.getResourcePool(), resourcePool)) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (!keyPairNo.equals(vmwareInstance.getKeyPairNo())) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
            if (vmwareAddress == null || BooleanUtils.isNotTrue(vmwareAddress.getEnabled())) {
                if (vmwareAddressDto != null) {
                    throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
                }
            } else {
                if (vmwareAddressDto == null) {
                    throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
                } else if (!StringUtils.equals(vmwareAddress.getIpAddress(), vmwareAddressDto.getIpAddress())
                        || !StringUtils.equals(vmwareAddress.getSubnetMask(), vmwareAddressDto.getSubnetMask())
                        || !StringUtils.equals(vmwareAddress.getDefaultGateway(),
                                vmwareAddressDto.getDefaultGateway())) {
                    throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
                }
            }
        }

        // VMware?
        vmwareInstance.setInstanceType(instanceType);
        vmwareInstance.setComputeResource(computeResource);
        vmwareInstance.setResourcePool(resourcePool);
        vmwareInstance.setKeyPairNo(keyPairNo);
        vmwareInstanceDao.update(vmwareInstance);

        Farm farm = farmDao.read(instance.getFarmNo());

        // VmwareAddress?
        if (vmwareAddress == null) {
            if (vmwareAddressDto != null) {
                vmwareAddress = new VmwareAddress();
                vmwareAddress.setPlatformNo(instance.getPlatformNo());
                vmwareAddress.setIpAddress(vmwareAddressDto.getIpAddress());
                vmwareAddress.setSubnetMask(vmwareAddressDto.getSubnetMask());
                vmwareAddress.setDefaultGateway(vmwareAddressDto.getDefaultGateway());
                vmwareAddress.setUserNo(farm.getUserNo());
                vmwareAddress.setInstanceNo(instanceNo);
                vmwareAddress.setEnabled(true);
                vmwareAddress.setAssociated(false);
                vmwareAddressDao.create(vmwareAddress);
            }
        } else {
            if (vmwareAddressDto == null) {
                vmwareAddress.setEnabled(false);
            } else {
                boolean change = false;
                if (!StringUtils.equals(vmwareAddress.getIpAddress(), vmwareAddressDto.getIpAddress())
                        || !StringUtils.equals(vmwareAddress.getSubnetMask(), vmwareAddressDto.getSubnetMask())
                        || !StringUtils.equals(vmwareAddress.getDefaultGateway(),
                                vmwareAddressDto.getDefaultGateway())) {
                    change = true;
                }

                vmwareAddress.setIpAddress(vmwareAddressDto.getIpAddress());
                vmwareAddress.setSubnetMask(vmwareAddressDto.getSubnetMask());
                vmwareAddress.setDefaultGateway(vmwareAddressDto.getDefaultGateway());
                vmwareAddress.setEnabled(true);
                if (change) {
                    vmwareAddress.setAssociated(false);
                }
            }
            vmwareAddressDao.update(vmwareAddress);
        }

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instanceName, "InstanceUpdate", instanceType, instance.getPlatformNo(), null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateNiftyInstance(Long instanceNo, String instanceName, String comment, String instanceType,
            Long keyPairNo) {
        // ?
        updateInstance(instanceNo, instanceName, comment);

        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }
        if (instanceType == null || instanceType.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceType");
        }
        if (keyPairNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "keyPairNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ??
        Platform platform = platformDao.read(instance.getPlatformNo());
        if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatformType()) == false) {
            throw new AutoApplicationException("ESERVICE-000410", instance.getInstanceName());
        }

        // ??????
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????????????????
            if (!StringUtils.equals(niftyInstance.getInstanceType(), instanceType)
                    || !keyPairNo.equals(niftyInstance.getKeyPairNo())) {
                throw new AutoApplicationException("ESERVICE-000407", instance.getInstanceName());
            }
        }

        // ?????????
        if (StringUtils.isNotEmpty(niftyInstance.getInstanceId())) {
            // ???????
            if (!niftyInstance.getKeyPairNo().equals(keyPairNo)) {
                // ??????
                throw new AutoApplicationException("ESERVICE-000411", instance.getInstanceName());
            }
        }

        // Nifty?
        niftyInstance.setInstanceType(instanceType);
        niftyInstance.setKeyPairNo(keyPairNo);
        niftyInstanceDao.update(niftyInstance);

        // 
        Farm farm = farmDao.read(instance.getFarmNo());
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instanceName, "InstanceUpdate", instanceType, instance.getPlatformNo(), null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void deleteInstance(Long instanceNo) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            // ?????
            return;
        }

        // ???????????
        if (InstanceStatus.fromStatus(instance.getStatus()) != InstanceStatus.STOPPED) {
            // ??????
            throw new AutoApplicationException("ESERVICE-000402", instance.getInstanceName());
        }

        // MySQL?Master???????
        List<InstanceConfig> instanceConfigs = instanceConfigDao.readByInstanceNo(instanceNo);
        for (InstanceConfig instanceConfig : instanceConfigs) {
            if (MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO.equals(instanceConfig.getConfigName())) {
                if (StringUtils.isEmpty(instanceConfig.getConfigValue())) {
                    // MySQL?Master??
                    throw new AutoApplicationException("ESERVICE-000413", instance.getInstanceName());
                }
            }
        }

        // Zabbix??
        Farm farm = farmDao.read(instance.getFarmNo());
        ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
        if (zabbixInstance != null) {
            if (StringUtils.isNotEmpty(zabbixInstance.getHostid())) {
                try {
                    // Zabbix??????
                    ZabbixProcessClient client = zabbixProcessClientFactory.createZabbixProcessClient();
                    client.deleteHost(zabbixInstance.getHostid());

                    //
                    eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null,
                            instanceNo, instance.getInstanceName(), "ZabbixUnregist", null,
                            instance.getPlatformNo(),
                            new Object[] { instance.getFqdn(), zabbixInstance.getHostid() });

                } catch (RuntimeException ignore) {
                    // ???????????
                    log.warn(ignore.getMessage());
                }
            }
            zabbixInstanceDao.delete(zabbixInstance);
        }

        // ZabbixData??
        ZabbixData zabbixData = zabbixDataDao.read(instanceNo);
        if (zabbixData != null) {
            zabbixDataDao.delete(zabbixData);
        }

        // Puppet??
        puppetInstanceDao.deleteByInstanceNo(instanceNo);

        // Puppet???
        // TODO: OS?????????????
        //reportLoader.deleteReportFiles(instance.getFqdn());

        Platform platform = platformDao.read(instance.getPlatformNo());
        // TODO CLOUD BRANCHING
        if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
            // AWS
            deleteAwsInstance(instanceNo);
        } else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType())) {
            // Cloudstack
            deleteCloudstackInstance(instanceNo);
        } else if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType())) {
            // VMware
            deleteVmwareInstance(instanceNo);
        } else if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatformType())) {
            // Nifty
            deleteNiftyInstance(instanceNo);
        } else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())) {
            // VCloud
            deleteVcloudInstance(instanceNo);
        } else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
            // Azure
            deleteAzureInstance(instanceNo);
        } else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
            // OpenStack
            deleteOpenStackInstance(instanceNo);
        }

        // ??????
        componentInstanceDao.deleteByInstanceNo(instanceNo);

        // ?????
        loadBalancerInstanceDao.deleteByInstanceNo(instanceNo);

        // ??
        instanceConfigDao.deleteByInstanceNo(instanceNo);

        // ??
        instanceDao.delete(instance);

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instance.getInstanceName(), "InstanceDelete", null, instance.getPlatformNo(), null);
    }

    protected void deleteCloudstackInstance(Long instanceNo) {
        // ?
        List<CloudstackAddress> cloudstackAddresses = cloudstackAddressDao.readByInstanceNo(instanceNo);
        for (CloudstackAddress cloudstackAddress : cloudstackAddresses) {
            cloudstackAddress.setInstanceNo(null);
            cloudstackAddressDao.update(cloudstackAddress);
        }

        // ?
        // TODO: ???????
        List<CloudstackVolume> cloudstackVolumes = cloudstackVolumeDao.readByInstanceNo(instanceNo);
        Instance instance = instanceDao.read(instanceNo);
        Farm farm = farmDao.read(instance.getFarmNo());
        CloudstackInstance cloudstackInstance = cloudstackInstanceDao.read(instanceNo);
        for (CloudstackVolume cloudstackVolume : cloudstackVolumes) {
            if (StringUtils.isEmpty(cloudstackVolume.getVolumeId())) {
                continue;
            }
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    cloudstackVolume.getPlatformNo());

            //
            Platform platform = platformDao.read(gateway.getPlatformNo());
            Component component = componentDao.read(cloudstackVolume.getComponentNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                    cloudstackVolume.getComponentNo(),
                    //component.getComponentName(), instanceNo, instance.getInstanceName(), "AwsEbsDelete", new Object[] {
                    component.getComponentName(), instanceNo, instance.getInstanceName(), "CloudStackVolumeDelete",
                    cloudstackInstance.getInstanceType(), instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), cloudstackVolume.getVolumeId() });

            try {
                // ?
                gateway.deleteVolume(cloudstackVolume.getVolumeId());
                //awsProcessClient.waitDeleteVolume(volumeId); // TODO: EC2??DeleteVolume???????Wait???

                //
                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                        cloudstackVolume.getComponentNo(),
                        //component.getComponentName(), instanceNo, instance.getInstanceName(), "AwsEbsDeleteFinish",
                        component.getComponentName(), instanceNo, instance.getInstanceName(),
                        "CloudStackVolumeDeleteFinish", cloudstackInstance.getInstanceType(),
                        instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), cloudstackVolume.getVolumeId() });

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        cloudstackVolumeDao.deleteByInstanceNo(instanceNo);

        // ??
        if (StringUtils.isNotEmpty(cloudstackInstance.getInstanceId())) {
            // ???????
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    instance.getPlatformNo());

            // 
            Platform platform = platformDao.read(gateway.getPlatformNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                    instance.getInstanceName(), "CloudStackInstanceDelete", cloudstackInstance.getInstanceType(),
                    instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), cloudstackInstance.getInstanceId() });

            try {
                // ?
                gateway.terminateInstance(cloudstackInstance.getInstanceId());

            } catch (AutoException ignore) {
                // ??????????????
            }
            // 
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                    instance.getInstanceName(), "CloudStackInstanceDeleteFinish",
                    cloudstackInstance.getInstanceType(), instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), cloudstackInstance.getInstanceId() });
        }
        cloudstackInstanceDao.deleteByInstanceNo(instanceNo);
    }

    protected void deleteAwsInstance(Long instanceNo) {
        // ?
        List<AwsAddress> awsAddresses = awsAddressDao.readByInstanceNo(instanceNo);
        for (AwsAddress awsAddress : awsAddresses) {
            awsAddress.setInstanceNo(null);
            awsAddressDao.update(awsAddress);
        }

        // AWS?
        // TODO: ???????
        List<AwsVolume> awsVolumes = awsVolumeDao.readByInstanceNo(instanceNo);
        Instance instance = instanceDao.read(instanceNo);
        Farm farm = farmDao.read(instance.getFarmNo());
        AwsInstance awsInstance = awsInstanceDao.read(instanceNo);
        for (AwsVolume awsVolume : awsVolumes) {
            if (StringUtils.isEmpty(awsVolume.getVolumeId())) {
                continue;
            }
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    awsVolume.getPlatformNo());

            //
            Platform platform = platformDao.read(gateway.getPlatformNo());
            Component component = componentDao.read(awsVolume.getComponentNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), awsVolume.getComponentNo(),
                    component.getComponentName(), instanceNo, instance.getInstanceName(), "AwsEbsDelete",
                    awsInstance.getInstanceType(), instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), awsVolume.getVolumeId() });

            try {
                // ?
                gateway.deleteVolume(awsVolume.getVolumeId());
                //awsProcessClient.waitDeleteVolume(volumeId); // TODO: EC2??DeleteVolume???????Wait???

                //
                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                        awsVolume.getComponentNo(), component.getComponentName(), instanceNo,
                        instance.getInstanceName(), "AwsEbsDeleteFinish", awsInstance.getInstanceType(),
                        instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), awsVolume.getVolumeId() });

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        awsVolumeDao.deleteByInstanceNo(instanceNo);

        // AWS??
        ImageAws imageAws = imageAwsDao.read(instance.getImageNo());
        if (imageAws.getEbsImage() && StringUtils.isNotEmpty(awsInstance.getInstanceId())) {
            // TODO: ???????
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    instance.getPlatformNo());

            // 
            Platform platform = platformDao.read(gateway.getPlatformNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                    instance.getInstanceName(), "AwsInstanceDelete", awsInstance.getInstanceType(),
                    instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), awsInstance.getInstanceId() });

            try {
                // ?
                gateway.terminateInstance(awsInstance.getInstanceId());

                // 
                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                        instance.getInstanceName(), "AwsInstanceDeleteFinish", awsInstance.getInstanceType(),
                        instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), awsInstance.getInstanceId() });
            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        awsInstanceDao.deleteByInstanceNo(instanceNo);
    }

    protected void deleteVmwareInstance(Long instanceNo) {
        Instance instance = instanceDao.read(instanceNo);

        // ?
        VmwareAddress vmwareAddress = vmwareAddressDao.readByInstanceNo(instanceNo);
        if (vmwareAddress != null) {
            vmwareAddressDao.delete(vmwareAddress);
        }

        VmwareProcessClient vmwareProcessClient = vmwareProcessClientFactory
                .createVmwareProcessClient(instance.getPlatformNo());

        try {
            // ?
            // TODO: ??????
            List<VmwareDisk> vmwareDisks = vmwareDiskDao.readByInstanceNo(instanceNo);
            for (VmwareDisk vmwareDisk : vmwareDisks) {
                if (StringUtils.isEmpty(vmwareDisk.getFileName())) {
                    continue;
                }
                try {
                    // ?
                    vmwareDiskProcess.deleteDisk(vmwareProcessClient, vmwareDisk.getDiskNo());
                } catch (AutoException ignore) {
                    // ??????????????
                }
            }
            vmwareDiskDao.deleteByInstanceNo(instanceNo);

            // ?
            // TODO: ??????
            try {
                vmwareMachineProcess.destroy(vmwareProcessClient, instanceNo);
            } catch (RuntimeException ignore) {
                // TODO: ?
                // ??????????????
            }
        } finally {
            vmwareProcessClient.getVmwareClient().logout();
        }

        // VMware??
        vmwareInstanceDao.deleteByInstanceNo(instanceNo);
    }

    protected void deleteNiftyInstance(Long instanceNo) {
        // Nifty??
        // TODO: ???????
        List<NiftyVolume> niftyVolumes = niftyVolumeDao.readByInstanceNo(instanceNo);
        Instance instance = instanceDao.read(instanceNo);
        Farm farm = farmDao.read(instance.getFarmNo());
        NiftyInstance niftyInstance = niftyInstanceDao.read(instanceNo);
        for (NiftyVolume niftyVolume : niftyVolumes) {
            if (StringUtils.isEmpty(niftyVolume.getVolumeId())) {
                continue;
            }

            try {
                // NiftyProcessClient??
                String clientType;
                clientType = PCCConstant.NIFTYCLIENT_TYPE_DISK;
                NiftyProcessClient niftyProcessClient = niftyProcessClientFactory
                        .createNiftyProcessClient(farm.getUserNo(), niftyVolume.getPlatformNo(), clientType);

                // ??
                niftyVolumeProcess.stopVolume(niftyProcessClient, instanceNo, niftyVolume.getVolumeNo());

                //
                Platform platform = platformDao.read(niftyProcessClient.getPlatformNo());
                Component component = componentDao.read(niftyVolume.getComponentNo());
                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                        niftyVolume.getComponentNo(), component.getComponentName(), instanceNo,
                        instance.getInstanceName(), "NiftyDiskDelete", niftyInstance.getInstanceType(),
                        instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), niftyVolume.getVolumeId() });

                // ?
                niftyProcessClient.deleteVolume(niftyVolume.getVolumeId());

                //
                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                        niftyVolume.getComponentNo(), component.getComponentName(), instanceNo,
                        instance.getInstanceName(), "NiftyDiskDeleteFinish", niftyInstance.getInstanceType(),
                        instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), niftyVolume.getVolumeId() });

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        niftyVolumeDao.deleteByInstanceNo(instanceNo);

        // Nifty??
        // TODO: ??????
        if (niftyInstance != null && StringUtils.isNotEmpty(niftyInstance.getInstanceId())) {
            String clientType;
            clientType = PCCConstant.NIFTYCLIENT_TYPE_SERVER;
            NiftyProcessClient niftyProcessClient = niftyProcessClientFactory
                    .createNiftyProcessClient(farm.getUserNo(), instance.getPlatformNo(), clientType);

            try {
                niftyProcessClient.terminateInstance(niftyInstance.getInstanceId());
            } catch (RuntimeException ignore) {
                // TODO: ?
                // ??????????????
            }
        }
        niftyInstanceDao.deleteByInstanceNo(instanceNo);
    }

    protected void deleteVcloudInstance(Long instanceNo) {
        Instance instance = instanceDao.read(instanceNo);
        VcloudInstance vcloudInstance = vcloudInstanceDao.read(instanceNo);

        // ?
        List<VcloudInstanceNetwork> vcloudInstanceNetworks = vcloudInstanceNetworkDao.readByInstanceNo(instanceNo);
        for (VcloudInstanceNetwork vcloudInstanceNetwork : vcloudInstanceNetworks) {
            vcloudInstanceNetworkDao.delete(vcloudInstanceNetwork);
        }

        Farm farm = farmDao.read(instance.getFarmNo());
        IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                instance.getPlatformNo());

        // ?
        List<VcloudDisk> vcloudDisks = vcloudDiskDao.readByInstanceNo(instanceNo);
        for (VcloudDisk vcloudDisk : vcloudDisks) {
            if (StringUtils.isEmpty(vcloudDisk.getDiskId())) {
                continue;
            }

            try {
                // ?
                // VCloud??DiskNo
                gateway.deleteVolume(String.valueOf(vcloudDisk.getDiskNo()));
            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        vcloudDiskDao.deleteByInstanceNo(instanceNo);

        // ?
        try {
            //VCloudInstance?Id??????VM_NAME???
            gateway.terminateInstance(vcloudInstance.getVmName());
        } catch (RuntimeException ignore) {
            // ??????????????
        }

        // VCloud??
        vcloudInstanceDao.deleteByInstanceNo(instanceNo);
    }

    protected void deleteAzureInstance(Long instanceNo) {

        // ?
        // TODO: ???????
        List<AzureDisk> azureDisks = azureDiskDao.readByInstanceNo(instanceNo);
        Instance instance = instanceDao.read(instanceNo);
        Farm farm = farmDao.read(instance.getFarmNo());
        AzureInstance azureInstance = azureInstanceDao.read(instanceNo);
        for (AzureDisk azureDisk : azureDisks) {
            if (StringUtils.isEmpty(azureDisk.getDiskName())) {
                continue;
            }
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    azureDisk.getPlatformNo());

            //
            Platform platform = platformDao.read(gateway.getPlatformNo());
            Component component = componentDao.read(azureDisk.getComponentNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), azureDisk.getComponentNo(),
                    component.getComponentName(), instanceNo, instance.getInstanceName(), "AzureDiskDelete",
                    azureInstance.getInstanceType(), instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), azureDisk.getDiskName() });

            try {
                // ?
                gateway.deleteVolume(azureDisk.getDiskNo().toString());

                //
                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                        azureDisk.getComponentNo(), component.getComponentName(), instanceNo,
                        instance.getInstanceName(), "AzureDiskDeleteFinish", azureInstance.getInstanceType(),
                        instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), azureDisk.getDiskName() });

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        azureDiskDao.deleteByInstanceNo(instanceNo);

        // ??
        if (StringUtils.isNotEmpty(azureInstance.getInstanceName())) {
            // ???????
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    instance.getPlatformNo());

            // 
            Platform platform = platformDao.read(gateway.getPlatformNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                    instance.getInstanceName(), "AzureInstanceDelete", azureInstance.getInstanceType(),
                    instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), azureInstance.getInstanceName() });

            try {
                // ?
                gateway.terminateInstance(azureInstance.getInstanceNo().toString());

            } catch (AutoException ignore) {
                // ??????????????
            }
            // 
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                    instance.getInstanceName(), "AzureInstanceDeleteFinish", azureInstance.getInstanceType(),
                    instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), azureInstance.getInstanceName() });
        }
        azureInstanceDao.deleteByInstanceNo(instanceNo);
    }

    protected void deleteOpenStackInstance(Long instanceNo) {

        Instance instance = instanceDao.read(instanceNo);
        Farm farm = farmDao.read(instance.getFarmNo());
        OpenstackInstance openstackInstance = openstackInstanceDao.read(instanceNo);

        // ?
        // TODO: ???????
        List<OpenstackVolume> openstackVolumes = openstackVolumeDao.readByInstanceNo(instanceNo);
        for (OpenstackVolume openstackVolume : openstackVolumes) {
            if (StringUtils.isEmpty(openstackVolume.getVolumeId())) {
                continue;
            }
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    openstackVolume.getPlatformNo());

            //
            Platform platform = platformDao.read(gateway.getPlatformNo());
            Component component = componentDao.read(openstackVolume.getComponentNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                    openstackVolume.getComponentNo(), component.getComponentName(), instanceNo,
                    instance.getInstanceName(), "OpenstackVolumeDelete", openstackInstance.getInstanceType(),
                    instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), openstackVolume.getVolumeId() });

            try {
                // ?
                gateway.deleteVolume(openstackVolume.getVolumeId());

                //
                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(),
                        openstackVolume.getComponentNo(), component.getComponentName(), instanceNo,
                        instance.getInstanceName(), "OpenstackVolumeDeleteFinish",
                        openstackInstance.getInstanceType(), instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), openstackVolume.getVolumeId() });

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        openstackVolumeDao.deleteByInstanceNo(instanceNo);

        // ??
        if (StringUtils.isNotEmpty(openstackInstance.getInstanceId())) {
            // ???????
            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    instance.getPlatformNo());

            // 
            // ????"m1.tiny"?
            Platform platform = platformDao.read(gateway.getPlatformNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                    instance.getInstanceName(), "OpenStackInstanceDelete", openstackInstance.getInstanceType(),
                    instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), openstackInstance.getInstanceId() });

            try {
                // ?
                gateway.terminateInstance(openstackInstance.getInstanceNo().toString());

            } catch (AutoException ignore) {
                // ??????????????
            }
            // 
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                    instance.getInstanceName(), "OpenStackInstanceDeleteFinish",
                    openstackInstance.getInstanceType(), instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), openstackInstance.getInstanceId() });
        }
        openstackInstanceDao.deleteByInstanceNo(instanceNo);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void associateComponents(Long instanceNo, List<Long> componentNos) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }
        if (componentNos == null) {
            throw new AutoApplicationException("ECOMMON-000003", "componentNos");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ?????
        List<Long> tmpComponentNos = new ArrayList<Long>();
        for (Long componentNo : componentNos) {
            if (!tmpComponentNos.contains(componentNo)) {
                tmpComponentNos.add(componentNo);
            }
        }
        componentNos = tmpComponentNos;

        // ????
        List<Component> components = componentDao.readInComponentNos(componentNos);
        if (componentNos.size() != components.size()) {
            for (Component component : components) {
                componentNos.remove(component.getComponentNo());
            }
            if (componentNos.size() > 0) {
                throw new AutoApplicationException("ESERVICE-000409", componentNos.iterator().next());
            }
        }

        // MySQL?Master???????
        List<InstanceConfig> instanceConfigs = instanceConfigDao.readByInstanceNo(instanceNo);
        for (InstanceConfig instanceConfig : instanceConfigs) {
            if (MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO.equals(instanceConfig.getConfigName())) {
                if (StringUtils.isEmpty(instanceConfig.getConfigValue())
                        && !componentNos.contains(instanceConfig.getComponentNo())) {
                    // MySQL?Master?????????
                    throw new AutoApplicationException("ESERVICE-000414", instance.getInstanceName());
                }
            }
        }

        // ????
        List<Component> allComponents = componentDao.readByFarmNo(instance.getFarmNo());
        List<ComponentInstance> componentInstances = componentInstanceDao.readByInstanceNo(instanceNo);
        for (Component component : allComponents) {
            // ?????????
            ComponentInstance componentInstance = null;
            for (ComponentInstance tmpComponentInstance : componentInstances) {
                if (component.getComponentNo().equals(tmpComponentInstance.getComponentNo())) {
                    componentInstance = tmpComponentInstance;
                    break;
                }
            }

            if (componentNos.contains(component.getComponentNo())) {
                // ??????
                if (componentInstance == null) {
                    // ????????
                    componentInstance = new ComponentInstance();
                    componentInstance.setComponentNo(component.getComponentNo());
                    componentInstance.setInstanceNo(instanceNo);
                    componentInstance.setAssociate(true);
                    componentInstance.setEnabled(false);
                    componentInstance.setStatus(ComponentInstanceStatus.STOPPED.toString());
                    componentInstanceDao.create(componentInstance);
                } else {
                    // ???????
                    if (BooleanUtils.isNotTrue(componentInstance.getAssociate())) {
                        componentInstance.setAssociate(true);
                        componentInstanceDao.update(componentInstance);
                    }
                }
            } else {
                // ????????
                if (componentInstance != null) {
                    // ????
                    ComponentInstanceStatus status = ComponentInstanceStatus
                            .fromStatus(componentInstance.getStatus());
                    if (status == ComponentInstanceStatus.STOPPED) {
                        // Zabbix??
                        if (zabbixInstanceDao.countByInstanceNo(componentInstance.getInstanceNo()) > 0) {
                            zabbixHostProcess.removeTemplate(componentInstance.getInstanceNo(),
                                    componentInstance.getComponentNo());
                        }

                        /******************************************************************
                         * ???????
                         * ??VCLOUDUSiZE?????
                         ******************************************************************/
                        List<VcloudDisk> vdisks = vcloudDiskDao.readByInstanceNo(instance.getInstanceNo());
                        for (VcloudDisk disk : vdisks) {
                            if (component.getComponentNo().equals(disk.getComponentNo())) {
                                //componentNo????????
                                Farm farm = farmDao.read(instance.getFarmNo());
                                IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                                        instance.getPlatformNo());
                                try {
                                    gateway.deleteVolume(String.valueOf(disk.getDiskNo()));
                                } catch (AutoException ignore) {
                                    // ??????????????
                                }
                                //
                                vcloudDiskDao.delete(disk);
                            }
                        }

                        // ???????????
                        componentInstanceDao.delete(componentInstance);
                    } else {
                        // ??
                        if (BooleanUtils.isTrue(componentInstance.getAssociate())) {
                            componentInstance.setAssociate(false);
                            componentInstanceDao.update(componentInstance);
                        }
                    }
                }
            }
        }

        for (Component component : components) {
            ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());

            // MySQL?????Master/Slave?
            if (MySQLConstants.COMPONENT_TYPE_NAME.equals(componentType.getComponentTypeName())) {
                InstanceConfig instanceConfig = instanceConfigDao.readByInstanceNoAndComponentNoAndConfigName(
                        instanceNo, component.getComponentNo(), MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO);
                if (instanceConfig == null) {
                    // Master??
                    Long masterInstanceNo = null;
                    List<InstanceConfig> configs = instanceConfigDao.readByComponentNo(component.getComponentNo());
                    for (InstanceConfig config : configs) {
                        if (MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO.equals(config.getConfigName())) {
                            if (StringUtils.isEmpty(config.getConfigValue())) {
                                masterInstanceNo = config.getInstanceNo();
                                break;
                            }
                        }
                    }

                    // Master???????Master????Slave??
                    instanceConfig = new InstanceConfig();
                    instanceConfig.setInstanceNo(instanceNo);
                    instanceConfig.setComponentNo(component.getComponentNo());
                    instanceConfig.setConfigName(MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO);
                    if (masterInstanceNo == null) {
                        instanceConfig.setConfigValue(null);
                    } else {
                        instanceConfig.setConfigValue(masterInstanceNo.toString());
                    }
                    instanceConfigDao.create(instanceConfig);
                }
            }
        }

        // 
        StringBuilder names = new StringBuilder();
        for (Component component : components) {
            names.append(component.getComponentName()).append(",");
        }
        if (names.length() > 0) {
            names.deleteCharAt(names.length() - 1);
        }
        Farm farm = farmDao.read(instance.getFarmNo());
        eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), null, null, instanceNo,
                instance.getInstanceName(), "InstanceAssociateComponent", null, instance.getPlatformNo(),
                new Object[] { names.toString() });
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<PlatformDto> getPlatforms(Long userNo) {
        // ?
        List<PlatformDto> dtos = new ArrayList<PlatformDto>();
        List<Platform> platforms = platformDao.readAll();
        List<ComponentType> componentTypes = componentTypeDao.readAll();
        List<Image> images = imageDao.readAll();
        for (Platform platform : platforms) {
            PlatformAws platformAws = null;
            PlatformVmware platformVmware = null;
            PlatformNifty platformNifty = null;
            PlatformCloudstack platformCloudstack = null;
            PlatformVcloud platformVcloud = null;
            PlatformAzure platformAzure = null;
            PlatformOpenstack platformOpenstack = null;

            // TODO CLOUD BRANCHING
            if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
                // AWS???????
                if (awsCertificateDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                platformAws = platformAwsDao.read(platform.getPlatformNo());
            } else if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType())) {
                // ?????
                // TODO: ???
                if (vmwareKeyPairDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                platformVmware = platformVmwareDao.read(platform.getPlatformNo());
            } else if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatformType())) {
                // ???????
                // TODO: ???
                if (niftyCertificateDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                if (niftyKeyPairDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                platformNifty = platformNiftyDao.read(platform.getPlatformNo());
            } else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType())) {
                // ???????
                // TODO: ???
                if (cloudstackCertificateDao.countByAccountAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                platformCloudstack = platformCloudstackDao.read(platform.getPlatformNo());
            } else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())) {
                // ???????
                if (vcloudCertificateDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                if (vcloudKeyPairDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                platformVcloud = platformVcloudDao.read(platform.getPlatformNo());
            } else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
                // ???????
                if (azureCertificateDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                platformAzure = platformAzureDao.read(platform.getPlatformNo());
            } else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
                // ???????
                if (openstackCertificateDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) == 0) {
                    continue;
                }
                platformOpenstack = platformOpenstackDao.read(platform.getPlatformNo());
            }

            List<ImageDto> imageDtos = getImages(platform, images, componentTypes);

            PlatformDto dto = new PlatformDto();
            dto.setPlatform(platform);
            dto.setPlatformAws(platformAws);
            dto.setPlatformVmware(platformVmware);
            dto.setPlatformNifty(platformNifty);
            dto.setPlatformCloudstack(platformCloudstack);
            dto.setPlatformVcloud(platformVcloud);
            dto.setPlatformAzure(platformAzure);
            dto.setPlatformOpenstack(platformOpenstack);
            dto.setImages(imageDtos);
            dtos.add(dto);
        }

        return dtos;
    }

    protected List<ImageDto> getImages(Platform platform, List<Image> images,
            List<ComponentType> allComponentTypes) {
        // ?
        List<ImageDto> imageDtos = new ArrayList<ImageDto>();
        for (Image image : images) {
            // ????
            if (platform.getPlatformNo().equals(image.getPlatformNo()) == false) {
                continue;
            }

            ImageAws imageAws = null;
            ImageCloudstack imageCloudstack = null;
            ImageVmware imageVmware = null;
            ImageNifty imageNifty = null;
            ImageVcloud imageVcloud = null;
            ImageAzure imageAzure = null;
            ImageOpenstack imageOpenstack = null;

            // TODO CLOUD BRANCHING
            if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
                imageAws = imageAwsDao.read(image.getImageNo());
            } else if (PCCConstant.PLATFORM_TYPE_CLOUDSTACK.equals(platform.getPlatformType())) {
                imageCloudstack = imageCloudstackDao.read(image.getImageNo());
            } else if (PCCConstant.PLATFORM_TYPE_VMWARE.equals(platform.getPlatformType())) {
                imageVmware = imageVmwareDao.read(image.getImageNo());
            } else if (PCCConstant.PLATFORM_TYPE_NIFTY.equals(platform.getPlatformType())) {
                imageNifty = imageNiftyDao.read(image.getImageNo());
            } else if (PCCConstant.PLATFORM_TYPE_VCLOUD.equals(platform.getPlatformType())) {
                imageVcloud = imageVcloudDao.read(image.getImageNo());
            } else if (PCCConstant.PLATFORM_TYPE_AZURE.equals(platform.getPlatformType())) {
                imageAzure = imageAzureDao.read(image.getImageNo());
            } else if (PCCConstant.PLATFORM_TYPE_OPENSTACK.equals(platform.getPlatformType())) {
                imageOpenstack = imageOpenstackDao.read(image.getImageNo());
            }

            // ??????
            String[] componentTypeNos = StringUtils.split(image.getComponentTypeNos(), ",");
            List<ComponentType> componentTypes = new ArrayList<ComponentType>();
            for (String componentTypeNo : componentTypeNos) {
                long no = Long.valueOf(componentTypeNo.trim());
                for (ComponentType componentType : allComponentTypes) {
                    if (no == componentType.getComponentTypeNo().longValue()) {
                        componentTypes.add(componentType);
                    }
                }
            }

            ImageDto imageDto = new ImageDto();
            imageDto.setImage(image);
            imageDto.setImageAws(imageAws);
            imageDto.setImageCloudstack(imageCloudstack);
            imageDto.setImageVmware(imageVmware);
            imageDto.setImageNifty(imageNifty);
            imageDto.setImageVcloud(imageVcloud);
            imageDto.setImageAzure(imageAzure);
            imageDto.setImageOpenstack(imageOpenstack);
            imageDto.setComponentTypes(componentTypes);
            imageDtos.add(imageDto);
        }

        return imageDtos;
    }

    protected String createUrl(String ipAddress, Long componentTypeNo) {

        ComponentType componentType = componentTypeDao.read(componentTypeNo);
        String url = componentType.getAddressUrl();
        url = url.replaceAll("%d", ipAddress);

        return url;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void enableZabbixMonitoring(Long instanceNo) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            // ?????
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ZABBIX_INSTANCE??
        ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
        if (zabbixInstance == null) {
            // ?????
            throw new AutoApplicationException("ESERVICE-000422", instanceNo);
        }

        // Zabbix(config.properties?zabbix.useZabbix)??
        Boolean useZabbix = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useZabbix"));
        if (BooleanUtils.isNotTrue(useZabbix)) {
            // Zabbix?true?
            throw new AutoApplicationException("ESERVICE-000423", instanceNo);
        }

        // ?OS??
        InstanceStatus instanceStatus = getInstanceStatus(instance);
        if (instanceStatus != InstanceStatus.RUNNING) {
            // ?OS?RUNNING?
            throw new AutoApplicationException("ESERVICE-000424", instance.getInstanceName());
        }

        // Zabbix??
        ZabbixInstanceStatus zabbixInstanceStatus = ZabbixInstanceStatus.fromStatus(zabbixInstance.getStatus());
        if (zabbixInstanceStatus != ZabbixInstanceStatus.UN_MONITORING) {
            // Zabbix??UN_MONITORING?
            throw new AutoApplicationException("ESERVICE-000425", instance.getInstanceName());
        }

        // Zabbix
        zabbixHostProcess.startHost(instanceNo);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void disableZabbixMonitoring(Long instanceNo) {
        // ?
        if (instanceNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "instanceNo");
        }

        // ??
        Instance instance = instanceDao.read(instanceNo);
        if (instance == null) {
            // ?????
            throw new AutoApplicationException("ESERVICE-000403", instanceNo);
        }

        // ZABBIX_INSTANCE??
        ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
        if (zabbixInstance == null) {
            // ?????
            throw new AutoApplicationException("ESERVICE-000422", instanceNo);
        }

        // Zabbix(config.properties?zabbix.useZabbix)??
        Boolean useZabbix = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useZabbix"));
        if (BooleanUtils.isNotTrue(useZabbix)) {
            // Zabbix?true?
            throw new AutoApplicationException("ESERVICE-000423", instanceNo);
        }

        // ?OS??
        InstanceStatus instanceStatus = getInstanceStatus(instance);
        if (instanceStatus != InstanceStatus.RUNNING) {
            // ?OS?RUNNING?
            throw new AutoApplicationException("ESERVICE-000426", instance.getInstanceName());
        }

        // Zabbix??
        ZabbixInstanceStatus zabbixInstanceStatus = ZabbixInstanceStatus.fromStatus(zabbixInstance.getStatus());
        if (zabbixInstanceStatus != ZabbixInstanceStatus.MONITORING) {
            // Zabbix??MONITORING?
            throw new AutoApplicationException("ESERVICE-000427", instance.getInstanceName());
        }

        // Zabbix
        zabbixHostProcess.stopHost(instanceNo);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public InstanceStatus getInstanceStatus(Instance instance) {
        // ?????
        InstanceStatus instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
        if (BooleanUtils.isTrue(instance.getEnabled())) {
            if (instanceStatus == InstanceStatus.STOPPED) {
                instance.setStatus(InstanceStatus.STARTING.toString());
            }
        } else {
            if (instanceStatus == InstanceStatus.RUNNING || instanceStatus == InstanceStatus.WARNING) {
                instance.setStatus(InstanceStatus.STOPPING.toString());
            }
        }

        // ???
        //    ? ?   ??
        //        Running         Coodinating            Configuring
        //        Running         Warning                Warning
        instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
        InstanceCoodinateStatus insCoodiStatus = InstanceCoodinateStatus.fromStatus(instance.getCoodinateStatus());
        // ?(Running)???(Coodinating)Configuring?
        if (instanceStatus == InstanceStatus.RUNNING && insCoodiStatus == InstanceCoodinateStatus.COODINATING) {
            instance.setStatus(InstanceStatus.CONFIGURING.toString());
            // ?(Running)???(Warning)Warning?
        } else if (instanceStatus == InstanceStatus.RUNNING && insCoodiStatus == InstanceCoodinateStatus.WARNING) {
            instance.setStatus(InstanceStatus.WARNING.toString());
        }

        return InstanceStatus.fromStatus(instance.getStatus());
    }

    /**
     * awsProcessClientFactory???
     *
     * @param awsProcessClientFactory awsProcessClientFactory
     */
    public void setIaasGatewayFactory(IaasGatewayFactory iaasGatewayFactory) {
        this.iaasGatewayFactory = iaasGatewayFactory;
    }

    /**
     * awsDescribeService???
     *
     * @param awsDescribeService awsDescribeService
     */
    public void setAwsDescribeService(IaasDescribeService awsDescribeService) {
        this.iaasDescribeService = awsDescribeService;
    }

    /**
     * vmwareDescribeService???
     *
     * @param vmwareDescribeService vmwareDescribeService
     */
    public void setVmwareDescribeService(VmwareDescribeService vmwareDescribeService) {
        this.vmwareDescribeService = vmwareDescribeService;
    }

    /**
     * vmwareMachineProcess???
     *
     * @param vmwareMachineProcess vmwareMachineProcess
     */
    public void setVmwareMachineProcess(VmwareMachineProcess vmwareMachineProcess) {
        this.vmwareMachineProcess = vmwareMachineProcess;
    }

    /**
     * vmwareDiskProcess???
     *
     * @param vmwareDiskProcess vmwareDiskProcess
     */
    public void setVmwareDiskProcess(VmwareDiskProcess vmwareDiskProcess) {
        this.vmwareDiskProcess = vmwareDiskProcess;
    }

    /**
     * vmwareProcessClientFactory???
     *
     * @param vmwareProcessClientFactory vmwareProcessClientFactory
     */
    public void setVmwareProcessClientFactory(VmwareProcessClientFactory vmwareProcessClientFactory) {
        this.vmwareProcessClientFactory = vmwareProcessClientFactory;
    }

    /**
     * niftyProcessClientFactory???
     *
     * @param niftyProcessClientFactory niftyProcessClientFactory
     */
    public void setNiftyProcessClientFactory(NiftyProcessClientFactory niftyProcessClientFactory) {
        this.niftyProcessClientFactory = niftyProcessClientFactory;
    }

    /**
     * zabbixProcessClientFactory???
     *
     * @param zabbixProcessClientFactory zabbixProcessClientFactory
     */
    public void setZabbixProcessClientFactory(ZabbixProcessClientFactory zabbixProcessClientFactory) {
        this.zabbixProcessClientFactory = zabbixProcessClientFactory;
    }

    /**
     * zabbixHostProcess???
     *
     * @param zabbixHostProcess zabbixHostProcess
     */
    public void setZabbixHostProcess(ZabbixHostProcess zabbixHostProcess) {
        this.zabbixHostProcess = zabbixHostProcess;
    }

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

    /**
     * niftyVolumeProcess???
     * @param niftyVolumeProcess niftyVolumeProcess
     */
    public void setNiftyVolumeProcess(NiftyVolumeProcess niftyVolumeProcess) {
        this.niftyVolumeProcess = niftyVolumeProcess;
    }

}