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

Java tutorial

Introduction

Here is the source code for jp.primecloud.auto.service.impl.ComponentServiceImpl.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.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import jp.primecloud.auto.common.constant.PCCConstant;
import jp.primecloud.auto.common.log.LoggingUtils;
import jp.primecloud.auto.common.status.ComponentInstanceStatus;
import jp.primecloud.auto.common.status.ComponentStatus;
import jp.primecloud.auto.common.status.InstanceStatus;
import jp.primecloud.auto.component.mysql.MySQLConstants;
import jp.primecloud.auto.config.Config;
import jp.primecloud.auto.entity.crud.AwsInstance;
import jp.primecloud.auto.entity.crud.AwsVolume;
import jp.primecloud.auto.entity.crud.AzureDisk;
import jp.primecloud.auto.entity.crud.AzureInstance;
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.ComponentConfig;
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.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.NiftyVolume;
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.VcloudDisk;
import jp.primecloud.auto.entity.crud.VmwareDisk;
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.ComponentConstants;
import jp.primecloud.auto.process.vmware.VmwareDiskProcess;
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.service.ComponentService;
import jp.primecloud.auto.service.InstanceService;
import jp.primecloud.auto.service.ServiceSupport;
import jp.primecloud.auto.service.dto.ComponentDto;
import jp.primecloud.auto.service.dto.ComponentInstanceDto;
import jp.primecloud.auto.service.dto.ComponentTypeDto;
import jp.primecloud.auto.service.dto.InstanceDto;

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

/**
 * <p>
 * TODO: 
 * </p>
 *
 */
public class ComponentServiceImpl extends ServiceSupport implements ComponentService {

    protected InstanceService instanceService;

    protected IaasGatewayFactory iaasGatewayFactory;

    protected VmwareProcessClientFactory vmwareProcessClientFactory;

    protected VmwareDiskProcess vmwareDiskProcess;

    protected ZabbixHostProcess zabbixHostProcess;

    protected EventLogger eventLogger;

    protected NiftyProcessClientFactory niftyProcessClientFactory;

    /**
     * {@inheritDoc}
     */
    @Override
    public List<ComponentDto> getComponents(Long farmNo) {
        // ???
        List<Component> components = new ArrayList<Component>();
        List<Component> allComponents = componentDao.readByFarmNo(farmNo);
        for (Component component : allComponents) {
            // ???
            if (BooleanUtils.isTrue(component.getLoadBalancer())) {
                continue;
            }
            components.add(component);
        }

        // ????
        List<Long> componentNos = new ArrayList<Long>();
        for (Component component : components) {
            componentNos.add(component.getComponentNo());
        }

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

        Farm farm = farmDao.read(farmNo);
        List<Instance> instances = instanceDao.readByFarmNo(farmNo);
        Map<Long, Instance> instanceMap = new HashMap<Long, Instance>();
        for (Instance instance : instances) {
            instanceMap.put(instance.getInstanceNo(), instance);
        }
        List<ComponentDto> dtos = new ArrayList<ComponentDto>();
        for (Component component : components) {
            ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());
            List<InstanceConfig> instanceConfigs = instanceConfigDao.readByComponentNo(component.getComponentNo());
            List<ComponentConfig> componentConfigs = componentConfigDao
                    .readByComponentNo(component.getComponentNo());
            List<ComponentInstance> componentInstances = componentInstanceMap.get(component.getComponentNo());
            List<ComponentInstanceDto> componentInstanceDtos = new ArrayList<ComponentInstanceDto>();

            // ???????
            for (ComponentInstance componentInstance : componentInstances) {
                Instance instance = instanceMap.get(componentInstance.getInstanceNo());
                ComponentInstanceStatus status = getComponentInstanceStatus(farm, componentInstance, instance);
                componentInstance.setStatus(status.toString());
            }

            // ????
            ComponentStatus componentStatus = getComponentStatus(componentInstances);

            // DTO??URL?
            for (ComponentInstance componentInstance : componentInstances) {
                ComponentInstanceDto componentInstanceDto = new ComponentInstanceDto();
                componentInstanceDto.setComponentInstance(componentInstance);
                Instance instance = instanceMap.get(componentInstance.getInstanceNo());

                //                for (Instance tmpInstance : instances) {
                //                    if (componentInstance.getInstanceNo().equals(tmpInstance.getInstanceNo())) {
                //                        instance = tmpInstance;
                //                        break;
                //                    }
                //                }

                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);
                componentInstanceDtos.add(componentInstanceDto);
            }
            //            // TODO: ????????
            //            for (ComponentInstanceDto componentInstanceDto : componentInstances) {
            //                ComponentInstance componentInstance = componentInstanceDto.getComponentInstance();
            //                ComponentInstanceStatus status = ComponentInstanceStatus.fromStatus(componentInstance.getStatus());
            //                if (BooleanUtils.isTrue(componentInstance.getEnabled())) {
            //                    if (status == ComponentInstanceStatus.STOPPED) {
            //                        Instance instance = instanceMap.get(componentInstance.getInstanceNo());
            //                        InstanceStatus instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
            //                        if (instanceStatus == InstanceStatus.WARNING) {
            //                            // ?Waring??????Warning??
            //                            componentInstance.setStatus(ComponentInstanceStatus.WARNING.toString());
            //                        } else if (BooleanUtils.isTrue(farm.getScheduled())) {
            //                            // ??????Starting??
            //                            componentInstance.setStatus(ComponentInstanceStatus.STARTING.toString());
            //                        }
            //                    } else if (status == ComponentInstanceStatus.RUNNING
            //                            && BooleanUtils.isTrue(componentInstance.getConfigure())) {
            //                        if (BooleanUtils.isTrue(farm.getScheduled())) {
            //                            // ???Running??????Configuring??
            //                            componentInstance.setStatus(ComponentInstanceStatus.CONFIGURING.toString());
            //                        }
            //                    }
            //                } else {
            //                    if (status == ComponentInstanceStatus.RUNNING || status == ComponentInstanceStatus.WARNING) {
            //                        if (BooleanUtils.isTrue(farm.getScheduled())) {
            //                            // ??????Stopping??
            //                            componentInstance.setStatus(ComponentInstanceStatus.STOPPING.toString());
            //                        }
            //                    }
            //                }
            //            }

            //            // ????
            //            ComponentStatus componentStatus;
            //            Set<ComponentInstanceStatus> statuses = new HashSet<ComponentInstanceStatus>();
            //            for (ComponentInstanceDto componentInstanceDto : componentInstances) {
            //                statuses.add(ComponentInstanceStatus
            //                        .fromStatus(componentInstanceDto.getComponentInstance().getStatus()));
            //            }
            //            if (statuses.contains(ComponentInstanceStatus.WARNING)) {
            //                componentStatus = ComponentStatus.WARNING;
            //            } else if (statuses.contains(ComponentInstanceStatus.CONFIGURING)) {
            //                componentStatus = ComponentStatus.CONFIGURING;
            //            } else if (statuses.contains(ComponentInstanceStatus.RUNNING)) {
            //                if (statuses.contains(ComponentInstanceStatus.STARTING)) {
            //                    componentStatus = ComponentStatus.CONFIGURING;
            //                } else if (statuses.contains(ComponentInstanceStatus.STOPPING)) {
            //                    componentStatus = ComponentStatus.CONFIGURING;
            //                } else {
            //                    componentStatus = ComponentStatus.RUNNING;
            //                }
            //            } else if (statuses.contains(ComponentInstanceStatus.STARTING)) {
            //                componentStatus = ComponentStatus.STARTING;
            //            } else if (statuses.contains(ComponentInstanceStatus.STOPPING)) {
            //                componentStatus = ComponentStatus.STOPPING;
            //            } else {
            //                componentStatus = ComponentStatus.STOPPED;
            //            }

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

            ComponentDto dto = new ComponentDto();
            dto.setComponent(component);
            dto.setComponentType(componentType);
            dto.setComponentConfigs(componentConfigs);
            dto.setComponentInstances(componentInstanceDtos);
            dto.setInstanceConfigs(instanceConfigs);
            dto.setStatus(componentStatus.toString());
            dtos.add(dto);
        }

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

        return dtos;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Long createComponent(Long farmNo, String componentName, Long componentTypeNo, String comment,
            Integer diskSize) {
        // ?
        if (farmNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "farmNo");
        }
        if (componentName == null || componentName.length() == 0) {
            throw new AutoApplicationException("ECOMMON-000003", "componentName");
        }
        if (componentTypeNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "componentTypeNo");
        }

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

        // TODO: ??

        // ???????
        Component checkComponent = componentDao.readByFarmNoAndComponentName(farmNo, componentName);
        if (checkComponent != null) {
            // ?????????
            throw new AutoApplicationException("ESERVICE-000301", componentName);
        }

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

        // ????
        Component component = new Component();
        component.setFarmNo(farmNo);
        component.setComponentName(componentName);
        component.setComponentTypeNo(componentTypeNo);
        component.setComment(comment);
        componentDao.create(component);

        // ?????
        if (diskSize != null) {
            // ?
            ComponentConfig componentConfig = new ComponentConfig();
            componentConfig.setComponentNo(component.getComponentNo());
            componentConfig.setConfigName(ComponentConstants.CONFIG_NAME_DISK_SIZE);
            componentConfig.setConfigValue(diskSize.toString());
            componentConfigDao.create(componentConfig);
        }

        ComponentType componentType = componentTypeDao.read(componentTypeNo);

        // TODO: ??phpMyAdmin???
        // MySQL??????phpMyAdmin??
        if (MySQLConstants.COMPONENT_TYPE_NAME.equals(componentType.getComponentTypeName())) {
            ComponentConfig componentConfig = new ComponentConfig();
            componentConfig.setComponentNo(component.getComponentNo());
            componentConfig.setConfigName(MySQLConstants.CONFIG_NAME_PHP_MY_ADMIN);
            componentConfig.setConfigValue("true");
            componentConfigDao.create(componentConfig);
        }

        // ??
        Boolean useZabbix = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useZabbix"));
        if (BooleanUtils.isTrue(useZabbix)) {
            zabbixHostProcess.createComponentHostgroup(component.getComponentNo());
        }

        // 
        eventLogger.log(EventLogLevel.INFO, farmNo, farm.getFarmName(), component.getComponentNo(), componentName,
                null, null, "ComponentCreate", null, null, new Object[] { componentType.getComponentTypeName() });

        return component.getComponentNo();
    }

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

        // ????
        Component component = componentDao.read(componentNo);
        if (component == null) {
            throw new AutoApplicationException("ESERVICE-000303", componentNo);
        }

        // ???
        List<Long> tmpInstanceNos = new ArrayList<Long>();
        for (Long instanceNo : instanceNos) {
            if (!tmpInstanceNos.contains(instanceNo)) {
                tmpInstanceNos.add(instanceNo);
            }
        }
        instanceNos = tmpInstanceNos;

        // ??
        List<Instance> instances = instanceDao.readInInstanceNos(instanceNos);
        if (instanceNos.size() != instances.size()) {
            for (Instance instance : instances) {
                instanceNos.remove(instance.getInstanceNo());
            }
            if (instanceNos.size() > 0) {
                throw new AutoApplicationException("ESERVICE-000304", instanceNos.iterator().next());
            }
        }

        ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());

        // MySQL?????Master?
        if (MySQLConstants.COMPONENT_TYPE_NAME.equals(componentType.getComponentTypeName())) {
            // Master??
            Long masterInstanceNo = null;
            List<InstanceConfig> instanceConfigs = instanceConfigDao.readByComponentNo(componentNo);
            for (InstanceConfig instanceConfig : instanceConfigs) {
                if (MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO.equals(instanceConfig.getConfigName())) {
                    if (StringUtils.isEmpty(instanceConfig.getConfigValue())) {
                        masterInstanceNo = instanceConfig.getInstanceNo();
                        break;
                    }
                }
            }

            // Master??????
            if (masterInstanceNo != null && !instanceNos.contains(masterInstanceNo)) {
                Instance masterInstance = instanceDao.read(masterInstanceNo);
                throw new AutoApplicationException("ESERVICE-000308", masterInstance.getInstanceName());
            }
        }

        // ??
        doAssociate(componentNo, tmpInstanceNos);

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

    /**
     * {@inheritDoc}
     */
    protected void doAssociate(Long componentNo, List<Long> instanceNos) {
        Component component = componentDao.read(componentNo);

        // ????
        List<Instance> allInstances = instanceDao.readByFarmNo(component.getFarmNo());
        List<ComponentInstance> componentInstances = componentInstanceDao.readByComponentNo(componentNo);
        for (Instance instance : allInstances) {
            // ???????
            ComponentInstance componentInstance = null;
            for (ComponentInstance tmpComponentInstance : componentInstances) {
                if (instance.getInstanceNo().equals(tmpComponentInstance.getInstanceNo())) {
                    componentInstance = tmpComponentInstance;
                    break;
                }
            }

            if (instanceNos.contains(instance.getInstanceNo())) {
                // ??????
                if (componentInstance == null) {
                    // ????????
                    componentInstance = new ComponentInstance();
                    componentInstance.setComponentNo(componentNo);
                    componentInstance.setInstanceNo(instance.getInstanceNo());
                    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(), componentNo);
                        }

                        /******************************************************************
                         * ???????
                         * ??VCLOUDUSiZE?????
                         ******************************************************************/
                        List<VcloudDisk> vdisks = vcloudDiskDao.readByInstanceNo(instance.getInstanceNo());
                        for (VcloudDisk disk : vdisks) {
                            if (componentNo.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);
                        }
                    }
                }
            }
        }

        ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());

        // MySQL?????Master?Slave?
        if (MySQLConstants.COMPONENT_TYPE_NAME.equals(componentType.getComponentTypeName())) {
            // Master/Slave??
            Long masterInstanceNo = null;
            Set<Long> slaveInstanceNos = new LinkedHashSet<Long>();
            List<InstanceConfig> instanceConfigs = instanceConfigDao.readByComponentNo(componentNo);
            for (InstanceConfig instanceConfig : instanceConfigs) {
                if (MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO.equals(instanceConfig.getConfigName())) {
                    if (StringUtils.isEmpty(instanceConfig.getConfigValue())) {
                        masterInstanceNo = instanceConfig.getInstanceNo();
                    } else {
                        slaveInstanceNos.add(instanceConfig.getInstanceNo());
                    }
                }
            }

            // Master?????????Master??
            if (masterInstanceNo == null && instanceNos.size() > 0) {
                masterInstanceNo = instanceNos.get(0);

                InstanceConfig instanceConfig = new InstanceConfig();
                instanceConfig.setInstanceNo(masterInstanceNo);
                instanceConfig.setComponentNo(componentNo);
                instanceConfig.setConfigName(MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO);
                instanceConfig.setConfigValue(null);
                instanceConfigDao.create(instanceConfig);
            }

            // Master/Slave??????Slave??
            if (masterInstanceNo != null) {
                for (Long instanceNo : instanceNos) {
                    if (!instanceNo.equals(masterInstanceNo) && !slaveInstanceNos.contains(instanceNo)) {
                        InstanceConfig instanceConfig = new InstanceConfig();
                        instanceConfig.setInstanceNo(instanceNo);
                        instanceConfig.setComponentNo(componentNo);
                        instanceConfig.setConfigName(MySQLConstants.CONFIG_NAME_MASTER_INSTANCE_NO);
                        instanceConfig.setConfigValue(masterInstanceNo.toString());
                        instanceConfigDao.create(instanceConfig);
                    }
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateComponent(Long componentNo, String comment, Integer diskSize, String customParam1,
            String customParam2, String customParam3) {
        // ?
        if (componentNo == null) {
            throw new AutoApplicationException("ECOMMON-000003", "componentNo");
        }

        // TODO: ??

        // ????
        Component component = componentDao.read(componentNo);
        if (component == null) {
            throw new AutoApplicationException("ESERVICE-000303", componentNo);
        }

        // ??
        Integer oldDiskSize = null;
        ComponentConfig componentConfig = componentConfigDao.readByComponentNoAndConfigName(componentNo,
                ComponentConstants.CONFIG_NAME_DISK_SIZE);
        if (componentConfig != null && StringUtils.isNotEmpty(componentConfig.getConfigValue())) {
            oldDiskSize = Integer.valueOf(componentConfig.getConfigValue());
        }

        // ???????????
        if (oldDiskSize != null && !oldDiskSize.equals(diskSize)) {
            // TODO CLOUD BRANCHING
            long count = awsVolumeDao.countByComponentNo(componentNo);
            count += vmwareDiskDao.countByComponentNo(componentNo);
            count += cloudstackVolumeDao.countByComponentNo(componentNo);
            count += vcloudDiskDao.countByComponentNo(componentNo);
            count += niftyVolumeDao.countByComponentNo(componentNo);
            count += azureDiskDao.countByComponentNo(componentNo);
            count += openstackVolumeDao.countByComponentNo(componentNo);
            if (count > 0) {
                throw new AutoApplicationException("ESERVICE-000307", componentNo);
            }
        }

        // ?
        Farm farm = farmDao.read(component.getFarmNo());
        // ???
        List<ComponentInstance> componentInstances = componentInstanceDao.readByComponentNo(componentNo);
        for (ComponentInstance componentInstance : componentInstances) {
            Instance instance = instanceDao.read(componentInstance.getInstanceNo());
            componentInstance.setStatus(getComponentInstanceStatus(farm, componentInstance, instance).toString());
        }
        ComponentStatus componentStatus = getComponentStatus(componentInstances);

        // ?1?
        ComponentConfig compConfCustomParam1 = componentConfigDao.readByComponentNoAndConfigName(componentNo,
                ComponentConstants.CONFIG_NAME_CUSTOM_PARAM_1);
        String oldCustomParam1 = null;
        if (compConfCustomParam1 != null) {
            oldCustomParam1 = compConfCustomParam1.getConfigValue();
        }

        // ?2?
        ComponentConfig compConfCustomParam2 = componentConfigDao.readByComponentNoAndConfigName(componentNo,
                ComponentConstants.CONFIG_NAME_CUSTOM_PARAM_2);
        String oldCustomParam2 = null;
        if (compConfCustomParam2 != null) {
            oldCustomParam2 = compConfCustomParam2.getConfigValue();
        }

        // ?3?
        ComponentConfig compConfCustomParam3 = componentConfigDao.readByComponentNoAndConfigName(componentNo,
                ComponentConstants.CONFIG_NAME_CUSTOM_PARAM_3);
        String oldCustomParam3 = null;
        if (compConfCustomParam3 != null) {
            oldCustomParam3 = compConfCustomParam3.getConfigValue();
        }

        // ?Stopped????
        if (ComponentStatus.STOPPED != componentStatus) {
            // 1
            if (oldCustomParam1 != null && !oldCustomParam1.equals(customParam1)) {
                throw new AutoApplicationException("ESERVICE-000311", component.getComponentName());
            }
            // 2
            if (oldCustomParam2 != null && !oldCustomParam2.equals(customParam2)) {
                throw new AutoApplicationException("ESERVICE-000312", component.getComponentName());
            }
            // 3
            if (oldCustomParam3 != null && !oldCustomParam3.equals(customParam3)) {
                throw new AutoApplicationException("ESERVICE-000313", component.getComponentName());
            }
        }

        // ???
        component.setComment(comment);
        componentDao.update(component);

        // ?
        if (diskSize != null && !diskSize.equals(oldDiskSize)) {
            if (componentConfig != null) {
                componentConfig.setConfigValue(diskSize.toString());
                componentConfigDao.update(componentConfig);
            } else {
                componentConfig = new ComponentConfig();
                componentConfig.setComponentNo(componentNo);
                componentConfig.setConfigName(ComponentConstants.CONFIG_NAME_DISK_SIZE);
                componentConfig.setConfigValue(diskSize.toString());
                componentConfigDao.create(componentConfig);
            }
        } else if (diskSize == null && oldDiskSize != null) {
            componentConfig.setConfigValue(null);
            componentConfigDao.update(componentConfig);
        }

        // 1?
        if (compConfCustomParam1 != null) {
            compConfCustomParam1.setConfigValue(customParam1);
            componentConfigDao.update(compConfCustomParam1);
        } else {
            compConfCustomParam1 = new ComponentConfig();
            compConfCustomParam1.setComponentNo(componentNo);
            compConfCustomParam1.setConfigName(ComponentConstants.CONFIG_NAME_CUSTOM_PARAM_1);
            compConfCustomParam1.setConfigValue(customParam1);
            componentConfigDao.create(compConfCustomParam1);
        }

        // 2?
        if (compConfCustomParam2 != null) {
            compConfCustomParam2.setConfigValue(customParam2);
            componentConfigDao.update(compConfCustomParam2);
        } else {
            compConfCustomParam2 = new ComponentConfig();
            compConfCustomParam2.setComponentNo(componentNo);
            compConfCustomParam2.setConfigName(ComponentConstants.CONFIG_NAME_CUSTOM_PARAM_2);
            compConfCustomParam2.setConfigValue(customParam2);
            componentConfigDao.create(compConfCustomParam2);
        }

        // 3?
        if (compConfCustomParam3 != null) {
            compConfCustomParam3.setConfigValue(customParam3);
            componentConfigDao.update(compConfCustomParam3);
        } else {
            compConfCustomParam3 = new ComponentConfig();
            compConfCustomParam3.setComponentNo(componentNo);
            compConfCustomParam3.setConfigName(ComponentConstants.CONFIG_NAME_CUSTOM_PARAM_3);
            compConfCustomParam3.setConfigValue(customParam3);
            componentConfigDao.create(compConfCustomParam3);
        }

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), componentNo,
                component.getComponentName(), null, null, "ComponentUpdate", null, null, null);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<ComponentTypeDto> getComponentTypes(Long farmNo) {
        List<ComponentTypeDto> dtos = new ArrayList<ComponentTypeDto>();

        List<ComponentType> componentTypes = componentTypeDao.readAll();

        // ????
        List<Component> components = componentDao.readByFarmNo(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);
        }

        for (ComponentType componentType : componentTypes) {
            // ???????
            if (ComponentConstants.LAYER_NAME_LB.equals(componentType.getLayer())) {
                continue;
            }

            // ?
            List<Long> availableInstanceNos = new ArrayList<Long>();

            // ??????
            for (Instance instance : instances) {
                Image image = imageDao.read(instance.getImageNo());
                String[] componentTypeNos = StringUtils.split(image.getComponentTypeNos(), ",");
                boolean available = false;
                for (String componentTypeNo : componentTypeNos) {
                    if (componentType.getComponentTypeNo().equals(Long.parseLong(componentTypeNo.trim()))) {
                        available = true;
                        break;
                    }
                }
                if (available) {
                    availableInstanceNos.add(instance.getInstanceNo());
                }
            }

            // ??????????????????????????
            for (Component component : components) {
                ComponentType type = componentTypeDao.read(component.getComponentTypeNo());
                if (StringUtils.equals(componentType.getLayer(), type.getLayer())) {
                    List<ComponentInstance> componentInstances = componentInstanceDao
                            .readByComponentNo(component.getComponentNo());
                    for (ComponentInstance componentInstance : componentInstances) {
                        ComponentInstanceStatus status = ComponentInstanceStatus
                                .fromStatus(componentInstance.getStatus());
                        if (BooleanUtils.isTrue(componentInstance.getAssociate())
                                || status != ComponentInstanceStatus.STOPPED) {
                            availableInstanceNos.remove(componentInstance.getInstanceNo());
                        }
                    }
                }
            }

            // DTO??
            ComponentTypeDto dto = new ComponentTypeDto();
            dto.setComponentType(componentType);
            dto.setInstanceNos(availableInstanceNos);

            dtos.add(dto);
        }

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

        return dtos;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ComponentTypeDto getComponentType(Long componentNo) {
        // ????
        Component component = componentDao.read(componentNo);

        // ????
        ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());

        // ?
        List<Instance> instances = new ArrayList<Instance>();
        List<Instance> allInstances = instanceDao.readByFarmNo(component.getFarmNo());
        for (Instance instance : allInstances) {
            // ?
            if (BooleanUtils.isTrue(instance.getLoadBalancer())) {
                continue;
            }

            instances.add(instance);
        }

        // ????
        List<Component> components = componentDao.readByFarmNo(component.getFarmNo());

        // ?
        List<Long> availableInstanceNos = new ArrayList<Long>();

        // ??????
        for (Instance instance : instances) {
            Image image = imageDao.read(instance.getImageNo());
            String[] componentTypeNos = StringUtils.split(image.getComponentTypeNos(), ",");
            boolean available = false;
            for (String componentTypeNo : componentTypeNos) {
                if (componentType.getComponentTypeNo().equals(Long.parseLong(componentTypeNo.trim()))) {
                    available = true;
                    break;
                }
            }
            if (available) {
                availableInstanceNos.add(instance.getInstanceNo());
            }
        }

        // ??????????????????????????
        for (Component component2 : components) {
            if (componentNo.equals(component2.getComponentNo())) {
                continue;
            }
            ComponentType componentType2 = componentTypeDao.read(component2.getComponentTypeNo());
            if (StringUtils.equals(componentType.getLayer(), componentType2.getLayer())) {
                List<ComponentInstance> componentInstances = componentInstanceDao
                        .readByComponentNo(component2.getComponentNo());
                for (ComponentInstance componentInstance : componentInstances) {
                    ComponentInstanceStatus status = ComponentInstanceStatus
                            .fromStatus(componentInstance.getStatus());
                    if (BooleanUtils.isTrue(componentInstance.getAssociate())
                            || status != ComponentInstanceStatus.STOPPED) {
                        availableInstanceNos.remove(componentInstance.getInstanceNo());
                    }
                }
            }
        }

        // DTO??
        ComponentTypeDto dto = new ComponentTypeDto();
        dto.setComponentType(componentType);
        dto.setInstanceNos(availableInstanceNos);

        return dto;
    }

    protected ComponentType getComponentType(String componentTypeName) {
        List<ComponentType> componentTypes = componentTypeDao.readAll();
        for (ComponentType componentType : componentTypes) {
            if (componentType.getComponentTypeName().equals(componentTypeName)) {
                return componentType;
            }
        }
        throw new RuntimeException("No such ComponentType: " + componentTypeName);
    }

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

        // ????
        Component component = componentDao.read(componentNo);
        if (component == null) {
            // ???????
            return;
        }

        // ?????????????
        List<ComponentInstance> componentInstances = componentInstanceDao.readByComponentNo(componentNo);
        for (ComponentInstance componentInstance : componentInstances) {
            ComponentInstanceStatus status = ComponentInstanceStatus.fromStatus(componentInstance.getStatus());
            if (status != ComponentInstanceStatus.STOPPED) {
                // ????????
                throw new AutoApplicationException("ESERVICE-000302", component.getComponentName());
            }
        }

        // ???????????
        List<AwsVolume> awsVolumes = awsVolumeDao.readByComponentNo(componentNo);
        for (AwsVolume awsVolume : awsVolumes) {
            if (StringUtils.isNotEmpty(awsVolume.getInstanceId())) {
                // ????????
                Instance instance = instanceDao.read(awsVolume.getInstanceNo());
                throw new AutoApplicationException("ESERVICE-000310", instance.getInstanceName());
            }
        }
        // ???????????
        List<CloudstackVolume> csVolumes = cloudstackVolumeDao.readByComponentNo(componentNo);
        for (CloudstackVolume csVolume : csVolumes) {
            if (StringUtils.isNotEmpty(csVolume.getInstanceId())) {
                // ????????
                Instance instance = instanceDao.read(csVolume.getInstanceNo());
                throw new AutoApplicationException("ESERVICE-000310", instance.getInstanceName());
            }
        }
        List<VmwareDisk> vmwareDisks = vmwareDiskDao.readByComponentNo(componentNo);
        for (VmwareDisk vmwareDisk : vmwareDisks) {
            if (BooleanUtils.isTrue(vmwareDisk.getAttached())) {
                // ????????
                Instance instance = instanceDao.read(vmwareDisk.getInstanceNo());
                throw new AutoApplicationException("ESERVICE-000310", instance.getInstanceName());
            }
        }
        List<VcloudDisk> vcloudDisks = vcloudDiskDao.readByComponentNo(componentNo);
        for (VcloudDisk vcloudDisk : vcloudDisks) {
            if (BooleanUtils.isTrue(vcloudDisk.getAttached())) {
                // Vcloud????????????????????????
                Instance instance = instanceDao.read(vcloudDisk.getInstanceNo());
                InstanceStatus status = InstanceStatus.fromStatus(instance.getStatus());
                if (InstanceStatus.STOPPED != status) {
                    throw new AutoApplicationException("ESERVICE-000310", instance.getInstanceName());
                }
            }
        }
        // ???????????
        List<AzureDisk> azureDisks = azureDiskDao.readByComponentNo(componentNo);
        for (AzureDisk azureDisk : azureDisks) {
            if (StringUtils.isNotEmpty(azureDisk.getInstanceName())) {
                // ????????
                Instance instance = instanceDao.read(azureDisk.getInstanceNo());
                throw new AutoApplicationException("ESERVICE-000310", instance.getInstanceName());
            }
        }
        // ???????????
        List<OpenstackVolume> osVolumes = openstackVolumeDao.readByComponentNo(componentNo);
        for (OpenstackVolume osVolume : osVolumes) {
            if (StringUtils.isNotEmpty(osVolume.getInstanceId())) {
                // ????????
                Instance instance = instanceDao.read(osVolume.getInstanceNo());
                throw new AutoApplicationException("ESERVICE-000310", instance.getInstanceName());
            }
        }
        // ???????????
        List<NiftyVolume> niftyVolumes = niftyVolumeDao.readByComponentNo(componentNo);
        for (NiftyVolume niftyVolume : niftyVolumes) {
            if (StringUtils.isNotEmpty(niftyVolume.getInstanceId())) {
                // ????????
                Instance instance = instanceDao.read(niftyVolume.getInstanceNo());
                throw new AutoApplicationException("ESERVICE-000310", instance.getInstanceName());
            }
        }

        // ???????????????
        List<LoadBalancer> loadBalancers = loadBalancerDao.readByComponentNo(componentNo);
        if (!loadBalancers.isEmpty()) {
            throw new AutoApplicationException("ESERVICE-000309", loadBalancers.get(0).getLoadBalancerName());
        }

        // ??
        instanceConfigDao.deleteByComponentNo(componentNo);

        // ??????
        doAssociate(componentNo, new ArrayList<Long>());
        componentInstanceDao.deleteByComponentNo(componentNo);

        // ????
        componentConfigDao.deleteByComponentNo(componentNo);

        // ???
        // TODO CLOUD BRANCHING
        Farm farm = farmDao.read(component.getFarmNo());

        // AWS??
        // TODO: ???????
        for (AwsVolume awsVolume : awsVolumes) {
            if (StringUtils.isEmpty(awsVolume.getVolumeId())) {
                continue;
            }

            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    awsVolume.getPlatformNo());

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

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

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

                // EC2??DeleteVolume???????Wait???
                //awsProcessClient.waitDeleteVolume(volumeId);
            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        awsVolumeDao.deleteByComponentNo(componentNo);

        // CLOUDSTACK??
        // TODO: ???????
        for (CloudstackVolume csVolume : csVolumes) {
            if (StringUtils.isEmpty(csVolume.getVolumeId())) {
                continue;
            }

            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    csVolume.getPlatformNo());

            //
            Platform platform = platformDao.read(gateway.getPlatformNo());
            Instance instance = instanceDao.read(csVolume.getInstanceNo());
            CloudstackInstance csInstance = cloudstackInstanceDao.read(csVolume.getInstanceNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), csVolume.getComponentNo(),
                    component.getComponentName(), csVolume.getInstanceNo(), instance.getInstanceName(),
                    "CloudStackVolumeDelete", csInstance.getInstanceType(), instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), csVolume.getVolumeId() });

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

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

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        cloudstackVolumeDao.deleteByComponentNo(componentNo);

        // VMware??
        // TODO: ??????
        for (VmwareDisk vmwareDisk : vmwareDisks) {
            if (StringUtils.isEmpty(vmwareDisk.getFileName())) {
                continue;
            }
            VmwareProcessClient vmwareProcessClient = vmwareProcessClientFactory
                    .createVmwareProcessClient(vmwareDisk.getPlatformNo());
            try {
                vmwareDiskProcess.deleteDisk(vmwareProcessClient, vmwareDisk.getDiskNo());
            } catch (AutoException ignore) {
                // ??????????????
            } finally {
                vmwareProcessClient.getVmwareClient().logout();
            }
        }
        vmwareDiskDao.deleteByComponentNo(componentNo);

        // VCloud??
        // VCLoud????doAssociate?????
        //        for (VcloudDisk vcloudDisk : vcloudDisks) {
        //            if (StringUtils.isEmpty(vcloudDisk.getDiskId())) {
        //                continue;
        //            }
        //
        //            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(), vcloudDisk.getPlatformNo());
        //
        //            //
        //            Platform platform = platformDao.read(gateway.getPlatformNo());
        //            Instance instance = instanceDao.read(vcloudDisk.getInstanceNo());
        //            VcloudInstance vcloudInstance = vcloudInstanceDao.read(vcloudDisk.getInstanceNo());
        //            //TODO ??
        //            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), vcloudDisk.getComponentNo(),
        //                    component.getComponentName(), vcloudDisk.getInstanceNo(), instance.getInstanceName(),
        //                    "VcloudVolumeDelete", vcloudInstance.getInstanceType(),  instance.getPlatformNo(), new Object[] { platform.getPlatformName(), vcloudDisk.getDiskId() });
        //
        //            try {
        //                // ?
        //                // VCloud??DiskNo
        //                gateway.deleteVolume(String.valueOf(vcloudDisk.getDiskNo()));
        //
        //                //
        //                eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), vcloudDisk.getComponentNo(),
        //                        component.getComponentName(), vcloudDisk.getInstanceNo(), instance.getInstanceName(),
        //                        "VcloudVolumeDeleteFinish", vcloudInstance.getInstanceType(), instance.getPlatformNo(), new Object[] { platform.getPlatformName(), vcloudDisk.getDiskId() });
        //
        //            } catch (AutoException ignore) {
        //                // ??????????????
        //            }
        //        }
        //        vcloudDiskDao.deleteByComponentNo(componentNo);

        // Azure??
        // TODO: ???????
        for (AzureDisk azureDisk : azureDisks) {
            if (StringUtils.isEmpty(azureDisk.getDiskName())) {
                continue;
            }

            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    azureDisk.getPlatformNo());

            //
            Platform platform = platformDao.read(gateway.getPlatformNo());
            Instance instance = instanceDao.read(azureDisk.getInstanceNo());
            AzureInstance azureInstance = azureInstanceDao.read(azureDisk.getInstanceNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), azureDisk.getComponentNo(),
                    component.getComponentName(), azureDisk.getInstanceNo(), 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(), azureDisk.getInstanceNo(),
                        instance.getInstanceName(), "AzureDiskDeleteFinish", azureInstance.getInstanceType(),
                        instance.getPlatformNo(),
                        new Object[] { platform.getPlatformName(), azureDisk.getDiskName() });

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        azureDiskDao.deleteByComponentNo(componentNo);

        // Openstack??
        // TODO: ???????
        for (OpenstackVolume osVolume : osVolumes) {
            if (StringUtils.isEmpty(osVolume.getVolumeId())) {
                continue;
            }

            IaasGatewayWrapper gateway = iaasGatewayFactory.createIaasGateway(farm.getUserNo(),
                    osVolume.getPlatformNo());

            //
            Platform platform = platformDao.read(gateway.getPlatformNo());
            Instance instance = instanceDao.read(osVolume.getInstanceNo());
            OpenstackInstance osInstance = openstackInstanceDao.read(osVolume.getInstanceNo());
            eventLogger.log(EventLogLevel.DEBUG, farm.getFarmNo(), farm.getFarmName(), osVolume.getComponentNo(),
                    component.getComponentName(), osVolume.getInstanceNo(), instance.getInstanceName(),
                    "OpenstackVolumeDelete", osInstance.getInstanceType(), instance.getPlatformNo(),
                    new Object[] { platform.getPlatformName(), osVolume.getVolumeId() });

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

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

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        openstackVolumeDao.deleteByComponentNo(componentNo);

        // Nifty??
        // TODO: ???????
        for (NiftyVolume niftyVolume : niftyVolumes) {
            if (StringUtils.isEmpty(niftyVolume.getVolumeId())) {
                continue;
            }

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

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

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

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

            } catch (AutoException ignore) {
                // ??????????????
            }
        }
        niftyVolumeDao.deleteByComponentNo(componentNo);

        // ????
        componentDao.delete(component);

        // 
        StringBuilder dpath = new StringBuilder("/opt/userdata/");
        dpath.append(LoggingUtils.getUserName());
        dpath.append(System.getProperty("file.separator"));
        dpath.append(LoggingUtils.getFarmName());
        dpath.append(System.getProperty("file.separator"));
        dpath.append(component.getComponentName());
        File delDir = new File(dpath.toString());
        if (delDir.exists()) {
            deleteDirectoryAndFile(delDir);
        }

        // 
        eventLogger.log(EventLogLevel.INFO, farm.getFarmNo(), farm.getFarmName(), componentNo,
                component.getComponentName(), null, null, "ComponentDelete", null, null, null);
    }

    private void deleteDirectoryAndFile(File delFile) {
        if (delFile == null || !delFile.exists()) {
            return;
        }
        if (delFile.isFile()) {
            // 
            if (delFile.exists() && !delFile.delete()) {
                delFile.deleteOnExit();
            }
        } else {
            // ?????
            File[] list = delFile.listFiles();
            for (int i = 0; i < list.length; i++) {
                deleteDirectoryAndFile(list[i]);
            }
            if (delFile.exists() && !delFile.delete()) {
                delFile.deleteOnExit();
            }
        }
    }

    protected Image getImage(Long platformNo, String imageName) {
        List<Image> images = imageDao.readAll();
        for (Image image : images) {
            if (image.getPlatformNo().equals(platformNo) && image.getImageName().equals(imageName)) {
                return image;
            }
        }
        throw new RuntimeException("No such Image: " + platformNo + ", " + imageName);
    }

    protected String createUrl(String ipAddress, Long componentTypeNo) {

        //        String url = "http://";
        //        ComponentType componentType = componentTypeDao.read(componentTypeNo);
        //        if (componentType.getComponentTypeName().equals("apache")) {
        //            url = url + ipAddress + ":80/";
        //        } else if (componentType.getComponentTypeName().equals("tomcat")) {
        //            url = url + ipAddress + ":8080/";
        //        } else if (componentType.getComponentTypeName().equals("geronimo")) {
        //            url = url + ipAddress + ":8080/console/";
        //        } else if (componentType.getComponentTypeName().equals("mysql")) {
        //            url = url + ipAddress + ":8085/phpmyadmin/";
        //        } else if (componentType.getComponentTypeName().equals("prjserver")) {
        //            url = url + ipAddress + "/trac/prj/top/";
        //        }

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

    protected int createPort(Long componentTypeNo) {
        ComponentType componentType = componentTypeDao.read(componentTypeNo);
        if (componentType.getComponentTypeName().equals("apache")) {
            return 80;
        } else if (componentType.getComponentTypeName().equals("tomcat")) {
            return 8080;
        } else if (componentType.getComponentTypeName().equals("geronimo")) {
            return 8080;
        } else if (componentType.getComponentTypeName().equals("mysql")) {
            return 8085;
        } else if (componentType.getComponentTypeName().equals("prjserver")) {
            return 80;
        }
        return 0;
    }

    protected ComponentInstanceStatus getComponentInstanceStatus(Farm farm, ComponentInstance componentInstance,
            Instance instance) {
        // ????????
        ComponentInstanceStatus status = ComponentInstanceStatus.fromStatus(componentInstance.getStatus());
        if (BooleanUtils.isTrue(componentInstance.getEnabled())) {
            if (status == ComponentInstanceStatus.STOPPED) {
                InstanceStatus instanceStatus = InstanceStatus.fromStatus(instance.getStatus());
                if (instanceStatus == InstanceStatus.WARNING) {
                    // ?Waring??????Warning??
                    return ComponentInstanceStatus.WARNING;
                } else if (BooleanUtils.isTrue(farm.getScheduled())) {
                    // ??????Starting??
                    return ComponentInstanceStatus.STARTING;
                }
            } else if (status == ComponentInstanceStatus.RUNNING
                    && BooleanUtils.isTrue(componentInstance.getConfigure())) {
                if (BooleanUtils.isTrue(farm.getScheduled())) {
                    // ???Running??????Configuring??
                    return ComponentInstanceStatus.CONFIGURING;
                }
            }
        } else {
            if (status == ComponentInstanceStatus.RUNNING || status == ComponentInstanceStatus.WARNING) {
                if (BooleanUtils.isTrue(farm.getScheduled())) {
                    // ??????Stopping??
                    return ComponentInstanceStatus.STOPPING;
                }
            }
        }
        return status;
    }

    protected ComponentStatus getComponentStatus(List<ComponentInstance> componentInstances) {
        // ????
        ComponentStatus componentStatus;
        Set<ComponentInstanceStatus> statuses = new HashSet<ComponentInstanceStatus>();
        for (ComponentInstance componentInstance : componentInstances) {
            statuses.add(ComponentInstanceStatus.fromStatus(componentInstance.getStatus()));
        }
        if (statuses.contains(ComponentInstanceStatus.WARNING)) {
            componentStatus = ComponentStatus.WARNING;
        } else if (statuses.contains(ComponentInstanceStatus.CONFIGURING)) {
            componentStatus = ComponentStatus.CONFIGURING;
        } else if (statuses.contains(ComponentInstanceStatus.RUNNING)) {
            if (statuses.contains(ComponentInstanceStatus.STARTING)) {
                componentStatus = ComponentStatus.CONFIGURING;
            } else if (statuses.contains(ComponentInstanceStatus.STOPPING)) {
                componentStatus = ComponentStatus.CONFIGURING;
            } else {
                componentStatus = ComponentStatus.RUNNING;
            }
        } else if (statuses.contains(ComponentInstanceStatus.STARTING)) {
            componentStatus = ComponentStatus.STARTING;
        } else if (statuses.contains(ComponentInstanceStatus.STOPPING)) {
            componentStatus = ComponentStatus.STOPPING;
        } else {
            componentStatus = ComponentStatus.STOPPED;
        }
        return componentStatus;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<Object> checkAttachDisk(Long farmNo, Long componentNo, String instanceName,
            String notSelectedItem, Collection<Object> moveList) {

        List<InstanceDto> instances = instanceService.getInstances(farmNo);
        for (InstanceDto instance : instances) {
            if (StringUtils.equals(instanceName, instance.getInstance().getInstanceName())) {
                //TODO CLOUD BRANCHING
                if (instance.getAwsVolumes() != null) {
                    // AwsVolume?
                    for (AwsVolume awsVolume : instance.getAwsVolumes()) {
                        if (componentNo.equals(awsVolume.getComponentNo())) {
                            if (StringUtils.isNotEmpty(awsVolume.getInstanceId())) {
                                // ????????
                                moveList.add(notSelectedItem);
                            }
                            break;
                        }
                    }
                } else if (instance.getVmwareDisks() != null) {
                    // VmwareDisk?
                    for (VmwareDisk vmwareDisk : instance.getVmwareDisks()) {
                        if (componentNo.equals(vmwareDisk.getComponentNo())) {
                            if (BooleanUtils.isTrue(vmwareDisk.getAttached())) {
                                // ????????
                                moveList.add(notSelectedItem);
                            }
                            break;
                        }
                    }
                } else if (instance.getCloudstackVolumes() != null) {
                    // CloudstackVolume?
                    for (CloudstackVolume cloudstackVolume : instance.getCloudstackVolumes()) {
                        if (componentNo.equals(cloudstackVolume.getComponentNo())) {
                            if (StringUtils.isNotEmpty(cloudstackVolume.getInstanceId())) {
                                // ????????
                                moveList.add(notSelectedItem);
                            }
                            break;
                        }
                    }
                } else if (instance.getVcloudDisks() != null) {
                    // VcloudDisk?
                    for (VcloudDisk vcloudDisk : instance.getVcloudDisks()) {
                        if (componentNo.equals(vcloudDisk.getComponentNo())) {
                            if (BooleanUtils.isTrue(vcloudDisk.getAttached())) {
                                if (InstanceStatus
                                        .fromStatus(instance.getInstance().getStatus()) != InstanceStatus.STOPPED) {
                                    // ????????
                                    moveList.add(notSelectedItem);
                                }
                            }
                            break;
                        }
                    }
                } else if (instance.getAzureDisks() != null) {
                    // AzureDisk?
                    for (AzureDisk azureDisk : instance.getAzureDisks()) {
                        if (componentNo.equals(azureDisk.getComponentNo())) {
                            if (StringUtils.isNotEmpty(azureDisk.getInstanceName())) {
                                if (InstanceStatus
                                        .fromStatus(instance.getInstance().getStatus()) != InstanceStatus.STOPPED) {
                                    // ????????
                                    moveList.add(notSelectedItem);
                                }
                            }
                            break;
                        }
                    }
                } else if (instance.getNiftyVolumes() != null) {
                    // NiftyVolume?
                    for (NiftyVolume niftyVolume : instance.getNiftyVolumes()) {
                        if (componentNo.equals(niftyVolume.getComponentNo())) {
                            if (StringUtils.isNotEmpty(niftyVolume.getInstanceId())) {
                                // ????????
                                moveList.add(notSelectedItem);
                            }
                            break;
                        }
                    }
                } else if (instance.getOpenstackVolumes() != null) {
                    // OpenstackVolume?
                    for (OpenstackVolume openstackVolume : instance.getOpenstackVolumes()) {
                        if (componentNo.equals(openstackVolume.getComponentNo())) {
                            if (StringUtils.isNotEmpty(openstackVolume.getInstanceId())) {
                                // ????????
                                moveList.add(notSelectedItem);
                            }
                            break;
                        }
                    }
                }
            }
        }

        return moveList;
    }

    /**
     * instanceService???
     *
     * @param instanceService instanceService
     */
    public void setInstanceService(InstanceService instanceService) {
        this.instanceService = instanceService;
    }

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

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

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

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

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

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

}