package com.bocloud.ims.service.resource.server;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.compute.HostDriver;
import com.bocloud.cmp.driver.compute.ResourcePoolDriver;
import com.bocloud.cmp.driver.compute.ServerDriver;
import com.bocloud.cmp.driver.monitor.MonitorDriver;
import com.bocloud.cmp.driver.network.NetworkDriver;
import com.bocloud.cmp.entity.enums.BocloudStatus;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.entity.enums.ModuleCode;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.HostOperateModel;
import com.bocloud.cmp.model.HostSystem;
import com.bocloud.cmp.model.SwitchModel;
import com.bocloud.common.encrypt.AESEncrptor;
import com.bocloud.common.encrypt.Encryptor;
import com.bocloud.common.enums.BoCloudService;
import com.bocloud.common.enums.ResourceCatalog;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.IDFactory;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.common.VendorSyncRecord;
import com.bocloud.ims.entity.params.ServerPerformanceParam;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.Ip.IpStatus;
import com.bocloud.ims.interfaces.resource.ServerService;
import com.bocloud.ims.interfaces.scheduler.SnapshotTaskService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.service.model.cmdb.CmdbInfo;
import com.bocloud.ims.service.model.cmdb.CmdbRelation;
import com.bocloud.ims.service.transportor.SingleVmwareTransportor;
import com.bocloud.ims.service.transportor.VmwareTransportor;
import com.bocloud.ims.service.utils.*;
import com.bocloud.service.core.CurrentService;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service("vmwareServerService")
public class VmwareServerServiceImpl extends ServerServiceImpl implements ServerService {
    private static Logger logger = LoggerFactory.getLogger(VmwareServerServiceImpl.class);

    public VmwareServerServiceImpl(CurrentService currentService) {
        super(currentService);
    }

    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private MonitorDriver monitorDriver;
    @Autowired
    private ServerRepository serverRepository;
    @Autowired
    private ImageRepository imageRepository;
    @Autowired
    private ClusterRepository clusterRepository;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private CloudServerRepository cloudServerRepository;
    @Autowired
    private VolumeRepository volumeRepository;
    @Autowired
    private ServerConfigRepository serverConfigRepository;
    @Autowired
    private ServerAssetsRepository serverAssetsRepository;
    @Autowired
    private ResourceRepository resourceRepository;
    @Autowired
    private NetworkHostRepository networkHostRepository;
    @Autowired
    private ResourcePoolDriver resourcePoolDriver;
    @Autowired
    private IpPoolRepository ipPoolRepository;
    @Autowired
    private ClusterNodeRepository clusterNodeRepository;
    @Autowired
    private ResourcePoolRepository resourcePoolRepository;
    @Autowired
    private StoreHostRepository storeHostRepository;
    @Autowired
    private NetworkRepository networkRepository;
    @Autowired
    private SnapshotRepository snapshotRepository;
    @Autowired
    private NetworkCardRepository networkCardRepository;
    @Autowired
    private SwitcherRepository switcherRepository;
    @Autowired
    private PortGroupRepository portGroupRepository;
    @Autowired
    private DataStoreRepository dataStoreRepository;
    @Autowired
    private ServerLabelRepository serverLabelRepository;
    @Autowired
    private IpRepository ipRepository;
    @Autowired
    private VdcRepository vdcRepository;
    @Autowired
    private HostDriver hostDriver;
    @Autowired
    private NetworkDriver networkDriver;
    @Autowired
    private TaskExecutor taskExecutor;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;
    @Autowired
    private CmdbMessagePublisher cmdbMessagePublisher;
    @Autowired
    @Qualifier("ServerService")
    private ServerService serverService;
    @Autowired
    private ServerDriver serverDriver;
    @Autowired
    private TagRepository tagRepository;
    @Autowired
    private IpPoolPortGroupRepository ipPoolPortGroupRepository;
    @Autowired
    private SnapshotTaskService snapshotTaskService;


    @Override
    public BocloudResult create(HostOperateModel model, RequestContext context) {
        try {
            Encryptor encryptor = new AESEncrptor();
            if (!StringUtils.isEmpty(model.getPassword())) {
                model.setPassword(encryptor.decrypt(model.getPassword(), null));
            }
            // license节点数校验
            BocloudResult licenseResult = this.licenseCheck(model.getVendorId(), 1, 0);
            if (licenseResult.isFailed()) {
                return licenseResult;
            }
            Long userId = context.getTarget();
            Long vendorId = model.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            if (null == vendor) {
                return new BocloudResult(false, "获取云供应商失败");
            }
            if (!CloudProvider.VMWARE.name().equals(vendor.getType())) {
                return new BocloudResult(false, "平台类型" + vendor.getType() + "错误!");
            }
            Vdc vdc = vdcRepository.query(model.getVdcId());
            if (null == vdc) {
                return new BocloudResult(false, "虚拟数据中心不存在");
            }
            // 启动一个线程
            taskExecutor.execute(() -> {
                BocloudResult result = hostDriver.create(vendor.getUuid(), null, model);
                String type = vendor.getType();
                String operate = type.toLowerCase() + ".host";
                if (result.isSuccess() && null != result.getData()) {
                    try {
                        List<CmdbInfo> infos = Lists.newArrayList();
                        String content = JSONObject.toJSONString(result.getData());
                        HostSystem hostSystem = JSONObject.parseObject(content, HostSystem.class);
                        Server server = new Server();
                        BeanUtils.copyProperties(hostSystem, server);
                        server.setManageIp(hostSystem.getHostIp());
                        server.preSave(userId, userId, vendorId, model.getVdcId(), model.getClusterId());
                        server.setResourceId(IDFactory.instance().uuid());
                        server.setOsCategory("ESXi");
                        serverRepository.save(server);
                        Long hostId = server.getId();
                        // 处理IP地址
                        if (!StringUtils.isEmpty(server.getManageIp())) {
                            Ip ip = new Ip(server.getManageIp(), null, null, null, vendorId,
                                    IDFactory.instance().uuid(), null, IpStatus.used);
                            ip.setCatalog("PM");
                            ip.setTarget(hostId);
                            ipRepository.save(ip);
                        }
                        SyncVmwareUtils utils = new SyncVmwareUtils(cloudServerRepository, dataStoreRepository,
                                serverRepository, snapshotRepository, networkRepository, null, storeHostRepository,
                                networkCardRepository, portGroupRepository, networkHostRepository,
                                serverConfigRepository, resourceRepository, ipRepository, imageRepository,
                                volumeRepository);
                        // 保存主机配置信息
                        ServerConfig config = utils.addServerConfig(hostSystem, hostId);
                        // 保存资源
                        server.setConfig(config);
                        List<CmdbRelation> serverRelations = Lists.newArrayList();
                        serverRelations
                                .add(new CmdbRelation(ModuleCode.VDC.name(), 3L, ListUtils.getList(vdc.getGuid())));
                        if (null != model.getClusterId()) {
                            Cluster cluster = clusterRepository.query(model.getClusterId());
                            serverRelations.add(new CmdbRelation(ModuleCode.CLUSTER.name(), 1L,
                                    ListUtils.getList(cluster.getGuid())));
                        } else {
                            serverRelations
                                    .add(new CmdbRelation(ModuleCode.VDC.name(), 1L, ListUtils.getList(vdc.getGuid())));
                        }
                        infos.add(CmdbInfoConvertor.getInfo(server, config, null, serverRelations));
                        List<String> privateIps = Lists.newArrayList();
                        if (!StringUtils.isEmpty(server.getManageIp())) {
                            privateIps.add(server.getManageIp());
                        }
                        Resource resource = new Resource(ResourceCategory.Computer.name(),
                                ResourceCatalog.PHYSICAL.name(), server.getId(), JSONObject.toJSONString(privateIps),
                                server.getCatalog(), vendor.getId());
                        resource.preSave(server.getName(), server.getStatus(), userId, context.getTenant());
                        resource.setInventory(JSONObject.toJSONString(server));
                        resourceRepository.save(resource);
                        // 添加交换机
                        Map<String, Long> switcherMap = Maps.newHashMap();
                        Map<String, PortGroup> vsNetMap = Maps.newHashMap();
                        for (Switcher switcher : server.getSwitchers()) {
                            switcher.preSave(userId, userId, vendorId, server.getVdcId(), hostId);
                            switcherRepository.save(switcher);
                            for (PortGroup group : switcher.getGroups()) {
                                group.preSave(userId, userId, vendorId, switcher.getId());
                                portGroupRepository.save(group);
                                if ("VIRTUAL".equals(group.getType())) {
                                    vsNetMap.put(group.getName(), group);
                                }
                            }
                            switcherMap.put(switcher.getName(), switcher.getId());
                        }
                        // 处理宿主机网络
                        List<Network> networks = server.getNetworks();
                        // 获取数据中心的网络关系
                        Map<String, Network> networkMap = Maps.newHashMap();
                        List<Network> oldNetworks = networkRepository.listByVdc(server.getVdcId());
                        for (Network network : oldNetworks) {
                            networkMap.put(network.getNetworkVal(), network);
                        }
                        for (Network network : networks) {
                            if (networkMap.containsKey(network.getNetworkVal())) {
                                continue;
                            }
                            if (vsNetMap.containsKey(network.getName())) {
                                PortGroup group = vsNetMap.get(network.getName());
                                network.setPortNum(group.getPortNum());
                                network.setType("VSWITCH");
                                network.preSave(userId, userId, vendorId, server.getVdcId());
                                networkRepository.save(network);
                                networkMap.put(network.getNetworkVal(), network);
                                List<CmdbRelation> relations = Lists.newArrayList();
                                relations.add(
                                        new CmdbRelation(ModuleCode.VDC.name(), 1L, ListUtils.getList(vdc.getGuid())));
                                infos.add(CmdbInfoConvertor.getInfo(network, null, relations));
                            }
                        }
                        // 保存物理网卡
                        utils.addCard(vendorId, hostId, userId, "PM", server.getNetcards(), switcherMap);
                        // 保存存储
                        Map<String, DataStore> storeMap = new HashMap<>();
                        List<DataStore> stores = dataStoreRepository.listByVdc(server.getVdcId());
                        for (DataStore store : stores) {
                            storeMap.put(store.getStoreVal(), store);
                        }
                        List<DataStore> dataStores = server.getDataStores();
                        if (null != dataStores) {
                            for (DataStore dataStore : dataStores) {
                                if (storeMap.containsKey(dataStore.getStoreVal())) {
                                    continue;
                                }
                                dataStore.preSave(userId, userId, vendorId, model.getVdcId());
                                dataStoreRepository.save(dataStore);
                                storeMap.put(dataStore.getStoreVal(), dataStore);
                                List<CmdbRelation> relations = Lists.newArrayList();
                                relations.add(
                                        new CmdbRelation(ModuleCode.VDC.name(), 1L, ListUtils.getList(vdc.getGuid())));
                                infos.add(CmdbInfoConvertor.getInfo(dataStore, null, relations));
                            }
                        }
                        // 宿主机和存储建立关系
                        utils.addStore(vendorId, hostId, userId, "PM", server.getStores(), storeMap);
                        // 宿主机和网络的关系
                        utils.addNetwork(vendorId, hostId, userId, "PM", server.getNetworks(), networkMap,
                                Maps.newHashMap());
                        // 保存虚拟机
                        List<CloudServer> cloudServers = server.getServers();
                        if (!ListTool.isEmpty(cloudServers)) {
                            List<IpPool> pools = ipPoolRepository.listByIpVersion(null);
                            for (CloudServer cloudServer : cloudServers) {
                                cloudServer.setVendorType(vendor.getType());
                                utils.addServerCascade(storeMap, cloudServer, vendorId, hostId, server.getVdcId(),
                                        userId, server.getPowerState(), networkMap, Maps.newHashMap(), vendor.getType(),
                                        pools);
                                List<CmdbRelation> relations = Lists.newArrayList();
                                relations.add(new CmdbRelation(ModuleCode.PM.name(), 1L,
                                        ListUtils.getList(server.getGuid())));
                                relations.add(new CmdbRelation(ModuleCode.PM.name(), 3L,
                                        ListUtils.getList(server.getGuid())));
                                // cmdb:虚拟机与数据存储关系
                                List<String> storeGuids = Lists.newArrayList();
                                for (String store : cloudServer.getStores()) {
                                    if (storeMap.containsKey(store)) {
                                        storeGuids.add(storeMap.get(store).getGuid());
                                    }
                                }
                                relations.add(new CmdbRelation(ModuleCode.DATASTORE.name(), 3L, storeGuids));
                                // cmdb:虚拟机与网络关系
                                List<String> networkGuids = Lists.newArrayList();
                                Map<String, Network> netMap = networkMap;
                                for (Network network : cloudServer.getNetworks()) {
                                    String val = network.getNetworkVal();
                                    if (netMap.containsKey(val)) {// 网络存在则直接保存,标准网络
                                        networkGuids.add(netMap.get(val).getGuid());
                                    }
                                }
                                relations.add(new CmdbRelation(ModuleCode.NETWORK.name(), 3L, networkGuids));
                                infos.add(CmdbInfoConvertor.getInfo(cloudServer, null, relations));
                            }
                        }
                        cmdbMessagePublisher.send(CmdbInfoConvertor.getModel(BoCloudService.IMS, infos));
                        if (null != model.getClusterId()) {
                            ClusterNode node = new ClusterNode(server.getManageIp(), server.getResourceId(), "PM",
                                    model.getClusterId());
                            node.setCreatorId(userId);
                            node.setMenderId(userId);
                            node.setName(server.getName());
                            node.setStatus(server.getStatus());
                            clusterNodeRepository.save(node);
                        }
                        // 保存资源池
                        VmResourcePool vmResourcePool = JSONObject
                                .parseObject(JSONObject.toJSONString(hostSystem.getResourcePool()), VmResourcePool.class);
                        if (null != vmResourcePool) {
                            vmResourcePool.setParentId(0L);
                            vmResourcePool.setVdcId(model.getVdcId());
                            vmResourcePool.setOwner(server.getId());
                            vmResourcePool.setOwnerCategory("HOST");
                            vmResourcePool.setVendorId(vendor.getId());
                            vmResourcePool.setTenantId(0L);
                            vmResourcePool.setCreatorId(userId);
                            resourcePoolRepository.save(vmResourcePool);
                        }
                    } catch (Exception e) {
                        logger.error("Create host fail:", e);
                        resourceEventPublisher.send(new OperateResult(false, "添加宿主机失败", operate,
                                MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                                OperateResult.OperateCategory.ResourceEvent, context));
                        return;
                    }
                }
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
            });
            return new BocloudResult(true, "添加任务已下发，正在执行……");
        } catch (Exception e) {
            logger.error("Create host fail:", e);
            return new BocloudResult(false, "添加失败");
        }
    }

    @Override
    public BocloudResult remove(Long id, Boolean force, RequestContext context) {
        String path = Server.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Server host = this.serverRepository.query(id);
            if (null == host) {
                logger.warn("Server data does not exist!");
                return new BocloudResult(false, "主机不存在");
            }
            if (null != host.getClusterId() && host.getMaintained() != null && !host.getMaintained()
                    && host.getConnected() != null && host.getConnected()) {
                return new BocloudResult(false, "存在于集群中的宿主机必须进入维护模式才能删除");
            }
            Long userId = context.getTarget();
            if (null == host.getVendorId()) {
                serverConfigRepository.removeBySid(id);
                serverAssetsRepository.removeBySid(id);
                serverRepository.remove(id, userId);
                resourceRepository.remove(id, ResourceCategory.Computer.name(), ResourceCatalog.PHYSICAL.name(),
                        userId);
                // 同步到cmdb
                List<CmdbInfo> infos = Lists.newArrayList();
                infos.add(CmdbInfoConvertor.getInfo(host, null, "delete", null));
                cmdbMessagePublisher.send(CmdbInfoConvertor.getModel(BoCloudService.IMS, infos));
                return new BocloudResult(true, id, "删除成功");
            }
            CloudVendor vendor = cloudVendorRepository.query(host.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "获取云供应商失败");
            }
            if (!CloudProvider.VMWARE.name().equals(vendor.getType())) {
                return new BocloudResult(false, "平台类型" + vendor.getType() + "错误!");
            }
            List<NetworkHost> nHosts = networkHostRepository.list(id, "PM");
            for (NetworkHost nHost : nHosts) {
                Network network = networkRepository.query(nHost.getNetworkId());
                if (null == network) {
                    continue;
                }
                if ("DVSWITCH".equals(network.getType())) {
                    return new BocloudResult(false, "无法删除，该主机正在被分布式交换机【" + network.getName() + "】使用");
                }
            }
            taskExecutor.execute(() -> {
                // 移除宿主机
                HostOperateModel model = new HostOperateModel();
                model.setHostName(host.getName());

                model.setClusterName(host.getClusterName());
                BocloudResult result = hostDriver.remove(vendor.getUuid(), null, model);
                String type = vendor.getType();
                String operate = type.toLowerCase() + ".host";
                if (result.isSuccess()) {
                    try {
                        // 同步到cmdb
                        List<CmdbInfo> infos = Lists.newArrayList();
                        List<CloudServer> servers = cloudServerRepository.listByHid(id);
                        for (CloudServer server : servers) {
                            // 删除虚拟机下的快照
                            snapshotRepository.removeByVm(server.getId(), userId);
                            storeHostRepository.deleteByHost(server.getId(), "VM");
                            networkHostRepository.deleteByHost(server.getId(), "VM");
                            networkCardRepository.removeByHost(server.getId(), "VM", userId);
                            resourceRepository.remove(server.getId(), ResourceCategory.Computer.name(),
                                    ResourceCatalog.LOGICAL.name(), userId);
                            // 回收IP
                            ipRepository.delete(server.getId(), "VM", vendor.getId());
                            // cmdb删除虚拟机
                            infos.add(CmdbInfoConvertor.getInfo(server, "delete", null));
                        }
                        // 删除该宿主机上的标准交换机
                        List<Switcher> switchers = switcherRepository.listByHostId(id);
                        List<String> netNames = Lists.newArrayList();
                        for (Switcher switcher : switchers) {
                            List<PortGroup> groups = portGroupRepository.listBySwitcher(switcher.getId());
                            for (PortGroup group : groups) {
                                if ("VIRTUAL".equals(group.getType())) {
                                    netNames.add(group.getName());
                                }
                            }
                            portGroupRepository.removeBySwitcher(switcher.getId(), userId);
                        }
                        // 获取宿主机所在数据中心的所有标准交换机
                        switchers = switcherRepository.listByVdc(host.getVdcId(), "VSWITCH");
                        Map<String, String> groupMap = Maps.newHashMap();
                        for (Switcher switcher : switchers) {
                            List<PortGroup> groups = portGroupRepository.listBySwitcher(switcher.getId());
                            for (PortGroup group : groups) {
                                if ("VIRTUAL".equals(group.getType())) {
                                    groupMap.put(group.getName(), group.getName());
                                }
                            }
                        }
                        // 当删除的交换机所涉及的端口组名称在该数据中心下只有一个时，删除该数据中心下以该端口组命名的标准网络
                        for (String netName : netNames) {
                            if (groupMap.containsKey(netName)) {
                                continue;
                            }
                            networkRepository.remove(netName, "VSWITCH", host.getVdcId(), userId);
                        }
                        switcherRepository.removeByHostId(id, userId);
                        // 删除虚拟机
                        cloudServerRepository.removeByHost(id, userId);
                        List<StoreHost> storeHosts = storeHostRepository.list(id, "PM");
                        storeHostRepository.deleteByHost(id, "PM");
                        // 如果数据存储没有被任何被任何宿主机挂载，则删除该存储
                        for (StoreHost storeHost : storeHosts) {
                            Long storeId = storeHost.getStoreId();
                            int count = storeHostRepository.countByStore(storeId, "PM");
                            if (count == 0) {
                                dataStoreRepository.remove(storeId, userId);
                            } else {
                                DataStore store = dataStoreRepository.query(storeId);
                                Integer hostNum = store.getHostNum();
                                if (null != hostNum) {
                                    hostNum--;
                                    store.setHostNum(hostNum < 0 ? 0 : hostNum);
                                    store.setMenderId(userId);
                                    store.setGmtModify(new Date());
                                    dataStoreRepository.update(store);
                                }

                            }

                        }
                        networkHostRepository.deleteByHost(id, "PM");
                        networkCardRepository.removeByHost(id, "PM", userId);
                        resourceRepository.remove(id, ResourceCategory.Computer.name(), ResourceCatalog.PHYSICAL.name(),
                                userId);
                        serverConfigRepository.removeBySid(id);
                        serverAssetsRepository.removeBySid(id);
                        serverRepository.remove(id, userId);
                        serverLabelRepository.deleteByTarget(id, "PM");
                        // cmdb删除宿主机
                        infos.add(CmdbInfoConvertor.getInfo(host, null, "delete", null));
                        cmdbMessagePublisher.send(CmdbInfoConvertor.getModel(BoCloudService.IMS, infos));
                        // 回收IP
                        ipRepository.delete(host.getId(), "PM", vendor.getId());
                        if (null != host.getClusterId()) {
                            clusterNodeRepository.removeByRid(host.getResourceId(), userId);
                        }
                        // 删除集群下的资源池信息
                        resourcePoolRepository.removeByOwner(id, "HOST", userId);
                        JSONObject object = new JSONObject();
                        object.put("type", Server.class.getSimpleName());
                        object.put("data", host);
                        amqpTemplate.convertAndSend("cmp.resource.deleted.queue", object);

                    } catch (Exception e) {
                        logger.error("删除失败", e);
                        resourceEventPublisher.send(new OperateResult(false, "删除宿主机失败", operate,
                                MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                                OperateResult.OperateCategory.ResourceEvent, context));
                        return;
                    }
                }
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
            });
            return new BocloudResult(true, "删除任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("Remove server fail:", e);
            return new BocloudResult(false, "删除失败");
        }
    }

    @Override
    public BocloudResult stop(Long id, RequestContext context) {
        String path = Server.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Server server = this.serverRepository.getServerBean(id);
            if (null == server) {
                logger.warn("Server data does not exist!");
                return new BocloudResult(false, server, "该服务器不存在");
            }
            ServerConfig config = serverConfigRepository.getBySid(id);
            CloudProvider type = serverService.getCloudVendorType(server);
            if (type != CloudProvider.VMWARE) {
                return new BocloudResult(false, "平台类型" + type.name() + "错误!");
            }
            HostOperateModel model = new HostOperateModel();
            model.setHostName(server.getName());
            Vdc vdc = vdcRepository.query(server.getVdcId());
            if (null == vdc) {
                return new BocloudResult(false, "数据中心不存在");
            }
            model.setVdcName(vdc.getName());
            CloudVendor vendor = cloudVendorRepository.query(server.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "宿主机所在云平台不存在");
            }
            boolean result = hostDriver.shutdown(vendor.getUuid(), null, model).isSuccess();
            String message = "关闭物理主机【" + server.getName() + "】失败";
            if (result) {
                server.setStatus(BocloudStatus.Server.STOPPED.name());
                server.setPowerState(BocloudStatus.Server.STOPPED.name());
                serverRepository.update(server);
                // 同步到cmdb
                List<CmdbInfo> infos = Lists.newArrayList();
                infos.add(CmdbInfoConvertor.getInfo(server, config, "modify", null));
                cmdbMessagePublisher.send(CmdbInfoConvertor.getModel(BoCloudService.IMS, infos));
                message = "关闭物理主机【" + server.getName() + "】成功";
            }
            return new BocloudResult(result, server, message);
        } catch (Exception e) {
            logger.error("Stop server fail:", e);
            return new BocloudResult(false, "关闭失败");
        }
    }

    @Override
    public BocloudResult restart(Long id, RequestContext context) {
        try {
            Server server = this.serverRepository.getServerBean(id);
            if (null == server) {
                logger.warn("Server data does not exist!");
                return new BocloudResult(false, server, "该服务器不存在");
            }
            ServerConfig config = serverConfigRepository.getBySid(id);
            // 如果是ESXi主机则调用vijava接口进行重启操作
            CloudProvider type = serverService.getCloudVendorType(server);
            if (type != CloudProvider.VMWARE) {
                return new BocloudResult(false, "平台类型" + type.name() + "错误!");
            }
            HostOperateModel model = new HostOperateModel();
            model.setHostName(server.getName());
            Vdc vdc = vdcRepository.query(server.getVdcId());
            if (null == vdc) {
                return new BocloudResult(false, "数据中心不存在");
            }
            model.setVdcName(vdc.getName());
            CloudVendor vendor = cloudVendorRepository.query(server.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "宿主机所在云平台不存在");
            }
            boolean result = hostDriver.reboot(vendor.getUuid(), null, model).isSuccess();
            String message = "重启物理主机【" + server.getName() + "】失败";
            if (result) {
                message = "重启物理主机【" + server.getName() + "】成功";
            }
            return new BocloudResult(result, message);
        } catch (Exception e) {
            logger.error("Restart server fail:", e);
            return new BocloudResult(false, "重启失败");
        }
    }

    private static OperateResult.OperateCategory operateCategory = OperateResult.OperateCategory.ResourceEvent;

    @Override
    public BocloudResult createVSwitch(SwitchModel switchModel, RequestContext context) {
        try {
            Long userId = context.getTarget();
            CloudVendor vendor = cloudVendorRepository.query(switchModel.getVendorId());
            if (null == vendor) {
                logger.error("get cloudVendor and region failure");
                return new BocloudResult(false, "未获取到云供应商");
            }
            Map<Long, List<Long>> hosts = switchModel.getHosts();
            Map<String, List<String>> values = Maps.newHashMap();
            List<NetworkCard> networkCards = Lists.newArrayList();
            // 获取宿主机名称和网卡名称
            if (hosts.isEmpty()) {
                return new BocloudResult(false, "请求参数有误：无宿主机参数");
            }
            Long hostId = hosts.keySet().iterator().next();
            List<Long> cardIds = hosts.get(hostId);
            List<String> cards = Lists.newArrayList();
            for (Long cardId : cardIds) {
                NetworkCard card = this.networkCardRepository.query(cardId);
                cards.add(card.getName());
                networkCards.add(card);
            }
            Server server = this.serverRepository.query(hostId);
            values.put(server.getName(), cards);
            switchModel.setValues(values);
            // 取得数据中心名称，放入SwitchModel中
            Long vdcId = switchModel.getVdcId();
            Vdc vdc = vdcRepository.query(vdcId);
            switchModel.setVdcName(vdc.getName());
            taskExecutor.execute(() -> {
                String operate = vendor.getType().toLowerCase() + ".switcher";
                String content = "标准交换机网络【" + switchModel.getName() + "】创建失败";
                // 创建交换机
                BocloudResult result = networkDriver.createVSwitch(vendor.getUuid(), switchModel);
                try {
                    if (result.isSuccess()) {
                        content = "标准交换机网络【" + switchModel.getName() + "】创建成功";
                        // 保存标准交换机
                        Switcher switcher = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                Switcher.class);
                        List<PortGroup> groups = switcher.getGroups();
                        Network network = switcher.getNetwork();
                        switcher.preSave(userId, userId, vendor.getId(), vdcId, server.getId());
                        switcherRepository.save(switcher);
                        // 保存分布式交换机端口组
                        for (PortGroup group : groups) {
                            group.preSave(userId, userId, vendor.getId(), switcher.getId());
                            portGroupRepository.save(group);
                        }
                        // 更新网卡的状态
                        for (NetworkCard card : networkCards) {
                            card.setUsed(true);
                            card.setMenderId(userId);
                            card.setSwitcherId(switcher.getId());
                            networkCardRepository.update(card);
                        }
                        List<Network> networks = networkRepository.listByVdc(vdcId);
                        Map<String, Network> maps = Maps.newHashMap();
                        for (Network net : networks) {
                            maps.put(net.getNetworkVal(), net);
                        }
                        Long networkId = null;
                        if (maps.containsKey(network.getNetworkVal())) {
                            networkId = maps.get(network.getNetworkVal()).getId();
                        } else {
                            network.preSave(userId, userId, vendor.getId(), vdcId);
                            networkRepository.save(network);
                            networkId = network.getId();
                        }
                        networkHostRepository.save(new NetworkHost(networkId, hostId, vendor.getId(), "PM"));

                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                            MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
                } catch (Exception e) {
                    logger.error("Get Message Exception:", e);
                    resourceEventPublisher.send(new OperateResult(false, content, operate,
                            MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
                }
            });
            return new BocloudResult(true, "创建任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("exception info", e);
            return new BocloudResult(false, "创建交换机失败");
        }
    }

    @Override
    public BocloudResult disconn(Long id, RequestContext context) {
        String path = Server.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Server server = serverRepository.query(id);
            if (null == server) {
                return new BocloudResult(false, "宿主机不存在");
            }
            CloudVendor vendor = cloudVendorRepository.query(server.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "获取运供应商失败");
            }
            HostOperateModel model = new HostOperateModel();
            model.setHostName(server.getName());
            BocloudResult result = hostDriver.disconn(vendor.getUuid(), null, model);
            Long userId = context.getTarget();
            if (result.isSuccess()) {
                server.setConnected(false);
                server.setMenderId(userId);
                server.setPowerState("UNKNOWN");
                server.setStatus("UNKNOWN");
                this.serverRepository.update(server);
                // 宿主机断开连接，更新虚拟机状态
                this.cloudServerRepository.updateStatusByHost(id, "UNKNOWNON", userId,
                        BocloudStatus.Server.RUNNING.name());
                this.cloudServerRepository.updateStatusByHost(id, "UNKNOWNOFF", userId,
                        BocloudStatus.Server.STOPPED.name());
                this.cloudServerRepository.updateStatusByHost(id, "UNKNOWNSUSPEND", userId,
                        BocloudStatus.Server.SUSPENDED.name());

                if (null != server.getClusterId()) {
                    ClusterNode node = this.clusterNodeRepository.queryByRid(server.getResourceId());
                    node.setStatus(server.getStatus());
                    node.setMenderId(userId);
                    clusterNodeRepository.update(node);
                }
            }
            return result;
        } catch (Exception e) {
            logger.error("disconnect host error:", e);
            return new BocloudResult(false, "断开连接失败");
        }
    }

    @Override
    public BocloudResult reconn(Long id, RequestContext context) {
        String path = Server.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Server host = serverRepository.query(id);
            if (null == host) {
                return new BocloudResult(false, "宿主机不存在");
            }
            CloudVendor vendor = cloudVendorRepository.query(host.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "获取运供应商失败");
            }
            Long userId = context.getTarget();
            // 启动一个线程
            taskExecutor.execute(() -> {
                HostOperateModel model = new HostOperateModel();
                model.setHostName(host.getName());
                BocloudResult result = hostDriver.reconn(vendor.getUuid(), null, model);
                String type = vendor.getType();
                String operate = type.toLowerCase() + ".host";
                try {
                    if (result.isSuccess()) {
                        host.setConnected(true);
                        host.setMenderId(userId);
                        host.setPowerState("RUNNING");
                        host.setStatus("RUNNING");
                        serverRepository.update(host);
                        // 更新集群节点状态
                        if (null != host.getClusterId()) {
                            ClusterNode node = clusterNodeRepository.queryByRid(host.getResourceId());
                            node.setStatus(host.getStatus());
                            node.setMenderId(userId);
                            clusterNodeRepository.update(node);
                        }
                        Long vendorId = vendor.getId();
                        // 宿主机和网络的关系
                        Map<String, Network> networkMap = Maps.newHashMap();
                        Map<String, String> groupMap = Maps.newHashMap();
                        List<Network> oldNetworks = networkRepository.listByVdc(host.getVdcId());
                        for (Network network : oldNetworks) {
                            networkMap.put(network.getNetworkVal(), network);
                        }

                        // 宿主机连接，更新虚拟机状态
                        List<CloudServer> oldServers = cloudServerRepository.listByHid(id);
                        Map<String, CloudServer> serverMap = Maps.newHashMap();
                        for (CloudServer server : oldServers) {
                            serverMap.put(server.getInstanceId(), server);
                        }
                        List<CloudServer> servers = JSONObject.parseArray(JSONObject.toJSONString(result.getData()),
                                CloudServer.class);
                        Map<String, DataStore> storeMap = new HashMap<>();
                        List<DataStore> stores = dataStoreRepository.listByVdc(host.getVdcId());
                        for (DataStore store : stores) {
                            storeMap.put(store.getStoreVal(), store);
                        }
                        for (CloudServer cloudServer : servers) {
                            if (serverMap.containsKey(cloudServer.getInstanceId())) {
                                CloudServer server = serverMap.get(cloudServer.getInstanceId());
                                String status = null;
                                if ("poweredOn".equalsIgnoreCase(cloudServer.getStatus())) {
                                    status = BocloudStatus.Server.RUNNING.name();
                                } else if ("poweredOff".equalsIgnoreCase(cloudServer.getStatus())) {
                                    status = BocloudStatus.Server.STOPPED.name();
                                } else if ("suspended".equalsIgnoreCase(cloudServer.getStatus())) {
                                    status = BocloudStatus.Server.SUSPENDED.name();
                                } else {
                                    status = BocloudStatus.Server.EXCEPTION.name();
                                }
                                if (!status.equals(server.getStatus())) {
                                    server.setStatus(status);
                                    server.setMenderId(userId);
                                    server.setToolsInstalled(cloudServer.getToolsInstalled());
                                    server.setToolsRunning(cloudServer.getToolsRunning());
                                    cloudServerRepository.update(server);
                                }
                                // 移除存在更新的虚拟机
                                serverMap.remove(cloudServer.getInstanceId());
                            } else {
                                SyncVmwareUtils utils = new SyncVmwareUtils(cloudServerRepository, dataStoreRepository,
                                        serverRepository, snapshotRepository, networkRepository, null,
                                        storeHostRepository, networkCardRepository, portGroupRepository,
                                        networkHostRepository, null, resourceRepository, ipRepository, imageRepository);
                                cloudServer.setVendorType(vendor.getType());
                                List<IpPool> pools = ipPoolRepository.listByIpVersion(null);
                                utils.addServerCascade(storeMap, cloudServer, vendorId, id, host.getVdcId(), userId,
                                        host.getPowerState(), networkMap, groupMap, vendor.getType(), pools);
                            }
                        }
                        Iterator<CloudServer> iterator = serverMap.values().iterator();
                        while (iterator.hasNext()) {
                            CloudServer server = iterator.next();
                            resourceRepository.remove(server.getId(), ResourceCategory.Computer.name(),
                                    ResourceCatalog.LOGICAL.name(), userId);
                            cloudServerRepository.remove(server.getId(), userId);
                            // 回收IP
                            ipRepository.delete(server.getId(), "PM", server.getVendorId());
                        }
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
                            MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                            OperateResult.OperateCategory.ResourceEvent, context));
                } catch (Exception e) {
                    logger.error("reconnect host error:", e);
                    resourceEventPublisher.send(new OperateResult(false, "连接宿主机失败", operate,
                            MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                            OperateResult.OperateCategory.ResourceEvent, context));
                }
            });
            return new BocloudResult(true, "连接任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("reconnect host error:", e);
            return new BocloudResult(false, "连接失败");
        }
    }

    @Override
    public BocloudResult entermaintain(Long id, RequestContext context) {
        String path = Server.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Server server = serverRepository.query(id);
            if (null == server) {
                return new BocloudResult(false, "宿主机不存在");
            }

            List<CloudServer> cloudServers = cloudServerRepository.listByHid(id);
            for (CloudServer cloudServer : cloudServers) {
                if (cloudServer.getStatus().equals(BocloudStatus.Server.RUNNING.name())) {
                    return new BocloudResult(false, "宿主机下存在运行的虚拟机，无法进入维护模式，需人工关闭");
                }
            }
            CloudVendor vendor = cloudVendorRepository.query(server.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "获取运供应商失败");
            }
            HostOperateModel model = new HostOperateModel();
            model.setHostName(server.getName());
            BocloudResult result = hostDriver.enterMode(vendor.getUuid(), null, model);
            if (result.isSuccess()) {
                server.setMaintained(true);
                server.setMenderId(context.getTarget());
                this.serverRepository.update(server);
            }
            return result;
        } catch (Exception e) {
            logger.error("enter maintain error:", e);
            return new BocloudResult(false, "进入维护模式失败");
        }
    }

    @Override
    public BocloudResult exitmaintain(Long id, RequestContext context) {
        String path = Server.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Server server = serverRepository.query(id);
            if (null == server) {
                return new BocloudResult(false, "宿主机不存在");
            }
            CloudVendor vendor = cloudVendorRepository.query(server.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "获取运供应商失败");
            }
            HostOperateModel model = new HostOperateModel();
            model.setHostName(server.getName());
            BocloudResult result = hostDriver.exitMode(vendor.getUuid(), null, model);
            if (result.isSuccess()) {
                server.setMaintained(false);
                server.setMenderId(context.getTarget());
                this.serverRepository.update(server);
            }
            return result;
        } catch (Exception e) {
            logger.error("exit maintain error:", e);
            return new BocloudResult(false, "退出维护模式失败");
        }
    }

    @Override
    public BocloudResult move(HostOperateModel model, RequestContext context) {
        try {
            CloudVendor vendor = cloudVendorRepository.query(model.getVendorId());
            if (null == vendor) {
                return new BocloudResult(false, "云平台不存在");
            }
            Server server = serverRepository.query(model.getHostId());
            if (null == server) {
                return new BocloudResult(false, "宿主机不存在");
            }
            if (server.getConnected() && null != server.getClusterId() && !server.getMaintained()) {
                return new BocloudResult(false, "宿主机不是维护模式且是连接状态，无法移动");
            }
            Vdc vdc = vdcRepository.query(server.getVdcId());
            if (null == vdc) {
                return new BocloudResult(false, "虚拟数据中心不存在！");
            }
            List<String> hosts = Lists.newArrayList();
            hosts.add(model.getHostName());
            model.setHosts(hosts);
            BocloudResult result = hostDriver.moveTo(vendor.getUuid(), null, model);
            Long userId = context.getTarget();
            if (result.isSuccess()) {
                Long oldClusterId = null;
                Long newClusterId = null;
                if (StringUtils.isEmpty(model.getClusterName())) {
                    oldClusterId = server.getClusterId();
                    server.setClusterId(null);
                    clusterNodeRepository.removeByRid(server.getResourceId(), userId);
                } else {
                    Cluster cluster = clusterRepository.getByName(model.getClusterName(), vdc.getId());
                    Long clusterId = 0L;
                    if (null != cluster) {
                        clusterId = cluster.getId();
                    }
                    if (null == server.getClusterId()) {

                        ClusterNode node = new ClusterNode(server.getManageIp(), server.getResourceId(), "PM",
                                clusterId);
                        node.setName(server.getName());
                        node.setCreatorId(userId);
                        node.setMenderId(userId);
                        node.setStatus(server.getStatus());
                        clusterNodeRepository.save(node);
                    } else {
                        ClusterNode node = this.clusterNodeRepository.queryByRid(server.getResourceId());
                        node.setClusterId(clusterId);
                        node.setStatus(server.getStatus());
                        node.setMenderId(userId);
                        clusterNodeRepository.update(node);
                    }
                    oldClusterId = server.getClusterId();
                    server.setClusterId(clusterId);
                    newClusterId = server.getClusterId();
                }
                server.setMenderId(userId);
                serverRepository.update(server);

                Cluster oldCluster = null;
                Cluster newCluster = null;
                if (null != oldClusterId) {
                    oldCluster = clusterRepository.query(oldClusterId);
                }
                if (null != newClusterId) {
                    newCluster = clusterRepository.query(newClusterId);
                }
                // 同步到cmdb
                List<CmdbInfo> infos = Lists.newArrayList();
                // 宿主机与对象的关系
                List<CmdbRelation> relations = Lists.newArrayList();
                relations.add(new CmdbRelation(ModuleCode.VDC.name(), 3L, ListUtils.getList(vdc.getGuid())));
                if (null != newCluster) {
                    relations.add(
                            new CmdbRelation(ModuleCode.CLUSTER.name(), 1L, ListUtils.getList(newCluster.getGuid())));
                } else {
                    relations.add(new CmdbRelation(ModuleCode.VDC.name(), 1L, ListUtils.getList(vdc.getGuid())));
                }
                ServerConfig config = serverConfigRepository.getBySid(server.getId());
                if (null == config) {
                    config = new ServerConfig();
                }
                infos.add(CmdbInfoConvertor.getInfo(server, config, null, relations));
                // 集群信息
                if (null != oldCluster) {
                    List<Server> list = serverRepository.listByCluster(oldCluster.getId());
                    Long cpuTotal = 0L;
                    Double memTotal = 0D;
                    Double diskTotal = 0D;
                    for (Server host : list) {
                        ServerConfig serverConfig = serverConfigRepository.getBySid(host.getId());
                        cpuTotal += serverConfig.getCpuHz();
                        memTotal += serverConfig.getMemoryCapacity();
                        diskTotal += serverConfig.getDiskCapacity();
                    }
                    oldCluster.setCpuTotal(cpuTotal);
                    oldCluster.setMemTotal(memTotal);
                    oldCluster.setDiskTotal(diskTotal);
                    infos.add(CmdbInfoConvertor.getInfo(oldCluster, "modify", null));
                }
                if (null != newCluster) {
                    List<Server> list = serverRepository.listByCluster(newCluster.getId());
                    Long cpuTotal = 0L;
                    Double memTotal = 0D;
                    Double diskTotal = 0D;
                    for (Server host : list) {
                        ServerConfig serverConfig = serverConfigRepository.getBySid(host.getId());
                        cpuTotal += serverConfig.getCpuHz();
                        memTotal += serverConfig.getMemoryCapacity();
                        diskTotal += serverConfig.getDiskCapacity();
                    }
                    newCluster.setCpuTotal(cpuTotal);
                    newCluster.setMemTotal(memTotal);
                    newCluster.setDiskTotal(diskTotal);
                    infos.add(CmdbInfoConvertor.getInfo(newCluster, "modify", null));
                }
                cmdbMessagePublisher.send(CmdbInfoConvertor.getModel(BoCloudService.IMS, infos));
                // 同步资源池数据
                VmwareTransportor transportor = new VmwareTransportor(resourcePoolRepository, clusterRepository,
                        serverRepository);
                List<VmResourcePool> pools = resourcePoolRepository.listByVdc(vdc.getId());
                BocloudResult bocloudResult = resourcePoolDriver.list(vendor.getUuid(), vdc.getName());
                if (bocloudResult.isSuccess()) {
                    List<VmResourcePool> newPools = JSONArray.parseArray(JSONObject.toJSONString(bocloudResult.getData()),
                            VmResourcePool.class);
                    transportor.syncResourcePool(pools, newPools, vdc.getId(), vendor.getId(), userId);
                }
            }
            return result;
        } catch (Exception e) {
            logger.error("exit maintain error:", e);
            return new BocloudResult(false, "移动主机失败");
        }
    }

    @Override
    public BocloudResult performance(String params, Long id, RequestContext context) {
    	JSONObject object = JSONTools.isJSONObj(params);
		try {
			CloudVendor vendor = this.cloudVendorRepository.query(object.getLong(Common.VENDORID));
			if (null == vendor) {
				logger.warn("Cloud vendor does not exist!");
				return new BocloudResult(false, "云平台不存在");
			}
			List<String> types = Lists.newArrayList();
			types.add("CPU");
			types.add("DISK");
			types.add("POWER");
			types.add("MEM");
			types.add("NET");
			types.add("SYSTEM");
			return new VmwareMonitorUtils(monitorDriver).getPerformance(object, vendor.getUuid(), types, "HostSystem");
		} catch (Exception e) {
			logger.error("查询数据失败", e);
			return new BocloudResult(false, "查询失败");
		}
    }

    @Override
    public BocloudResult syncVmByHost(Long id, RequestContext context) {
        try {
            Server server = serverRepository.query(id);
            if (null == server) {
                logger.error("宿主机不存在!");
                return new BocloudResult(false, "宿主机不存在");
            }
            Cluster cluster = clusterRepository.query(server.getClusterId());
            if (null == cluster) {
                logger.error("主机集群不存在!");
                return new BocloudResult(false, "主机集群不存在");
            }
            Vdc vdc = vdcRepository.query(cluster.getVdcId());
            if (null == vdc) {
                logger.error("数据中心不存在!");
                return new BocloudResult(false, "数据中心不存在");
            }
            CloudVendor vendor = cloudVendorRepository.query(cluster.getVendorId());
            if (null == vendor) {
                logger.error("平台不存在!");
                return new BocloudResult(false, "平台不存在");
            }
            // 启动一个线程
            new Thread(() -> {
                Date startTime = new Date();
                String path = CloudVendor.class.getSimpleName() + "_" + vendor.getId();
                String operate = vendor.getType().toLowerCase() + ".sync";
                BocloudResult result = new BocloudResult(false, "暂不支持");
                OperateResult operateResult = new OperateResult(true, "宿主机下虚拟机同步成功", operate,
                        MapTools.simpleMap("vendorId", vendor.getId()), OperateResult.OperateCategory.ResourceEvent, context);
                try (BocloudACLock lock = lockFactory.getACLock(path)) {
                    Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
                    CloudVendor cloudVendor = cloudVendorRepository.query(vendor.getId());
                    if (null == cloudVendor) {
                        logger.error("平台数据不存在!");
                        result = new BocloudResult(false, "平台数据不存在!");
                        operateResult.setSuccess(false);
                        operateResult.setMessage("平台数据不存在！");
                    }
                    if (operateResult.isSuccess()) {
                        String vendorUuid = vendor.getUuid();
                        String vendorName = vendor.getName();
                        String hostName = server.getName();
                        logger.info("开始执行平台{} 宿主机{} 的虚拟机同步操作", vendorName, hostName);
                        result = serverDriver.listByHost(vendorUuid, hostName);
                        if (result.isSuccess()) {
                            SingleVmwareTransportor tool = new SingleVmwareTransportor(networkRepository, networkCardRepository,
                                    switcherRepository, portGroupRepository, ipPoolPortGroupRepository,
                                    dataStoreRepository, storeHostRepository, networkHostRepository,
                                    cloudServerRepository, imageRepository, snapshotRepository, volumeRepository,
                                    resourceRepository, ipRepository, ipPoolRepository, snapshotTaskService,
                                    tagRepository, serverLabelRepository, amqpTemplate);
                            result = tool.syncVmByHost(vendor, vdc, server, result.getData(), context.getTarget());
                        }
                    }
                    logger.info("宿主机下虚拟机同步任务结果：{}", result.getMessage());
                    operateResult.setSuccess(result.isSuccess());
                    operateResult.setMessage(result.getMessage());
                } catch (Exception e) {
                    logger.error("宿主机下虚拟机同步任务异常", e);
                    operateResult.setSuccess(false);
                    operateResult.setMessage("宿主机下虚拟机同步任务异常");
                }
                resourceEventPublisher.send(operateResult);
                VendorSyncRecord record = new VendorSyncRecord();
                record.setVendorId(vendor.getId());
                record.setStartTime(startTime);
                record.setEndTime(new Date());
                record.setCost(record.getEndTime().getTime() - startTime.getTime());
                record.setResult(operateResult.getMessage());
                record.setCreatorId(context.getTarget());
                record.setSyncResult(operateResult.isSuccess());
                record.setAuto(false);
                amqpTemplate.convertAndSend("vendor.record.queue", record);
                if (operateResult.isSuccess()) {
                    // 发送给云平台统计队列对云平台重新统计
                    JSONObject object = new JSONObject();
                    object.put(Common.VENDORID, vendor.getId());
                    amqpTemplate.convertAndSend("vendor.statistics.queue", object);
                }
                // 更新云平台最后一次同步时间
                vendor.setGmtModify(record.getEndTime());
                vendor.setMenderId(context.getTarget());
                cloudVendorRepository.update(vendor);
            }).start();
            return new BocloudResult(true, "同步任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("sync vm by host exception ", e);
            return new BocloudResult(false, "同步失败!");
        }
    }
}
