package com.bocloud.ims.service.transporter.vendor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.entity.enums.ModuleCode;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.entity.enums.TagType;
import com.bocloud.cmp.model.*;
import com.bocloud.cmp.model.database.*;
import com.bocloud.common.enums.ResourceCatalog;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.model.Result;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.entity.middleware.*;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.service.model.cmdb.CmdbInfo;
import com.bocloud.ims.service.model.cmdb.CmdbRelation;
import com.bocloud.ims.service.transporter.AbstractTransporter;
import com.bocloud.ims.service.utils.CmdbInfoConvertor;
import com.bocloud.ims.service.utils.ListUtils;
import com.google.api.client.util.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

/**
 * 阿里云同步调整
 * @author ymh
 * @date 2022/01/26
 */
@Component
public class AliyunTransporter extends AbstractTransporter {

    private static Logger logger = LoggerFactory.getLogger(AliyunTransporter.class);

    @Override
    public Result transport(CloudVendor vendor, Long operator) {
    	return this.syncCloudResource(vendor, operator);
    }
    
    @Override
    public BocloudResult process(CloudVendor vendor, Object data, Region region, Long userId, List<CmdbInfo> infos) {
        try {
            if (null != data) {
                if (cloudServerRepository.hasBuilding(vendor.getId())) {
                    return new BocloudResult(false, "该平台下有云主机正在创建，请稍后进行同步操作");
                }
                String content = JSONObject.toJSONString(data);
                AliyunSyncModel model = JSONObject.parseObject(content, AliyunSyncModel.class);
                // 同步域
                logger.info("Starting sync region and zone......");
                this.syncRegion(model.getRegionModels(), region, vendor, userId);
                logger.info("End sync region and zone......");

                // 同步云主机规格
                logger.info("Starting sync instance type......");
                this.syncInstanceType(model.getFlavorModels(), vendor.getId(), region);
                logger.info("End sync instance type......");

                // 同步密钥
                logger.info("Starting sync keypair......");
                this.syncKeypair(model.getKeypairModels(), region.getRegionId(), vendor.getId(), userId);
                logger.info("End sync keypair...");
                List<Keypair> keyPairList = keypairRepository.listByVid(vendor.getId(), region.getRegionId());
                Map<String, Long> keyPairMap = new HashMap<>();
                for (Keypair keypair : keyPairList) {
                    keyPairMap.put(keypair.getName(), keypair.getId());
                }

                // 同步vpc
                logger.info("Starting sync vpc......");
                this.syncVpc(model.getVpcModels(), vendor.getId(), userId, region);
                logger.info("End sync vpc......");
                // 获取vpc信息
                Map<String, Vpc> vpcMap = Maps.newHashMap();
                List<Vpc> vpcList = vpcRepository.list(vendor.getId(), region.getRegionId());
                for (Vpc vpc : vpcList) {
                    vpcMap.put(vpc.getVpcId(), vpc);
                }

                // 同步交换机
                logger.info("Starting sync switch......");
                this.syncSubnets(model.getSubnetModels(), vendor.getId(), userId, region, vpcMap);
                logger.info("End sync switch......");
                List<Subnet> subnets = subnetRepository.listByRegion(vendor.getId(), region.getRegionId());
                Map<String, Subnet> subnetMap = Maps.newHashMap();
                for (Subnet subnet : subnets) {
                    subnetMap.put(subnet.getSubnetUuid(), subnet);
                }

                // 同步路由器
                logger.info("Starting sync router......");
                this.syncRouter(model.getRouterModels(), vendor.getId(), userId, vpcMap, region.getRegionId());
                logger.info("End sync router......");

                // 同步路由表
                logger.info("Starting sync route tables......");
                this.syncRouteTable(model.getRouteTableModels(), vendor.getId(), userId, vpcMap, region.getRegionId(),
                        subnetMap);
                logger.info("End sync route tables......");

                // 同步弹性公网IP
                logger.info("Starting sync elastic ip......");
                this.syncElasticIp(model.getElasticIpModels(), vendor.getId(), userId, region.getRegionId());
                logger.info("End sync elastic ip......");

                // 同步安全组
                logger.info("Starting sync security group......");
                this.syncSecurityGroup(model.getSecurityGroupModels(), vendor, userId, region.getRegionId(), vpcMap);
                logger.info("End sync security group......");
                List<SecurityGroup> groups = securityGroupRepository.listByVendorId(vendor.getId(),
                        region.getRegionId());
                Map<String, Long> groupMap = Maps.newHashMap();
                for (SecurityGroup group : groups) {
                    groupMap.put(group.getGroupUuid(), group.getId());
                }

                // 同步镜像
                logger.info("Starting sync image......");
                this.syncImage(model.getImageModels(), region, vendor, userId);
                logger.info("End sync image......");
                List<Image> imageList = imageRepository.listByVendorId(vendor.getId(), region.getRegionId());
                Map<String, Image> imageMap = Maps.newHashMap();
                for (Image image : imageList) {
                    imageMap.put(image.getImageUuid(), image);
                }

                // 同步云主机
                logger.info("Starting sync server......");
                this.syncServer(model.getServerModels(), vendor, userId, groupMap, region, imageMap, keyPairMap, infos);
                logger.info("End sync server......");
                List<CloudServer> cloudServers = cloudServerRepository.listByVendorId(vendor.getId(),
                        region.getRegionId());
                Map<String, Long> serverMap = Maps.newHashMap();
                for (CloudServer cloudServer : cloudServers) {
                    serverMap.put(cloudServer.getInstanceId(), cloudServer.getId());
                }

                // 同步NAT网关
                logger.info("Starting sync nat gateway......");
                this.syncNatGateWay(model.getNatGatewayModels(), vendor.getId(), userId, region.getRegionId(), vpcMap,
                        subnetMap);
                logger.info("End sync nat gateway......");

                // 同步云硬盘
                logger.info("Starting sync volume......");
                this.syncVolume(model.getVolumeModels(), vendor, userId, serverMap, region);
                logger.info("End sync volume......");
                // 获取云硬盘信息
                Map<String, Long> volumeMap = Maps.newHashMap();
                List<Volume> volumes = volumeRepository.listByVendorId(vendor.getId(), region.getRegionId());
                for (Volume volume : volumes) {
                    volumeMap.put(volume.getVolumeUuid(), volume.getId());
                }

                // 同步云快照
                logger.info("Starting sync snapshot......");
                this.syncSnapshot(model.getSnapshotModels(), vendor, userId, volumeMap, region);
                logger.info("End sync snapshot......");

                // 同步弹性网卡 关联安全组 关联vpc 关联云主机
                logger.info("Starting sync networkInterface......");
                this.syncNetworkInterface(model.getNetworkInterfaceModels(), vendor.getId(), userId, groupMap, vpcMap,
                        serverMap, region.getRegionId(), subnetMap);
                logger.info("End sync networkInterface......");

                // 国网POC去掉资源组同步，5.5发布需要改过来
                // 同步资源组
                logger.info("Starting sync resourcegroups ......");
                this.syncResourceGroups(model.getResourceGroupModels(), vendor, userId, region);
                logger.info("End sync resourcegroups ......");

                // 同步负载均衡实例
                logger.info("Starting sync lb......");
                this.syncLb(model.getLbModels(), vendor.getId(), userId, region.getRegionId(), vpcMap, subnetMap);
                logger.info("End sync lb......");

                // 同步负载监听器
                logger.info("Starting sync listeners ......");
                this.syncListeners(model.getListenerModels(), vendor.getId(), userId, region.getRegionId());
                logger.info("End sync listeners ......");

                // 同步pool虚拟服务器组
                logger.info("Starting sync pools ......");
                this.syncPools(model.getPoolModels(), vendor.getId(), userId, region.getRegionId());
                logger.info("End sync pools ......");

                // 同步member后端服务
                logger.info("Starting sync members ......");
                this.syncMembers(model.getMemberModels(), vendor.getId(), userId, region.getRegionId());
                logger.info("End sync members ......");

                // 同步访问控制
                logger.info("Starting sync access control ......");
                this.syncAcls(model.getAcls(), vendor.getId(), userId, region.getRegionId());
                logger.info("End sync access control ......");

                // 同步dbInstance
                logger.info("Starting sync dbInstances ......");
                this.syncDbInstances(model.getDbInstanceModels(), vendor, userId, region.getRegionId());
                logger.info("End sync dbInstances ......");

                // 同步dbFlavor
                logger.info("Starting sync dbFlavor ......");
                this.syncdbFlavors(model.getDbFlavorModel(), vendor, userId, region.getRegionId());
                logger.info("End sync dbFlavor ......");

                // 同步参数模板
                logger.info("Starting sync paramGroup ......");
                this.syncdbparamGroups(model.getDbInstanceParameterGroupModel(), vendor, userId, region.getRegionId());
                logger.info("End sync paramGroup ......");

                // 同步OSS对象存储
                logger.info("Starting sync aliyun OSS ......");
                this.syncBuckets(model.getBucketModels(), region.getRegionId(), vendor.getId(), userId);
                logger.info("End sync aliyun OSS ......");
            }
            return new BocloudResult(true, "云平台【" + vendor.getName() + "】平台数据同步成功");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult(false, "云平台【" + vendor.getName() + "】平台数据同步失败:" + e.getMessage());
        }
    }

    private void syncBuckets(List<BucketModel> bucketModels, String regionId, Long vendorId, Long userId)
            throws Exception {
        if (ListTool.isEmpty(bucketModels)) {
            // 删除对象用户存储桶
            bucketRepository.removeByVid(vendorId, regionId, userId);
            // 删除存储桶内资源
            bucketObjectRepository.removeByVid(vendorId, regionId, null, userId);
            return;
        }
        List<Bucket> buckets = bucketRepository.listByVendorId(vendorId, regionId);
        Map<String, Bucket> bucketMap = Maps.newConcurrentMap();

        for (Bucket bucket : buckets) {
            String bucketName = bucket.getName();
            if (bucketMap.containsKey(bucketName)) {
                bucketRepository.remove(bucket.getId(), userId);
                // 删除存储桶内资源
                bucketObjectRepository.removeByVid(vendorId, regionId, bucket.getId(), userId);
            } else {
                bucketMap.put(bucketName, bucket);
            }
        }
        for (BucketModel bucketModel : bucketModels) {
            String bucketName = bucketModel.getName();
            Bucket bucket = new Bucket();
            if (bucketMap.containsKey(bucketName)) {
                bucket = bucketMap.get(bucketName);
                BeanUtils.copyProperties(bucketModel, bucket);
                bucket.setRegionId(regionId);
                bucketRepository.update(bucket);
                syncBucketObjects(bucketModel.getBucketObjectModels(), regionId, bucket.getId(), vendorId, userId);
                bucketMap.remove(bucketName);
                continue;
            }
            BeanUtils.copyProperties(bucketModel, bucket);
            bucket.setRegionId(regionId);
            bucket.setVendorId(vendorId);
            bucket.setCreatorId(userId);
            bucket.setMenderId(userId);
            bucket.setTenantId(0L);
            bucketRepository.save(bucket);
            syncBucketObjects(bucketModel.getBucketObjectModels(), regionId, bucket.getId(), vendorId, userId);
        }
        for (Entry<String, Bucket> set : bucketMap.entrySet()) {
            bucketRepository.remove(set.getValue().getId(), userId);
            // 删除存储桶内资源
            bucketObjectRepository.removeByVid(vendorId, regionId, set.getValue().getId(), userId);
        }
    }

    private void syncBucketObjects(List<BucketObjectModel> bucketObjectModels, String regionId, Long bucketId,
                                   Long vendorId, Long userId) throws Exception {
        if (ListTool.isEmpty(bucketObjectModels)) {
            // 删除存储桶内资源
            bucketObjectRepository.removeByVid(vendorId, regionId, bucketId, userId);
            return;
        }
        List<BucketObject> bucketObjects = bucketObjectRepository.listByBucketId(bucketId, vendorId);
        Map<String, BucketObject> bucketObjectMap = Maps.newConcurrentMap();
        for (BucketObject bucketObject : bucketObjects) {
            String objectKey = bucketObject.getKey();
            if (null != objectKey) {
                if (bucketObjectMap.containsKey(objectKey)) {
                    // 删除存储桶内资源
                    bucketObjectRepository.remove(bucketObject.getId(), userId);
                } else {
                    bucketObjectMap.put(objectKey, bucketObject);
                }
            }
        }
        List<BucketObject> insertBucketObject = new ArrayList<BucketObject>();
        List<BucketObject> updateBucketObject = new ArrayList<BucketObject>();
        for (BucketObjectModel bucketObjectModel : bucketObjectModels) {
            String key = bucketObjectModel.getKey();
            BucketObject bucketObject = new BucketObject();
            if (bucketObjectMap.containsKey(key)) {
                bucketObject = bucketObjectMap.get(key);
                BeanUtils.copyProperties(bucketObjectModel, bucketObject);
                bucketObject.setRegionId(regionId);
                bucketObject.setBucketId(bucketId);
                updateBucketObject.add(bucketObject);
                bucketObjectMap.remove(key);
                continue;
            }
            BeanUtils.copyProperties(bucketObjectModel, bucketObject);
            bucketObject.setRegionId(regionId);
            bucketObject.setBucketId(bucketId);
            bucketObject.setVendorId(vendorId);
            bucketObject.setCreatorId(userId);
            bucketObject.setMenderId(userId);
            bucketObject.setTenantId(0L);
            insertBucketObject.add(bucketObject);
        }
        if (!ListTool.isEmpty(insertBucketObject)) {
            bucketObjectRepository.batchSave(insertBucketObject, insertBucketObject.size());
        }
        if (!ListTool.isEmpty(updateBucketObject)) {
            bucketObjectRepository.batchUpdate(updateBucketObject, updateBucketObject.size());
        }
        for (Entry<String, BucketObject> set : bucketObjectMap.entrySet()) {
            // 删除存储桶内资源
            bucketObjectRepository.remove(set.getValue().getId(), userId);
        }
    }

    private void syncdbparamGroups(List<DbInstanceParameterGroupModel> models, CloudVendor vendor, Long userId,
                                   String regionId) throws Exception {
        if (ListTool.isEmpty(models)) {
            rdsPublicCloudInstanceParameterGroupRepository.removeByVid(vendor.getId(), userId, regionId);
            return;
        }
        Map<String, RdsPublicCloudInstanceParameterGroup> groupMap = Maps.newHashMap();
        List<RdsPublicCloudInstanceParameterGroup> parameterGroups = rdsPublicCloudInstanceParameterGroupRepository
                .listByVid(vendor.getId(), regionId);
        for (RdsPublicCloudInstanceParameterGroup group : parameterGroups) {
            groupMap.put(group.getParameterGroupId(), group);
        }
        for (DbInstanceParameterGroupModel model : models) {
            RdsPublicCloudInstanceParameterGroup group = new RdsPublicCloudInstanceParameterGroup();
            if (groupMap.containsKey(model.getParameterGroupId())) {
                group = groupMap.get(model.getParameterGroupId());
                BeanUtils.copyProperties(model, group);
                group.setVendorId(vendor.getId());
                group.setRegionId(regionId);
                group.setGmtModify(new Date());
                group.setMenderId(userId);
                group.setParamDetail(model.getParamDetail().toJSONString());
                rdsPublicCloudInstanceParameterGroupRepository.update(group);
                groupMap.remove(model.getParameterGroupId());
            } else {
                BeanUtils.copyProperties(model, group);
                group.setVendorId(vendor.getId());
                group.setRegionId(regionId);
                group.setCreatorId(userId);
                group.setGmtCreate(new Date());
                group.setParamDetail(model.getParamDetail().toJSONString());
                rdsPublicCloudInstanceParameterGroupRepository.save(group);
                groupMap.remove(model.getParameterGroupId());
            }
        }
        for (RdsPublicCloudInstanceParameterGroup group : groupMap.values()) {
            rdsPublicCloudInstanceParameterGroupRepository.delete(group.getId(), userId);
        }
    }

    private void syncdbFlavors(List<DbFlavorModel> flavorModels, CloudVendor vendor, Long userId, String regionId) throws Exception {
        if (ListTool.isEmpty(flavorModels)) {
            rdsPublicCLoudFlavorRepository.removeByVid(vendor.getId(), userId, regionId);
            return;
        }
        Map<String, RdsPublicCloudFlavor> map = Maps.newHashMap();
        List<RdsPublicCloudFlavor> flavorList = rdsPublicCLoudFlavorRepository.listByVid(vendor.getId(), regionId);
        for (RdsPublicCloudFlavor flavor : flavorList) {
            map.put(flavor.getFlavorUuid(), flavor);
        }
        for (DbFlavorModel flavorModel : flavorModels) {
            RdsPublicCloudFlavor publicCloudFlavor = new RdsPublicCloudFlavor();
            if (map.containsKey(flavorModel.getDBInstanceClass())) {
                publicCloudFlavor = map.get(flavorModel.getDBInstanceClass());
                publicCloudFlavor.setRegionId(flavorModel.getRegionId());
                publicCloudFlavor.setName(flavorModel.getDBInstanceClass());
                publicCloudFlavor.setFlavorUuid(flavorModel.getDBInstanceClass());
                publicCloudFlavor.setInstanceMode(flavorModel.getCategory());
                publicCloudFlavor.setStatus(flavorModel.getStatus());
                publicCloudFlavor.setVendorId(vendor.getId());
                publicCloudFlavor.setZone(flavorModel.getZoneId());
                publicCloudFlavor.setEngine(flavorModel.getEngine());
                publicCloudFlavor.setVersion(flavorModel.getVersion());
                publicCloudFlavor.setStorageType(flavorModel.getStorageType());
                publicCloudFlavor.setChargeType(flavorModel.getChargeType());
                publicCloudFlavor.setCategory(flavorModel.getCategory());
                publicCloudFlavor.setDeleted(false);
                publicCloudFlavor.setCreatorId(userId);
                publicCloudFlavor.setGmtCreate(new Date());
                rdsPublicCLoudFlavorRepository.update(publicCloudFlavor);
                map.remove(flavorModel.getDBInstanceClass());
            } else {
                publicCloudFlavor.setRegionId(flavorModel.getRegionId());
                publicCloudFlavor.setName(flavorModel.getDBInstanceClass());
                publicCloudFlavor.setFlavorUuid(flavorModel.getDBInstanceClass());
                publicCloudFlavor.setInstanceMode(flavorModel.getCategory());
                publicCloudFlavor.setStatus(flavorModel.getStatus());
                publicCloudFlavor.setVendorId(vendor.getId());
                publicCloudFlavor.setZone(flavorModel.getZoneId());
                publicCloudFlavor.setEngine(flavorModel.getEngine());
                publicCloudFlavor.setVersion(flavorModel.getVersion());
                publicCloudFlavor.setStorageType(flavorModel.getStorageType());
                publicCloudFlavor.setChargeType(flavorModel.getChargeType());
                publicCloudFlavor.setCategory(flavorModel.getCategory());
                publicCloudFlavor.setDeleted(false);
                publicCloudFlavor.setMenderId(userId);
                publicCloudFlavor.setGmtModify(new Date());
                rdsPublicCLoudFlavorRepository.save(publicCloudFlavor);
                map.remove(flavorModel.getDBInstanceClass());
            }
        }
        for (RdsPublicCloudFlavor value : map.values()) {
            rdsPublicCLoudFlavorRepository.delete(value.getId(), userId);
        }
    }

    private void syncDbInstances(List<DbInstanceModel> dbInstanceModels, CloudVendor vendor, Long userId, String regionId)
            throws Exception {
        if (ListTool.isEmpty(dbInstanceModels)) {
            rdsPublicCloudInstanceRepository.removeByVid(vendor.getId(), userId, regionId);
            return;
        }
        List<RdsPublicCloudInstance> rdsList = rdsPublicCloudInstanceRepository.listByVid(vendor.getId(), regionId);
        Map<String, RdsPublicCloudInstance> rdsMap = Maps.newHashMap();
        for (RdsPublicCloudInstance rds : rdsList) {
            rdsMap.put(rds.getInstanceId(), rds);
        }
        for (DbInstanceModel model : dbInstanceModels) {
            RdsPublicCloudInstance rds = new RdsPublicCloudInstance();
            // 更新
            if (rdsMap.containsKey(model.getInstanceId())) {
                rds = rdsMap.get(model.getInstanceId());
                BeanUtils.copyProperties(model, rds);
                rds.setInstanceId(model.getInstanceId());
                rds.setRegion(model.getRegionId());
                rds.setRegionId(model.getRegionId());
                rds.setAvailZone(model.getZoneId());
                rds.setDataStoreType(model.getEngine());
                rds.setDataStoreVersion(model.getVersion());
                rds.setName(model.getName());
                rds.setVswitchId(model.getVswitchId());
                rds.setVpcCloudInstanceId(model.getVpcCloudInstanceId());
                rds.setVolSize(model.getDbInstanceStorage());
                rds.setType(model.getInstanceType()); // 主备
                rds.setCategory(model.getCategory());
                rds.setMenderId(userId);
                rds.setGmtModify(new Date());
                rds.setVendorId(vendor.getId());
                rds.setVendorType(vendor.getType());
                rds.setFlavorId(model.getInstanceClass());
                rds.setVolSize(model.getDisk());
                // M转换GB
                if (null != model.getMemory()) {
                    rds.setMemory(model.getMemory().longValue() / 1024);
                }
                rds.setDbPort(model.getPort());
                rds.setVpcId(model.getVpcId());
                // 内网连接地址
                rds.setDnsName(model.getConnectionString());
                rds.setInstanceNetworkType(model.getNetworkType());
                rds.setCategory(model.getCategory());
                rds.setDbInstanceNetType(model.getNetType());
                rds.setMaxIops(model.getMaxIOPS());
                rds.setVpcCloudInstanceId(model.getVpcCloudInstanceId());
                rds.setSepcCode(model.getInstanceClass());
                rds.setPeriod(model.getPeriod());
                rds.setUsedTime(model.getUsedTime());
                rds.setResourceId(model.getResourceId());
                rds.setAutoRenew(model.getAutoRenew());
                rds.setParamGroupId(model.getDBParamGroupId());
                rds.setTimeZone(model.getDBTimeZone());
                rds.setIgnoreCase(model.getDBIsIgnoreCase());
                rdsPublicCloudInstanceRepository.update(rds);
                rdsMap.remove(model.getInstanceId());
            } else {
                // 新增
                BeanUtils.copyProperties(model, rds);
                rds.setInstanceId(model.getInstanceId());
                rds.setRegion(model.getRegionId());
                rds.setRegionId(model.getRegionId());
                rds.setAvailZone(model.getZoneId());
                rds.setDataStoreType(model.getEngine());
                rds.setDataStoreVersion(model.getVersion());
                rds.setName(model.getName());
                rds.setVswitchId(model.getVswitchId());
                rds.setVpcCloudInstanceId(model.getVpcCloudInstanceId());
                rds.setVolSize(model.getDbInstanceStorage());
                rds.setType(model.getInstanceType()); // 主备
                rds.setCategory(model.getCategory());
                rds.setCreatorId(userId);
                rds.setGmtCreate(new Date());
                rds.setVendorId(vendor.getId());
                rds.setVendorType(vendor.getType());
                rds.setFlavorId(model.getInstanceClass());
                rds.setVolSize(model.getDisk());
                // M转换GB
                if (null != model.getMemory()) {
                    rds.setMemory(model.getMemory().longValue() / 1024);
                }
                // 内网连接地址
                rds.setDnsName(model.getConnectionString());
                rds.setDbPort(model.getPort());
                rds.setVpcId(model.getVpcId());
                rds.setInstanceNetworkType(model.getNetworkType());
                rds.setCategory(model.getCategory());
                rds.setDbInstanceNetType(model.getNetType());
                rds.setMaxIops(model.getMaxIOPS());
                rds.setVpcCloudInstanceId(model.getVpcCloudInstanceId());
                rds.setPeriod(model.getPeriod());
                rds.setUsedTime(model.getUsedTime());
                rds.setResourceId(model.getResourceId());
                rds.setAutoRenew(model.getAutoRenew());
                rds.setParamGroupId(model.getDBParamGroupId());
                rds.setTimeZone(model.getDBTimeZone());
                rds.setIgnoreCase(model.getDBIsIgnoreCase());
                rdsPublicCloudInstanceRepository.save(rds);
                rdsMap.remove(model.getInstanceId());
            }
            // 同步实例下的用户
            BocloudResult users = syncUsers(model.getUserModels(), vendor.getId(), userId, rds.getId());
            if (users.isFailed()) {
                return;
            }
            // 同步实例下的数据库
            syncDbs(model.getDbModels(), vendor.getId(), userId, rds.getId());
        }
        for (Entry<String, RdsPublicCloudInstance> entry : rdsMap.entrySet()) {
            rdsPublicCloudInstanceRepository.delete(RdsPublicCloudInstance.class, entry.getValue().getId());
        }
    }

    private BocloudResult syncDbs(List<DbInstanceDbModel> dbModels, Long vendorId, Long userId, Long rdsId)
            throws Exception {
        if (ListTool.isEmpty(dbModels)) {
            rdsDbRepository.removeByVidAndRdsId(vendorId, userId, rdsId);
            return new BocloudResult(true, "同步实例数据库成功");
        }
        List<RdsDb> rdsDbList = rdsDbRepository.listByVidAndRdsId(vendorId, rdsId);
        Map<String, RdsDb> dbsMap = Maps.newHashMap();
        for (RdsDb db : rdsDbList) {
            dbsMap.put(db.getName(), db);
        }
        for (DbInstanceDbModel model : dbModels) {
            RdsDb rdsDb = new RdsDb();
            if (dbsMap.containsKey(model.getDBName())) {
                rdsDb = dbsMap.get(model.getDBName());
                rdsDb.setName(model.getDBName());
                rdsDb.setStatus(model.getDBStatus());
                rdsDb.setCharacterSet(model.getCharacterSetName());
                rdsDb.setRemark(model.getDBDescription());
                rdsDb.setEngine(model.getEngine());
                rdsDb.setAccounts(model.getAccounts().toJSONString());
                rdsDb.setMenderId(userId);
                rdsDb.setGmtModify(new Date());
                rdsDb.setVendorId(vendorId);
                rdsDb.setRdsId(rdsId);
                rdsDbRepository.update(rdsDb);
                dbsMap.remove(model.getDBName());
            } else {
                rdsDb.setName(model.getDBName());
                rdsDb.setStatus(model.getDBStatus());
                rdsDb.setCharacterSet(model.getCharacterSetName());
                rdsDb.setRemark(model.getDBDescription());
                rdsDb.setEngine(model.getEngine());
                rdsDb.setAccounts(model.getAccounts().toJSONString());
                rdsDb.setCreatorId(userId);
                rdsDb.setGmtCreate(new Date());
                rdsDb.setVendorId(vendorId);
                rdsDb.setRdsId(rdsId);
                rdsDbRepository.save(rdsDb);
                dbsMap.remove(model.getDBName());
            }
        }
        for (RdsDb value : dbsMap.values()) {
            rdsDbRepository.remove(value.getId(), userId);
        }
        return new BocloudResult(true, "同步实例下的数据库成功");
    }

    private BocloudResult syncUsers(List<DbInstanceUserModel> users, Long vendorId, Long userId, Long rdsId)
            throws Exception {
        if (ListTool.isEmpty(users)) {
            rdsUserRepository.removeByVidAndRdsId(vendorId, userId, rdsId);
            return new BocloudResult(true, "同步实例用户成功");
        }
        List<RdsUser> rdsUserList = rdsUserRepository.listByVidAndRdsId(vendorId, rdsId);
        Map<String, RdsUser> usersMap = Maps.newHashMap();
        for (RdsUser rdsUser : rdsUserList) {
            usersMap.put(rdsUser.getUsername(), rdsUser);
        }
        for (DbInstanceUserModel user : users) {
            RdsUser rdsUser = new RdsUser();
            if (usersMap.containsKey(user.getAccountName())) {
                rdsUser = usersMap.get(user.getAccountName());
                rdsUser.setUsername(user.getAccountName());
                rdsUser.setPermission(user.getAccountType());
                rdsUser.setStatus(user.getAccountStatus());
                rdsUser.setRemark(user.getAccountDescription());
                rdsUser.setRdsId(rdsId);
                rdsUser.setPrivileges(user.getDatabasePrivileges().toJSONString());
                rdsUser.setMenderId(userId);
                rdsUser.setGmtModify(new Date());
                rdsUser.setVendorId(vendorId);
                rdsUserRepository.update(rdsUser);
                usersMap.remove(user.getAccountName());
            } else {
                rdsUser.setUsername(user.getAccountName());
                rdsUser.setPermission(user.getAccountType());
                rdsUser.setStatus(user.getAccountStatus());
                rdsUser.setRemark(user.getAccountDescription());
                rdsUser.setVendorId(vendorId);
                rdsUser.setRdsId(rdsId);
                rdsUser.setPrivileges(user.getDatabasePrivileges().toJSONString());
                rdsUser.setCreatorId(userId);
                rdsUser.setGmtCreate(new Date());
                rdsUserRepository.save(rdsUser);
                usersMap.remove(user.getAccountName());
            }
        }
        for (RdsUser value : usersMap.values()) {
            rdsUserRepository.remove(value.getId(), userId);
        }
        return new BocloudResult(true, "同步实例下用户成功");
    }

    private void syncAcls(List<AccessControlModel> acls, Long vendorId, Long userId, String regionId) throws Exception {
        if (null == acls) {
            return;
        }
        if (ListTool.isEmpty(acls)) {
            accessControlRepository.removeByVid(vendorId, userId, regionId);
            return;
        }
        List<AccessControl> aclsList = accessControlRepository.listByVid(vendorId, regionId);
        Map<String, AccessControl> accessControlMap = Maps.newHashMap();
        for (AccessControl acl : aclsList) {
            accessControlMap.put(acl.getAclUuId(), acl);
        }
        for (AccessControlModel model : acls) {
            AccessControl accessControl = new AccessControl();
            // 获取资源组数据
            ResourceGroup resourceGroup = resourceGroupRepository.getByUuid(model.getResourceGroupUuid(), vendorId);
            if (accessControlMap.containsKey(model.getAclUuId())) {
                accessControl = accessControlMap.get(model.getAclUuId());
                BeanUtils.copyProperties(model, accessControl);
                accessControl.setVendorId(vendorId);
                accessControl.setRegionId(regionId);
                accessControl.setGmtModify(new Date());
                accessControl.setMenderId(userId);
                if (null != resourceGroup) {
                    accessControl.setResourceGroupId(resourceGroup.getId());
                }
                accessControl.setListeners(null != model.getListenerModels() ? model.getListenerModels().toJSONString()
                        : new JSONArray().toJSONString());
                accessControlRepository.update(accessControl);
                accessControlMap.remove(model.getAclUuId());
            } else {
                BeanUtils.copyProperties(model, accessControl);
                accessControl.setCreatorId(userId);
                accessControl.setVendorId(vendorId);
                accessControl.setGmtCreate(new Date());
                accessControl.setRegionId(regionId);
                if (null != resourceGroup) {
                    accessControl.setResourceGroupId(resourceGroup.getId());
                }
                accessControl.setListeners(null != model.getListenerModels() ? model.getListenerModels().toJSONString()
                        : new JSONArray().toJSONString());
                accessControlRepository.save(accessControl);
                accessControlMap.remove(model.getAclUuId());
            }
        }
        for (AccessControl acl : accessControlMap.values()) {
            accessControlRepository.remove(acl.getId(), userId);
        }
    }

    private void syncMembers(List<LbMemberModel> memberModels, Long vendorId, Long userId, String regionId)
            throws Exception {
        if (null == memberModels) {
            return;
        }
        if (ListTool.isEmpty(memberModels)) {
            lbMemberRepository.removeByVid(vendorId, userId, regionId);
            return;
        }
        List<LbMember> members = lbMemberRepository.listByVid(vendorId, regionId);
        Map<String, LbMember> memberMap = Maps.newHashMap();
        for (LbMember member : members) {
        	String key = member.getMemberUuid() + member.getPoolUuid() + member.getPort();
            memberMap.put(key, member);
            if(memberMap.containsKey(key)) {
            	lbMemberRepository.remove(member.getId(), userId);
            } else {
            	memberMap.put(key, member);
            }
        }
        for (LbMemberModel model : memberModels) {
            LbMember member = new LbMember();
            // 根据pooluuid获取pool的id
            LbPool pool = lbPoolRepository.queryByUuid(model.getPoolUuid(), vendorId);
            // 获取云主机信息
            CloudServer cloudServer = cloudServerRepository.get(model.getMemberUuid());
            String key = member.getMemberUuid() + member.getPoolUuid() + member.getPort();
            if (memberMap.containsKey(key)) {
                member = memberMap.get(key);
                BeanUtils.copyProperties(model, member);
                if(null != cloudServer) {
                	member.setName(cloudServer.getName());
                    member.setSubnetUuid(cloudServer.getSubnetUuid());
                    member.setAddress(cloudServer.getPrivateIps());
                }
                member.setPoolId(pool.getId());
                member.setVendorId(vendorId);
                member.setRegionId(regionId);
                member.setGmtModify(new Date());
                lbMemberRepository.update(member);
                memberMap.remove(key);
            } else {
                BeanUtils.copyProperties(model, member);
                if(null != cloudServer) {
                	member.setName(cloudServer.getName());
                    member.setSubnetUuid(cloudServer.getSubnetUuid());
                    member.setAddress(cloudServer.getPrivateIps());
                }
                member.setPoolId(pool.getId());
                member.setCreatorId(userId);
                member.setVendorId(vendorId);
                member.setGmtCreate(new Date());
                member.setRegionId(regionId);
                lbMemberRepository.save(member);
                memberMap.remove(key);
            }
        }
        for (LbMember member : memberMap.values()) {
            lbMemberRepository.remove(member.getId(), userId);
        }
    }

    private void syncPools(List<LbPoolModel> poolModels, Long vendorId, Long userId, String regionId) throws Exception {
        if (null == poolModels) {
            return;
        }
        if (ListTool.isEmpty(poolModels)) {
            lbPoolRepository.removeByVid(vendorId, userId, regionId);
            return;
        }
        List<LbPool> lbPools = lbPoolRepository.listByVid(vendorId, regionId);
        Map<String, LbPool> poolMap = Maps.newHashMap();
        for (LbPool pool : lbPools) {
            poolMap.put(pool.getPoolUuid(), pool);
        }
        for (LbPoolModel model : poolModels) {
            // 查询lb数据
            LoadBalancer loadBalancer = loadBalancerRepository.queryByUuid(model.getLbId());
            LbPool lbPool = new LbPool();
            if (poolMap.containsKey(model.getPoolUuid())) {
                lbPool = poolMap.get(model.getPoolUuid());
                BeanUtils.copyProperties(model, lbPool);
                lbPool.setVendorId(vendorId);
                lbPool.setRegionId(regionId);
                lbPool.setGmtModify(new Date());
                lbPool.setMenderId(userId);
                lbPool.setLbId(loadBalancer.getId());
                lbPool.setLbUuid(loadBalancer.getLbUuid());
                lbPoolRepository.update(lbPool);
                poolMap.remove(model.getPoolUuid());
            } else {
                BeanUtils.copyProperties(model, lbPool);
                lbPool.setCreatorId(userId);
                lbPool.setVendorId(vendorId);
                lbPool.setGmtCreate(new Date());
                lbPool.setRegionId(regionId);
                lbPool.setLbId(loadBalancer.getId());
                lbPool.setLbUuid(loadBalancer.getLbUuid());
                lbPoolRepository.save(lbPool);
                poolMap.remove(model.getPoolUuid());
            }
        }
        for (LbPool lbPool : poolMap.values()) {
            lbPoolRepository.remove(lbPool.getId(), userId);
        }
    }

    private void syncListeners(List<LbListenerModel> models, Long vendorId, Long userId, String regionId)
            throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            lbListenerRepository.removeByVid(vendorId, userId, regionId);
            return;
        }
        List<LbListener> listeners = lbListenerRepository.listByVid(vendorId, regionId);
        Map<String, LbListener> listenerMap = Maps.newHashMap();
        for (LbListener listener : listeners) {
            listenerMap.put(listener.getListenerUuid(), listener);
        }
        for (LbListenerModel model : models) {
            LbListener listener = new LbListener();
            listener.setConfiguration(JSONObject.parseObject(JSONObject.toJSONString(model)));
            // 查询负载均衡id
            LoadBalancer loadBalancer = loadBalancerRepository.queryByUuid(model.getLbUuid());
            //设置会话保持按钮状态
            if(null!=model.getPersistenceTimeout()){
                model.setStickySession(model.getPersistenceTimeout() > 0 );
            }
            listener.setLbId(loadBalancer.getId());
            if (listenerMap.containsKey(model.getListenerUuid())) {
                listener = listenerMap.get(model.getListenerUuid());
                BeanUtils.copyProperties(model, listener);
                listener.setVendorId(vendorId);
                listener.setRegionId(regionId);
                listener.setGmtModify(new Date());
                listener.setMenderId(userId);
                listener.setCertificates(JSONObject.parseObject(JSONObject.toJSONString(model)));
                lbListenerRepository.update(listener);
                listenerMap.remove(model.getListenerUuid());
            } else {
                BeanUtils.copyProperties(model, listener);
                listener.setListenerUuid(model.getListenerUuid());
                listener.setCreatorId(userId);
                listener.setVendorId(vendorId);
                listener.setGmtCreate(new Date());
                listener.setRegionId(regionId);
                listener.setCertificates(JSONObject.parseObject(JSONObject.toJSONString(model)));
                lbListenerRepository.save(listener);
                listenerMap.remove(model.getListenerUuid());
            }
        }
        for (LbListener value : listenerMap.values()) {
            lbListenerRepository.remove(value.getId(), userId);
        }
    }

    private void syncLb(List<LbModel> models, Long vendorId, Long userId, String region, Map<String, Vpc> vpcMap,
                        Map<String, Subnet> subnetMap) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            loadBalancerRepository.removeByVid(vendorId, region, userId);
            tagRepository.removeByRes(vendorId, region, null, TagType.SLB.name());
            return;
        }
        List<LoadBalancer> loadBalancers = loadBalancerRepository.listByVid(vendorId, region);
        Map<String, LoadBalancer> lbMap = Maps.newHashMap();
        for (LoadBalancer loadBalancer : loadBalancers) {
            lbMap.put(loadBalancer.getLbUuid(), loadBalancer);
        }
        for (LbModel model : models) {
            // 获取资源组数据
            LoadBalancer loadBalancer = new LoadBalancer();
            ResourceGroup resourceGroup = resourceGroupRepository.getByUuid(model.getResourceGroupUuid(), vendorId);
            if (null != resourceGroup) {
                loadBalancer.setResourceGroupId(resourceGroup.getId());
            }
            if (lbMap.containsKey(model.getLbUuid())) {
                loadBalancer = lbMap.get(model.getLbUuid());
                BeanUtils.copyProperties(model, loadBalancer);
                // 关联vpc
                if (!StringUtils.isEmpty(model.getVpcUuid())) {
                    loadBalancer.setVpcId(Optional.ofNullable(model.getVpcUuid())
                            .map(vpcUuid -> vpcMap.get(vpcUuid).getId()).orElse(null));
                }
                if (!StringUtils.isEmpty(model.getSubnetUuid())) {
                    loadBalancer.setSubnetId(Optional.ofNullable(model.getSubnetUuid())
                            .map(subnetUuid -> subnetMap.get(subnetUuid).getId()).orElse(null));
                }
                loadBalancer.setAvailabilityZones(model.getAvailabilityZones().toJSONString());
                loadBalancer.setMenderId(userId);
                loadBalancer.setVendorId(vendorId);
                loadBalancer.setGmtModify(new Date());
                loadBalancer.setRegion(region);
                loadBalancerRepository.update(loadBalancer);
                lbMap.remove(loadBalancer.getLbUuid());
            } else {
                BeanUtils.copyProperties(model, loadBalancer);
                if (!StringUtils.isEmpty(model.getVpcUuid())) {
                    loadBalancer.setVpcId(Optional.ofNullable(model.getVpcUuid())
                            .map(vpcUuid -> vpcMap.get(vpcUuid).getId()).orElse(null));
                }
                if (!StringUtils.isEmpty(model.getSubnetUuid())) {
                    loadBalancer.setSubnetId(Optional.ofNullable(model.getSubnetUuid())
                            .map(subnetUuid -> subnetMap.get(subnetUuid).getId()).orElse(null));
                }
                loadBalancer.setAvailabilityZones(model.getAvailabilityZones().toJSONString());
                loadBalancer.setCreatorId(userId);
                loadBalancer.setVendorId(vendorId);
                loadBalancer.setGmtCreate(new Date());
                loadBalancer.setRegion(region);
                loadBalancerRepository.save(loadBalancer);
                lbMap.remove(loadBalancer.getLbUuid());
            }
            syncTag(model.getTagModels(), model.getLbUuid(), TagType.SLB.name(), vendorId, region);
        }
        for (Map.Entry<String, LoadBalancer> entry : lbMap.entrySet()) {
            loadBalancerRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendorId, region, entry.getValue().getLbUuid(), TagType.SLB.name());
        }
    }

    private void syncNatGateWay(List<NatGatewayModel> models, Long vendorId, Long userId, String region,
                                Map<String, Vpc> vpcMap, Map<String, Subnet> subnetMap) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            natGatewayRepository.removeByVid(vendorId, region, userId);
            natGatewayDnatRuleRepository.removeByVid(vendorId, region, userId);
            natGatewaySnatRuleRepository.removeByVid(vendorId, region, userId);
            return;
        }
        List<NatGateway> gateways = natGatewayRepository.listByVendorId(vendorId, region);
        Map<String, NatGateway> gatewayMap = Maps.newHashMap();
        for (NatGateway gateway : gateways) {
            gatewayMap.put(gateway.getUuid(), gateway);
        }

        Map<String, Long> subnetCidrMap = new HashMap<>();
        List<Subnet> subnets = subnetRepository.listByRegion(vendorId, region);
        for (Subnet subnet : subnets) {
            subnetCidrMap.put(subnet.getCidr(), subnet.getId());
        }

        Map<String, Long> serverCidrMap = new HashMap<>();
        List<CloudServer> servers = cloudServerRepository.listByVid(vendorId, region);
        for (CloudServer server : servers) {
            String privateIps = server.getPrivateIps();
            if (StringUtils.isEmpty(privateIps)) {
                continue;
            }
            List<String> ipList = JSONArray.parseArray(privateIps, String.class);
            for (String ip : ipList) {
                serverCidrMap.put(ip + "/32", server.getId());
            }
        }

        for (NatGatewayModel model : models) {
            NatGateway gateway = new NatGateway();
            if (gatewayMap.containsKey(model.getUuid())) {
                gateway = gatewayMap.get(model.getUuid());
                BeanUtils.copyProperties(model, gateway);
                if (!StringUtils.isEmpty(model.getVpcUuid()) && null != vpcMap.get(model.getVpcUuid())) {
                    gateway.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
                }
                if (!StringUtils.isEmpty(model.getSubnetUuid()) && null != subnetMap.get(model.getSubnetUuid())) {
                    gateway.setSubnetId(subnetMap.get(model.getSubnetUuid()).getId());
                }
                gateway.setMenderId(userId);
                gateway.setVendorId(vendorId);
                gateway.setGmtModify(new Date());
                gateway.setRegionId(region);
                natGatewayRepository.update(gateway);
                gatewayMap.remove(gateway.getUuid());
            } else {
                BeanUtils.copyProperties(model, gateway);
                if (!StringUtils.isEmpty(model.getVpcUuid()) && null != vpcMap.get(model.getVpcUuid())) {
                    gateway.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
                }
                if (!StringUtils.isEmpty(model.getSubnetUuid()) && null != subnetMap.get(model.getSubnetUuid())) {
                    gateway.setSubnetId(subnetMap.get(model.getSubnetUuid()).getId());
                }
                gateway.setCreatorId(userId);
                gateway.setVendorId(vendorId);
                gateway.setGmtCreate(new Date());
                gateway.setRegionId(region);
                natGatewayRepository.save(gateway);
            }

            // 同步dnat规则
            syncDnatRule(model.getDnatRules(), vendorId, userId, region, gateway.getId());
            // 同步snat规则
            syncSnatRule(model.getSnatRules(), vendorId, userId, region, gateway.getId(), subnetCidrMap, serverCidrMap);
            // //同步弹性网卡信息
            // if(StringUtils.isNotBlank(model.getEniInstanceId())){
            // networkInterfaceRepository.updateForNatGateway(vendorId,region,model.getUuid(),model.getEniInstanceId());
            // }
        }
        for (Map.Entry<String, NatGateway> entry : gatewayMap.entrySet()) {
            natGatewayRepository.delete(entry.getValue().getId(), userId);
            if (StringUtils.isNotBlank(entry.getValue().getForwardTableIds())) {
                natGatewayDnatRuleRepository.remove(vendorId, region, userId,
                        Arrays.asList(entry.getValue().getForwardTableIds().split(",")));
            }
            if (StringUtils.isNotBlank(entry.getValue().getSnatTableIds())) {
                natGatewaySnatRuleRepository.remove(vendorId, region, userId,
                        Arrays.asList(entry.getValue().getSnatTableIds().split(",")));
            }
        }
    }

    /**
     * 同步dnat规则
     *
     * @param models
     * @param vendorId
     * @param userId
     * @param region
     * @throws Exception
     */
    private void syncDnatRule(List<NatGatewayDnatRuleModel> models, Long vendorId, Long userId, String region,
                              Long natGatewayId) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            natGatewayDnatRuleRepository.removeByVid(vendorId, region, userId, natGatewayId);
            return;
        }
        List<NatGatewayDnatRule> dnatRules = natGatewayDnatRuleRepository.listByNatGatewayId(natGatewayId);
        Map<String, NatGatewayDnatRule> dnatRuleMap = Maps.newHashMap();
        for (NatGatewayDnatRule dnatRule : dnatRules) {
            dnatRuleMap.put(dnatRule.getUuid(), dnatRule);
        }
        for (NatGatewayDnatRuleModel model : models) {
            NatGatewayDnatRule dnatRule = new NatGatewayDnatRule();
            if (dnatRuleMap.containsKey(model.getUuid())) {
                dnatRule = dnatRuleMap.get(model.getUuid());
                BeanUtils.copyProperties(model, dnatRule);
                dnatRule.setMenderId(userId);
                dnatRule.setVendorId(vendorId);
                dnatRule.setGmtModify(new Date());
                dnatRule.setRegionId(region);
                dnatRule.setNatGatewayId(natGatewayId);
                natGatewayDnatRuleRepository.update(dnatRule);
                dnatRuleMap.remove(dnatRule.getUuid());
            } else {
                BeanUtils.copyProperties(model, dnatRule);
                dnatRule.setCreatorId(userId);
                dnatRule.setVendorId(vendorId);
                dnatRule.setGmtCreate(new Date());
                dnatRule.setRegionId(region);
                dnatRule.setNatGatewayId(natGatewayId);
                natGatewayDnatRuleRepository.save(dnatRule);
            }
        }
        for (Map.Entry<String, NatGatewayDnatRule> entry : dnatRuleMap.entrySet()) {
            natGatewayDnatRuleRepository.delete(entry.getValue().getId(), userId);
        }
    }

    /**
     * 同步Snat规则
     *
     * @param models
     */
    private void syncSnatRule(List<NatGatewaySnatRuleModel> models, Long vendorId, Long userId, String region,
                              Long natGatewayId, Map<String, Long> subnetCidrMap, Map<String, Long> serverCidrMap) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            natGatewaySnatRuleRepository.removeByVid(vendorId, region, userId, natGatewayId);
            return;
        }
        List<NatGatewaySnatRule> snatRules = natGatewaySnatRuleRepository.listByNatGatewayId(natGatewayId);
        Map<String, NatGatewaySnatRule> snatRuleMap = Maps.newHashMap();
        for (NatGatewaySnatRule snatRule : snatRules) {
            snatRuleMap.put(snatRule.getUuid(), snatRule);
        }
        for (NatGatewaySnatRuleModel model : models) {
            NatGatewaySnatRule snatRule = new NatGatewaySnatRule();
            Long subnetId = subnetCidrMap.get(model.getCidr());
            Long serverId = serverCidrMap.get(model.getCidr());

            if (snatRuleMap.containsKey(model.getUuid())) {
                snatRule = snatRuleMap.get(model.getUuid());
                BeanUtils.copyProperties(model, snatRule);
                snatRule.setMenderId(userId);
                snatRule.setVendorId(vendorId);
                snatRule.setGmtModify(new Date());
                snatRule.setRegionId(region);
                snatRule.setNatGatewayId(natGatewayId);
                snatRule.setSubnetId(subnetId);
                snatRule.setEcsId(serverId);
                snatRule.setSnatIp(model.getFloatingIpAddress());
                natGatewaySnatRuleRepository.update(snatRule);
                snatRuleMap.remove(snatRule.getUuid());
                continue;
            } else {
                BeanUtils.copyProperties(model, snatRule);
                snatRule.setCreatorId(userId);
                snatRule.setVendorId(vendorId);
                snatRule.setGmtCreate(new Date());
                snatRule.setNatGatewayId(natGatewayId);
                snatRule.setRegionId(region);
                snatRule.setSubnetId(subnetId);
                snatRule.setEcsId(serverId);
                snatRule.setSnatIp(model.getFloatingIpAddress());
                natGatewaySnatRuleRepository.save(snatRule);
            }
        }
        for (Map.Entry<String, NatGatewaySnatRule> entry : snatRuleMap.entrySet()) {
            natGatewayDnatRuleRepository.delete(entry.getValue().getId(), userId);
        }
    }

    private void syncElasticIp(List<ElasticIpModel> models, Long vendorId, Long userId, String region)
            throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            elasticIpRepository.removeByVid(vendorId, userId, region);
            tagRepository.removeByRes(vendorId, region, null, TagType.EIP.name());
            return;
        }
        List<ElasticIp> elasticIps = elasticIpRepository.listByVid(vendorId, region);
        Map<String, ElasticIp> elasticIpMap = Maps.newHashMap();
        for (ElasticIp elasticIp : elasticIps) {
            elasticIpMap.put(elasticIp.getElasticIpUuid(), elasticIp);
        }
        for (ElasticIpModel model : models) {
            ElasticIp elasticIp = new ElasticIp();
            if (elasticIpMap.containsKey(model.getElasticIpUuid())) {
                elasticIp = elasticIpMap.get(model.getElasticIpUuid());
                BeanUtils.copyProperties(model, elasticIp);
                elasticIp.setVendorId(vendorId);
                elasticIp.setGmtModify(new Date());
                elasticIp.setRegionId(region);
                elasticIpRepository.update(elasticIp);
                elasticIpMap.remove(elasticIp.getElasticIpUuid());
            } else {
                BeanUtils.copyProperties(model, elasticIp);
                elasticIp.setCreatorId(userId);
                elasticIp.setVendorId(vendorId);
                elasticIp.setGmtCreate(new Date());
                elasticIp.setRegionId(region);
                elasticIpRepository.save(elasticIp);
                elasticIpMap.remove(model.getElasticIpUuid());
            }
            syncTag(model.getTagModels(), model.getElasticIpUuid(), TagType.EIP.name(), vendorId, region);
        }
        for (Map.Entry<String, ElasticIp> entry : elasticIpMap.entrySet()) {
            elasticIpRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendorId, region, entry.getValue().getElasticIpUuid(), TagType.EIP.name());
        }
    }

    private void syncRouter(List<RouterModel> models, Long vendorId, Long userId, Map<String, Vpc> vpcMap,
                            String region) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            routerRepository.removeByVid(vendorId, region, userId);
            return;
        }
        List<Router> routers = routerRepository.listByVid(vendorId, region);
        Map<String, Router> routerMap = Maps.newHashMap();
        routers.forEach((Router router) -> {
            routerMap.put(router.getRouterUuid(), router);
        });
        for (RouterModel model : models) {
            Router router = new Router();
            if (routerMap.containsKey(model.getRouterUuid())) {
                router = routerMap.get(model.getRouterUuid());
                BeanUtils.copyProperties(model, router);
                // 关联vpc
                if (!StringUtils.isEmpty(model.getVpcUuid()) && null != vpcMap.get(model.getVpcUuid())) {
                    router.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
                }
                router.setMenderId(userId);
                router.setGmtModify(new Date());
                router.setVendorId(vendorId);
                router.setRegionId(region);
                router.setRouteTableIds(JSON.toJSONString(model.getRouteTableIds()));
                routerRepository.update(router);
                routerMap.remove(model.getRouterUuid());
                continue;
            }
            BeanUtils.copyProperties(model, router);
            // 关联vpc
            if (!StringUtils.isEmpty(model.getVpcUuid()) && null != vpcMap.get(model.getVpcUuid())) {
                router.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
            }
            router.setCreatorId(userId);
            router.setGmtCreate(new Date());
            router.setVendorId(vendorId);
            router.setRegionId(region);
            router.setRouteTableIds(JSON.toJSONString(model.getRouteTableIds()));
            routerRepository.save(router);
            routerMap.remove(model.getRouterUuid());
        }
        for (Map.Entry<String, Router> entry : routerMap.entrySet()) {
            routerRepository.remove(entry.getValue().getId(), userId);
        }
    }

    private void syncRouteTable(List<RouteTableModel> models, Long vendorId, Long userId, Map<String, Vpc> vpcMap,
                                String region, Map<String, Subnet> subnetMap) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            routeTableRepository.removeByVid(vendorId, region, userId);
            routeRepository.removeByVid(vendorId, region, userId);
            tagRepository.removeByRes(vendorId, region, null, TagType.ROUTETABLE.name());
            return;
        }
        List<RouteTable> routeTables = routeTableRepository.listByVid(vendorId, region);
        Map<String, RouteTable> routeTableMap = Maps.newHashMap();
        routeTables.forEach((RouteTable routeTable) -> {
            routeTableMap.put(routeTable.getUuid(), routeTable);
        });
        for (RouteTableModel model : models) {
            RouteTable routeTable = new RouteTable();
            if (routeTableMap.containsKey(model.getUuid())) {
                routeTable = routeTableMap.get(model.getUuid());
                BeanUtils.copyProperties(model, routeTable);
                // 关联vpc
                if (!StringUtils.isEmpty(model.getVpcUuid()) && null != vpcMap.get(model.getVpcUuid())) {
                    routeTable.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
                }
                routeTable.setMenderId(userId);
                routeTable.setGmtModify(new Date());
                routeTable.setVendorId(vendorId);
                routeTable.setRegionId(region);
                routeTableRepository.update(routeTable);
                List<String> subnetlds = model.getSubnetlds();
                if (!ListTool.isEmpty(subnetlds)) {
                    subnetlds.forEach(subnetId -> {
                        Subnet subnet = subnetMap.get(subnetId);
                        if (null != subnet) {
                            subnet.setRouteTableId(model.getUuid());
                            subnetRepository.update(subnet);
                        }
                    });
                }
                routeTableMap.remove(model.getUuid());
            } else {
                BeanUtils.copyProperties(model, routeTable);
                // 关联vpc
                if (!StringUtils.isEmpty(model.getVpcUuid()) && null != vpcMap.get(model.getVpcUuid())) {
                    routeTable.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
                }
                routeTable.setCreatorId(userId);
                routeTable.setGmtCreate(new Date());
                routeTable.setVendorId(vendorId);
                routeTable.setRegionId(region);
                routeTableRepository.save(routeTable);
                List<String> subnetlds = model.getSubnetlds();
                if (!ListTool.isEmpty(subnetlds)) {
                    subnetlds.forEach(subnetId -> {
                        Subnet subnet = subnetMap.get(subnetId);
                        if (null != subnet) {
                            subnet.setRouteTableId(model.getUuid());
                            subnetRepository.update(subnet);
                        }
                    });
                }
                routeTableMap.remove(model.getUuid());
            }
            syncRouteEntry(model.getRouteModels(), routeTable.getId(), vendorId, userId, region);
            syncTag(model.getTagModels(), model.getUuid(), TagType.ROUTETABLE.name(), vendorId, region);
        }
        for (Map.Entry<String, RouteTable> entry : routeTableMap.entrySet()) {
            routeTableRepository.remove(entry.getValue().getId(), userId);
            routeRepository.removeByVid(vendorId, region, userId, entry.getValue().getId());
            tagRepository.removeByRes(vendorId, region, entry.getValue().getUuid(), TagType.ROUTETABLE.name());
        }
    }

    private void syncRouteEntry(List<RouteModel> models, Long routeTableId, Long vendorId, Long userId, String region)
            throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            routeRepository.removeByVid(vendorId, region, userId, routeTableId);
            return;
        }
        List<Route> routes = routeRepository.listByVid(vendorId, region, routeTableId);
        Map<String, Route> routeMap = Maps.newHashMap();
        routes.forEach((Route route) -> {
            routeMap.put(route.getUuid() + route.getName() + route.getDestination() + route.getType(), route);
        });
        for (RouteModel model : models) {
            Route route = new Route();
            String key = model.getUuid() + model.getName() + model.getDestination() + model.getType();
            if (routeMap.containsKey(key)) {
                route = routeMap.get(key);
                BeanUtils.copyProperties(model, route);
                route.setRouteTableId(routeTableId);
                route.setMenderId(userId);
                route.setGmtModify(new Date());
                route.setVendorId(vendorId);
                route.setRegionId(region);
                routeRepository.update(route);
                routeMap.remove(key);
            } else {
                BeanUtils.copyProperties(model, route);
                route.setRouteTableId(routeTableId);
                route.setCreatorId(userId);
                route.setGmtCreate(new Date());
                route.setVendorId(vendorId);
                route.setRegionId(region);
                routeRepository.save(route);
                routeMap.remove(key);
            }
        }
        for (Map.Entry<String, Route> entry : routeMap.entrySet()) {
            routeRepository.remove(entry.getValue().getId(), userId);
        }
    }

    private void syncNetworkInterface(List<NetworkInterfaceModel> models, Long vendorId, Long userId,
                                      Map<String, Long> groupMap, Map<String, Vpc> vpcMap, Map<String, Long> serverMap, String region,
                                      Map<String, Subnet> subnetMap) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            networkInterfaceRepository.removeByVid(vendorId, userId, region);
            tagRepository.removeByRes(vendorId, region, null, TagType.eni.name());
            return;
        }
        List<NetworkInterface> networkInterfaces = networkInterfaceRepository.listByVendorId(vendorId, region);
        Map<String, NetworkInterface> networkInterfaceMap = Maps.newHashMap();
        networkInterfaces.forEach((NetworkInterface networkInterface) -> {
            networkInterfaceMap.put(networkInterface.getNetworkInterfaceUuid(), networkInterface);
        });
        for (NetworkInterfaceModel model : models) {
            NetworkInterface networkInterface = new NetworkInterface();
            if (networkInterfaceMap.containsKey(model.getNetworkInterfaceUuid())) {
                networkInterface = networkInterfaceMap.get(model.getNetworkInterfaceUuid());
                BeanUtils.copyProperties(model, networkInterface);
                // 关联安全组
                networkInterface.setSgroupUuid(
                        Optional.ofNullable(model.getSecurityGroups()).map(JSON::toJSONString).orElse(null));
                // 关联vpc
                networkInterface.setVpcId(
                        Optional.ofNullable(model.getNetworkUuid()).map(vpcMap::get).map(Vpc::getId).orElse(null));
                // 关联云主机
                networkInterface
                        .setServerId(Optional.ofNullable(model.getInstanceId()).map(serverMap::get).orElse(null));
                // 关联子网
                networkInterface.setSubnetId(
                        Optional.ofNullable(model.getSubnetUuid()).map(subnetMap::get).map(Subnet::getId).orElse(null));
                networkInterface.setSubnetName(Optional.ofNullable(model.getSubnetUuid()).map(subnetMap::get)
                        .map(Subnet::getName).orElse(null));
                networkInterface.setMenderId(userId);
                networkInterface.setGmtModify(new Date());
                networkInterface.setVendorId(vendorId);
                networkInterface.setRegionId(region);
                networkInterface.setPrivateIPAddress(JSON.toJSONString(model.getPrivateIpAddress()));
                networkInterfaceRepository.update(networkInterface);
                networkInterfaceMap.remove(model.getNetworkInterfaceUuid());
            } else {
                BeanUtils.copyProperties(model, networkInterface);
                // 关联安全组
                networkInterface.setSgroupUuid(
                        Optional.ofNullable(model.getSecurityGroups()).map(JSON::toJSONString).orElse(null));
                // 关联vpc
                networkInterface.setVpcId(
                        Optional.ofNullable(model.getNetworkUuid()).map(vpcMap::get).map(Vpc::getId).orElse(null));
                ;
                // 关联云主机
                networkInterface
                        .setServerId(Optional.ofNullable(model.getInstanceId()).map(serverMap::get).orElse(null));
                // 关联子网
                networkInterface.setSubnetId(
                        Optional.ofNullable(model.getSubnetUuid()).map(subnetMap::get).map(Subnet::getId).orElse(null));
                networkInterface.setSubnetName(Optional.ofNullable(model.getSubnetUuid()).map(subnetMap::get)
                        .map(Subnet::getName).orElse(null));
                networkInterface.setCreatorId(userId);
                networkInterface.setGmtCreate(new Date());
                networkInterface.setVendorId(vendorId);
                networkInterface.setRegionId(region);
                networkInterface.setPrivateIPAddress(JSON.toJSONString(model.getPrivateIpAddress()));
                networkInterfaceRepository.save(networkInterface);
                networkInterfaceMap.remove(model.getNetworkInterfaceUuid());
            }
            syncTag(model.getTagModels(), model.getNetworkInterfaceUuid(), TagType.eni.name(), vendorId, region);
        }
        for (Map.Entry<String, NetworkInterface> entry : networkInterfaceMap.entrySet()) {
            networkInterfaceRepository.delete(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendorId, region, entry.getValue().getNetworkInterfaceUuid(), TagType.eni.name());
        }
    }

    private void syncResourceGroups(List<ResourceGroupModel> resourceGroupModels, CloudVendor vendor, Long userId,
                                    Region region) throws Exception {
        if (null == resourceGroupModels) {
            return;
        }
        if (ListTool.isEmpty(resourceGroupModels)) {
            resourceGroupRepository.removeByVid(vendor.getId(), userId);
            return;
        }
        List<ResourceGroup> listResourceGroups = resourceGroupRepository.listByVendorId(vendor.getId());
        Map<String, ResourceGroup> resourceGroupMap = Maps.newHashMap();
        for (ResourceGroup resourceGroup : listResourceGroups) {
            resourceGroupMap.put(resourceGroup.getResourceGroupUuid(), resourceGroup);
        }
        for (ResourceGroupModel model : resourceGroupModels) {
            ResourceGroup resourceGroup = new ResourceGroup();
            String resourceGroupUuid = model.getResourceGroupUuid();
            if (resourceGroupMap.containsKey(resourceGroupUuid)) {
                resourceGroup = resourceGroupMap.get(resourceGroupUuid);
                BeanUtils.copyProperties(model, resourceGroup);
                resourceGroup.setMenderId(userId);
                resourceGroup.setGmtModify(new Date());
                resourceGroup.setVendorId(vendor.getId());
                resourceGroup.setRegionId(region.getRegionId());
                resourceGroupRepository.update(resourceGroup);
                resourceGroupMap.remove(resourceGroupUuid);
                continue;
            }
            BeanUtils.copyProperties(model, resourceGroup);
            resourceGroup.setCreatorId(userId);
            resourceGroup.setGmtCreate(new Date());
            resourceGroup.setRegionId(region.getRegionId());
            resourceGroup.setVendorId(vendor.getId());
            resourceGroupRepository.save(resourceGroup);
        }
        for (Entry<String, ResourceGroup> entry : resourceGroupMap.entrySet()) {
            resourceGroupRepository.remove(entry.getValue().getId(), userId);
        }

    }

    private void syncSubnets(List<SubnetModel> subnetModels, Long vendorId, Long userId, Region region,
                             Map<String, Vpc> vpcMap) throws Exception {
        if (null == subnetModels) {
            return;
        }
        if (ListTool.isEmpty(subnetModels)) {
            subnetRepository.removeByVid(vendorId, region.getRegionId(), userId);
            tagRepository.removeByRes(vendorId, region.getRegionId(), null, TagType.VSWITCH.name());
            return;
        }
        List<Subnet> listByRegion = subnetRepository.listByRegion(vendorId, region.getRegionId());
        Map<String, Subnet> subnetMap = Maps.newHashMap();
        for (Subnet subnet : listByRegion) {
            subnetMap.put(subnet.getSubnetUuid(), subnet);
        }
        for (SubnetModel model : subnetModels) {
            Subnet subnet = new Subnet();
            if (subnetMap.containsKey(model.getSubnetUuid())) {
                subnet = subnetMap.get(model.getSubnetUuid());
                BeanUtils.copyProperties(model, subnet);
                if (vpcMap.containsKey(subnet.getVpcUuid())) {
                    subnet.setVpcId(vpcMap.get(subnet.getVpcUuid()).getId());
                    subnet.setNetworkId(vpcMap.get(subnet.getVpcUuid()).getId());
                }
                subnet.setMenderId(userId);
                subnet.setGmtModify(new Date());
                subnet.setVendorId(vendorId);
                subnet.setRegionId(region.getRegionId());
                subnetRepository.update(subnet);
                subnetMap.remove(model.getSubnetUuid());
            } else {
                BeanUtils.copyProperties(model, subnet);
                if (vpcMap.containsKey(subnet.getVpcUuid())) {
                    subnet.setVpcId(vpcMap.get(subnet.getVpcUuid()).getId());
                    subnet.setNetworkId(vpcMap.get(subnet.getVpcUuid()).getId());
                }
                subnet.setCreatorId(userId);
                subnet.setGmtCreate(new Date());
                subnet.setVendorId(vendorId);
                subnet.setRegionId(region.getRegionId());
                subnetRepository.save(subnet);
                vpcMap.remove(model.getSubnetUuid());
            }
            syncTag(model.getTagModels(), model.getSubnetUuid(), TagType.VSWITCH.name(), vendorId,
                    region.getRegionId());
            syncCidr(model.getCidrBlockModels(), vendorId, userId, region.getRegionId(), subnet.getSubnetUuid());
        }
        for (Entry<String, Subnet> entry : subnetMap.entrySet()) {
            subnetRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendorId, region.getRegionId(), entry.getValue().getSubnetUuid(),
                    TagType.VSWITCH.name());
        }
    }

    /**
     * 同步云主机
     *
     * @param models
     * @param vendor
     * @param userId
     * @param groupMap
     * @param infos
     * @throws Exception
     */
    private void syncServer(List<ServerModel> models, CloudVendor vendor, Long userId, Map<String, Long> groupMap,
                            Region region, Map<String, Image> imageMap, Map<String, Long> keyPairMap, List<CmdbInfo> infos)
            throws Exception {
        if (null == models) {
            return;
        }
        if (null != groupMap && groupMap.keySet().size() > 0) {
            for (String key : groupMap.keySet()) {
                serverSgroupRepository.removeBySgid(groupMap.get(key));
            }
        }
        // 删除 云主机 秘钥关联关系
        List<CloudServer> servers = cloudServerRepository.listByVid(vendor.getId(), region.getRegionId());
        for (CloudServer cloudServer : servers) {
            serverKeypairRepository.removeBySid(cloudServer.getId());
        }
        if (ListTool.isEmpty(models)) {
            for (CloudServer server : servers) {
                // cmdb：删除云主机
                infos.add(CmdbInfoConvertor.getInfo(server, "delete", null));
            }
            cloudServerRepository.removeByVid(vendor.getId(), region.getRegionId(), userId);
            // 删除资源表
            resourceRepository.removeByVidReg(vendor.getId(), region.getRegionId(), userId);
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), null, TagType.instance.name());
            return;
        }
        Map<String, CloudServer> serverMap = Maps.newHashMap();
        for (CloudServer server : servers) {
            serverMap.put(server.getInstanceId(), server);
        }
        for (ServerModel model : models) {
            CloudServer server = new CloudServer();
            List<CmdbRelation> relations = Lists.newArrayList();
            relations.add(new CmdbRelation(ModuleCode.REGION.name(), 1L, ListUtils.getList(region.getGuid())));
            if (serverMap.containsKey(model.getInstanceId())) {
                server = serverMap.get(model.getInstanceId());

                String account = server.getAccount();
                if (StringUtils.isEmpty(account)) {
                    Image image = imageMap.get(model.getImageUuid());
                    if (null != image) {
                        account = image.getDefaultUser();
                    }
                }
                model.setAccount(account);
                model.setPassword(server.getPassword());
                BeanUtils.copyProperties(model, server);
                server.setGmtModify(new Date());
                server.setGmtVmCreate(model.getGmtVmCreate());
                server.setVendorId(vendor.getId());
                server.setRegionId(region.getRegionId());
                server.setVendorType(vendor.getType());
                server.setIsTemplate(false);
                List<String> securityGroups = model.getSecurityGroups();
                Image image = imageMap.get(model.getImageUuid());
                if (null != image) {
                    server.setOsCategory(image.getOsType());
                    server.setOsVersion(image.getOsVersion());
                }
                server.setFlavorUuid(server.getFlavorUuid());
                server.setOsName(server.getOsName());
                server.setNetworkUuid(server.getVpcUuid());
                server.setVpcUuid(server.getVpcUuid());
                server.setSubnetUuid(server.getVSwitchId());
                cloudServerRepository.update(server);
                this.updateServerKeyPair(server, keyPairMap);
                // 更新资源表
                updateResource(server, vendor, region.getRegionId(), userId);
                // 更新云主机绑定的安全组
                serverSgroupRepository.removeBySid(server.getId());
                if (null != securityGroups) {
                    updateSGroup(server.getId(), JSON.toJSONString(securityGroups), groupMap);
                }
                // CMDB更新集群数据
                infos.add(CmdbInfoConvertor.getInfo(server, null, relations));
                serverMap.remove(model.getInstanceId());
            } else {
                BeanUtils.copyProperties(model, server);
                List<String> securityGroups = model.getSecurityGroups();
                server.setCreatorId(0L);
                server.setMenderId(0L);
                server.setGmtCreate(new Date());
                server.setVendorId(vendor.getId());
                server.setVendorType(vendor.getType());
                server.setTenantId(0L);
                server.setProjectId(0L);
                server.setRegionId(region.getRegionId());
                server.setIsTemplate(false);
                server.setRecycle(false);
                Image image = imageMap.get(model.getImageUuid());
                if (null != image) {
                    server.setOsCategory(image.getOsType());
                    server.setOsVersion(image.getOsVersion());
                }
                server.setFlavorUuid(server.getFlavorUuid());
                server.setOsName(server.getOsName());
                server.setNetworkUuid(server.getVpcUuid());
                server.setVpcUuid(server.getVpcUuid());
                server.setSubnetUuid(server.getVSwitchId());
                cloudServerRepository.save(server);
                this.updateServerKeyPair(server, keyPairMap);
                // 更新资源表
                updateResource(server, vendor, region.getRegionId(), userId);
                // 更新云主机绑定的安全组
                serverSgroupRepository.removeBySid(server.getId());
                if (null != securityGroups) {
                    updateSGroup(server.getId(), JSON.toJSONString(securityGroups), groupMap);
                }
                // CMDB更新集群数据
                infos.add(CmdbInfoConvertor.getInfo(server, null, relations));
                serverMap.remove(model.getInstanceId());
            }
            syncTag(model.getTagModels(), model.getInstanceId(), TagType.instance.name(), vendor.getId(),
                    region.getRegionId());
        }
        for (Entry<String, CloudServer> entry : serverMap.entrySet()) {
            CloudServer server = entry.getValue();
            cloudServerRepository.remove(server.getId(), userId);
            // 删除资源表
            resourceRepository.remove(server.getId(), ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
                    userId);
            // cmdb：删除云主机
            infos.add(CmdbInfoConvertor.getInfo(server, "delete", null));
            serverSgroupRepository.removeBySid(server.getId());
            serverKeypairRepository.removeBySid(server.getId());
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), server.getInstanceId(),
                    TagType.instance.name());
        }
    }

    private void updateServerKeyPair(CloudServer server, Map<String, Long> keyPairMap) throws Exception {
        String keypairName = server.getKeypairName();
        if (null != keypairName && !"".equals(keypairName)) {
            ServerKeypair serverKeypair = new ServerKeypair();
            serverKeypair.setKeypairId(keyPairMap.get(keypairName));
            serverKeypair.setServerId(server.getId());
            serverKeypairRepository.save(serverKeypair);
        }
    }

    /**
     * 更新云主机安全组
     *
     * @param serverId
     * @param groups
     * @param groupMap
     * @throws Exception
     */
    private void updateSGroup(Long serverId, String groups, Map<String, Long> groupMap) throws Exception {
        if (!StringUtils.isEmpty(groups)) {
            List<String> groupList = JSONArray.parseArray(groups, String.class);
            for (String group : groupList) {
                ServerSgroup serverSgroup = new ServerSgroup(serverId, groupMap.get(group));
                serverSgroupRepository.save(serverSgroup);
            }
        }
    }

    /**
     * 更新资源表相关信息
     *
     * @param server
     * @param vendor
     * @param userId
     * @throws Exception
     */
    private void updateResource(CloudServer server, CloudVendor vendor, String region, Long userId) throws Exception {
        // 更新资源表
        Resource resource = resourceRepository.query(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
                server.getId());
        List<String> ips = new ArrayList<>();
        if (!StringUtils.isEmpty(server.getPrivateIps()) && server.getPrivateIps().contains("[")) {
            ips.addAll(JSONArray.parseArray(server.getPrivateIps(), String.class));
        }
        if (!StringUtils.isEmpty(server.getPublicIps()) && server.getPublicIps().contains("[")) {
            ips.addAll(JSONArray.parseArray(server.getPublicIps(), String.class));
        }
        if (null != resource) {
            resource.setStatus(server.getStatus());
            resource.setPrivateIps(JSONObject.toJSONString(ips));
            resource.setMenderId(userId);
            resource.setAccurated(false);
            resource.setAuthed(false);
            resource.setVendorId(vendor.getId());
            resource.setRegionId(region);
            resourceRepository.update(resource);
            server.setResource(resource);
        } else {
            resource = new Resource(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(), server.getId(),
                    null, server.getOsCategory(), vendor.getId());
            resource.preSave(server.getName(), server.getStatus(), userId, 0L, 0L);
            resource.setInventory(JSONObject.toJSONString(server));
            resource.setPrivateIps(JSONObject.toJSONString(ips));
            resource.setOwnerId(userId);
            resource.setAccurated(false);
            resource.setVendorId(vendor.getId());
            resource.setRegionId(region);
            resource.setAuthed(false);
            resourceRepository.save(resource);
            server.setResource(resource);
        }
    }

    /**
     * 同步镜像
     *
     * @param models
     * @param vendor
     * @param userId
     * @throws Exception
     */
    private void syncImage(List<ImageModel> models, Region region, CloudVendor vendor, Long userId) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            imageRepository.removeByVid(vendor.getId(), region.getRegionId(), userId);
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), null, TagType.image.name());
            return;
        }
        List<Image> images = imageRepository.listByVendorId(vendor.getId(), region.getRegionId());
        Map<String, Image> imageMap = Maps.newHashMap();
        for (Image image : images) {
            imageMap.put(image.getImageUuid(), image);
        }
        for (ImageModel model : models) {
            Image image = new Image();
            if (imageMap.containsKey(model.getImageUuid())) {
                image = imageMap.get(model.getImageUuid());
                BeanUtils.copyProperties(model, image);
                image.setMenderId(userId);
                image.setGmtModify(new Date());
                image.setRegionId(region.getRegionId());
                image.setVendorId(vendor.getId());
                image.setVendorType(vendor.getType());
                imageRepository.update(image);
                imageMap.remove(image.getImageUuid());
            } else {
                BeanUtils.copyProperties(model, image);
                image.setCreatorId(userId);
                image.setGmtCreate(new Date());
                image.setVendorId(vendor.getId());
                image.setVendorType(vendor.getType());
                image.setRegionId(region.getRegionId());
                image.setTenantId(0L);
                image.setProjectId(0L);
                image.setCatalog("VM");
                imageRepository.save(image);
                imageMap.remove(image.getImageUuid());
            }
            syncTag(model.getTagModels(), model.getImageUuid(), TagType.image.name(), vendor.getId(),
                    region.getRegionId());
        }
        for (Entry<String, Image> entry : imageMap.entrySet()) {
            imageRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), entry.getValue().getImageUuid(),
                    TagType.image.name());
        }
    }

    /**
     * 同步云硬盘
     *
     * @param models
     * @param vendor
     * @param userId
     * @param serverMap
     * @throws Exception
     */
    private void syncVolume(List<VolumeModel> models, CloudVendor vendor, Long userId, Map<String, Long> serverMap,
                            Region region) throws Exception {
        if (null == models) {
            return;
        }
        // 删除 脏数据
        volumeRepository.deleteRegionNull(vendor.getId());
        if (ListTool.isEmpty(models)) {
            volumeRepository.removeByVid(vendor.getId(), region.getRegionId(), userId);
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), null, TagType.disk.name());
            return;
        }
        List<Volume> volumes = volumeRepository.listByVendorId(vendor.getId(), region.getRegionId());
        Map<String, Volume> volumeMap = Maps.newHashMap();
        for (Volume volume : volumes) {
            volumeMap.put(volume.getVolumeUuid(), volume);
        }
        for (VolumeModel model : models) {
            Volume volume = new Volume();
            if (volumeMap.containsKey(model.getVolumeUuid())) {
                volume = volumeMap.get(model.getVolumeUuid());
                BeanUtils.copyProperties(model, volume);
                volume.setGmtModify(new Date());
                volume.setDevice(model.getDeviceName());
                volume.setRegionId(region.getRegionId());
                volume.setVendorId(vendor.getId());
                volume.setVendorType(vendor.getType());
                if (!StringUtils.isEmpty(model.getInstanceId())) {
                    volume.setServerId(serverMap.get(model.getInstanceId()));
                }
                volumeRepository.update(volume);
                volumeMap.remove(volume.getVolumeUuid());
            } else {
                BeanUtils.copyProperties(model, volume);
                volume.setCreatorId(userId);
                volume.setMenderId(userId);
                volume.setDevice(model.getDeviceName());
                volume.setGmtCreate(new Date());
                volume.setVendorId(vendor.getId());
                volume.setRegionId(region.getRegionId());
                volume.setVendorType(vendor.getType());
                volume.setTenantId(0L);
                volume.setProjectId(0L);
                if (!StringUtils.isEmpty(model.getInstanceId())) {
                    volume.setServerId(serverMap.get(model.getInstanceId()));
                }
                volumeRepository.save(volume);
                volumeMap.remove(volume.getVolumeUuid());
            }
            syncTag(model.getTagModels(), model.getVolumeUuid(), TagType.disk.name(), vendor.getId(),
                    region.getRegionId());
        }
        for (Entry<String, Volume> entry : volumeMap.entrySet()) {
            volumeRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), entry.getValue().getVolumeUuid(),
                    TagType.disk.name());
        }
    }

    /**
     * 同步快照
     *
     * @param models
     * @param vendor
     * @param userId
     * @param volumeMap
     * @throws Exception
     */
    private void syncSnapshot(List<SnapshotModel> models, CloudVendor vendor, Long userId, Map<String, Long> volumeMap,
                              Region region) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            snapshotRepository.removeByVid(vendor.getId(), region.getRegionId(), userId);
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), null, TagType.snapshot.name());
            return;
        }
        List<Snapshot> snapshots = snapshotRepository.listByVid(vendor.getId(), region.getRegionId());
        Map<String, Snapshot> snapshotMap = Maps.newHashMap();
        for (Snapshot snapshot : snapshots) {
            snapshotMap.put(snapshot.getSnapshotUuid(), snapshot);
        }
        for (SnapshotModel model : models) {
            if (snapshotMap.containsKey(model.getSnapshotUuid())) {
                Snapshot snapshot = snapshotMap.get(model.getSnapshotUuid());
                BeanUtils.copyProperties(model, snapshot);
                snapshot.setVolumeId(volumeMap.get(model.getVolumeUuid()));
                snapshot.setMenderId(userId);
                snapshot.setVendorId(vendor.getId());
                snapshot.setRegion(region.getId());
                snapshot.setRegionId(region.getRegionId());
                snapshotRepository.update(snapshot);
                snapshotMap.remove(model.getSnapshotUuid());
            } else {
                Snapshot snapshot = JSONObject.parseObject(JSONObject.toJSONString(model), Snapshot.class);
                snapshot.setVolumeId(volumeMap.get(model.getVolumeUuid()));
                snapshot.setRegion(region.getId());
                snapshot.setRegionId(region.getRegionId());
                snapshot.preSave(userId, userId, vendor.getId(), null, 0L, 0L);
                snapshotRepository.save(snapshot);
            }
            syncTag(model.getTagModels(), model.getSnapshotUuid(), TagType.snapshot.name(), vendor.getId(),
                    region.getRegionId());
        }
        for (Entry<String, Snapshot> entry : snapshotMap.entrySet()) {
            snapshotRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendor.getId(), region.getRegionId(), entry.getValue().getSnapshotUuid(),
                    TagType.snapshot.name());
        }
    }

    /**
     * 同步安全组
     *
     * @param models
     * @param vendor
     * @param userId
     * @throws Exception
     */
    private void syncSecurityGroup(List<SecurityGroupModel> models, CloudVendor vendor, Long userId, String region,
                                   Map<String, Vpc> vpcMap) throws Exception {
        if (null == models) {
            return;
        }
        // 当安全组为空时,删除数据库残留数据
        if (ListTool.isEmpty(models)) {
            securityGroupRepository.removeByVid(vendor.getId(), region, userId);
            tagRepository.removeByRes(vendor.getId(), region, null, TagType.securitygroup.name());
            return;
        }
        List<SecurityGroup> groups = securityGroupRepository.listByVendorId(vendor.getId(), region);
        Map<String, SecurityGroup> groupMap = Maps.newHashMap();
        for (SecurityGroup group : groups) {
            groupMap.put(group.getGroupUuid(), group);
        }
        for (SecurityGroupModel model : models) {
            SecurityGroup group = new SecurityGroup();
            if (groupMap.containsKey(model.getGroupUuid())) {
                group = groupMap.get(model.getGroupUuid());
                BeanUtils.copyProperties(model, group);
                group.setMenderId(userId);
                group.setVendorId(vendor.getId());
                group.setRegionId(region);
                if (vpcMap != null && vpcMap.containsKey(model.getVpcUuid())) {
                    group.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
                }
                securityGroupRepository.update(group);
                securityGroupRuleRepository.removeBySgId(group.getId(), userId);
                for (SecurityGroupRuleModel securityGroupRuleModel : model.getModels()) {
                    SecurityGroupRule securityGroupRule = new SecurityGroupRule();
                    BeanUtils.copyProperties(securityGroupRuleModel, securityGroupRule);
                    securityGroupRule.setCreatorId(userId);
                    securityGroupRule.setVendorId(vendor.getId());
                    securityGroupRule.setGroupId(group.getId());
                    securityGroupRule.setGroupUuid(group.getGroupUuid());
                    securityGroupRuleRepository.save(securityGroupRule);
                }
                groupMap.remove(model.getGroupUuid());
            } else {
                group = JSONObject.parseObject(JSONObject.toJSONString(model), SecurityGroup.class);
                BeanUtils.copyProperties(model, group);
                group.preSave(userId, userId, vendor.getId(), 0L, 0L);
                group.setRegionId(region);
                if (vpcMap != null && vpcMap.containsKey(model.getVpcUuid())) {
                    group.setVpcId(vpcMap.get(model.getVpcUuid()).getId());
                }
                securityGroupRepository.save(group);
                securityGroupRuleRepository.removeBySgId(group.getId(), userId);
                for (SecurityGroupRuleModel securityGroupRuleModel : model.getModels()) {
                    SecurityGroupRule securityGroupRule = new SecurityGroupRule();
                    BeanUtils.copyProperties(securityGroupRuleModel, securityGroupRule);
                    securityGroupRule.setCreatorId(userId);
                    securityGroupRule.setVendorId(vendor.getId());
                    securityGroupRule.setGroupId(group.getId());
                    securityGroupRule.setGroupUuid(group.getGroupUuid());
                    securityGroupRuleRepository.save(securityGroupRule);
                }
            }
            syncTag(model.getTagModels(), model.getGroupUuid(), TagType.securitygroup.name(), vendor.getId(), region);
        }
        // 删除不存在的安全组
        for (Entry<String, SecurityGroup> entry : groupMap.entrySet()) {
            securityGroupRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendor.getId(), region, entry.getValue().getGroupUuid(),
                    TagType.securitygroup.name());
        }
    }

    /**
     * 同步云主机规格
     *
     * @param models
     * @param vendorId
     * @throws Exception
     */
    private void syncInstanceType(List<FlavorModel> models, Long vendorId, Region region) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            flavorRepository.removeByVid(vendorId, region.getRegionId());
            return;
        }
        List<Flavor> flavors = flavorRepository.listByVendorId(vendorId, region.getRegionId());
        Map<String, Flavor> flavorMap = Maps.newHashMap();
        for (Flavor flavor : flavors) {
            flavorMap.put(flavor.getFlavorUuid() + "_" + flavor.getZone() + "_" + flavor.getRegionId(), flavor);
        }
        Flavor flavor = null;
        for (FlavorModel model : models) {
            flavor = new Flavor();
            if (flavorMap.containsKey(model.getFlavorUuid() + "_" + model.getZone() + "_" + model.getRegionId())) {
                flavor = flavorMap.get(model.getFlavorUuid() + "_" + model.getZone() + "_" + model.getRegionId());
                BeanUtils.copyProperties(model, flavor);
                flavor.setVendorId(vendorId);
                flavor.setRegionId(region.getRegionId());
                flavorRepository.update(flavor);
                flavorMap.remove(model.getFlavorUuid() + "_" + model.getZone() + "_" + model.getRegionId());
                continue;
            }
            BeanUtils.copyProperties(model, flavor);
            flavor.setVendorId(vendorId);
            flavor.setRegionId(region.getRegionId());
            flavorRepository.save(flavor);
            flavorMap.remove(model.getFlavorUuid() + "_" + model.getZone() + "_" + model.getRegionId());
        }
        for (Map.Entry<String, Flavor> entry : flavorMap.entrySet()) {
            flavorRepository.delete(entry.getValue().getId());
        }

    }

    /**
     * 同步域
     *
     * @param regionModels
     * @param region
     * @param vendor
     * @param userId
     * @throws Exception
     */
    private void syncRegion(List<RegionModel> regionModels, Region region, CloudVendor vendor, Long userId)
            throws Exception {
        if (null == regionModels) {
            return;
        }
        if (ListTool.isEmpty(regionModels)) {
            regionRepository.deleteByVid(vendor.getId(), region.getRegionId());
            zoneRepository.deleteByRegionId(region.getRegionId(), vendor.getId());
            return;
        }
        for (RegionModel model : regionModels) {
            syncZone(model.getZones(), model.getCode(), vendor, userId);
        }
    }

    /**
     * 同步域下面的区
     *
     * @param models
     * @param regionId
     * @param vendor、
     * @param userId
     * @throws Exception
     */
    private void syncZone(List<ZoneModel> models, String regionId, CloudVendor vendor, Long userId) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            zoneRepository.deleteByRegionId(regionId, vendor.getId());
            return;
        }
        List<Zone> zones = zoneRepository.listByRegionId(regionId, vendor.getId());
        Map<String, Zone> zoneMap = Maps.newHashMap();
        for (Zone zone : zones) {
            zoneMap.put(zone.getZoneId(), zone);
        }
        for (ZoneModel model : models) {
            Zone zone = new Zone();
            if (zoneMap.containsKey(model.getZoneId())) {
                zone = zoneMap.get(model.getZoneId());
                BeanUtils.copyProperties(model, zone);
                zone.setVendorId(vendor.getId());
                zone.setRegionId(regionId);
                zoneRepository.update(zone);
                zoneMap.remove(model.getZoneId());
                continue;
            }
            BeanUtils.copyProperties(model, zone);
            zone.setVendorId(vendor.getId());
            zone.setRegionId(regionId);
            zoneRepository.save(zone);
            zoneMap.remove(model.getZoneId());
        }
        for (Entry<String, Zone> entry : zoneMap.entrySet()) {
            zoneRepository.delete(entry.getValue().getId());
        }
    }

    /**
     * 同步vpc专用网络
     *
     * @param models
     * @param vendorId
     * @param userId
     * @throws Exception
     */
    private void syncVpc(List<VpcModel> models, Long vendorId, Long userId, Region region) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            vpcRepository.deleteByVid(vendorId, region.getRegionId(), userId);
            tagRepository.removeByRes(vendorId, region.getRegionId(), null, TagType.VPC.name());
            return;
        }
        List<Vpc> vpcs = vpcRepository.list(vendorId, region.getRegionId());
        Map<String, Vpc> vpcMap = Maps.newHashMap();
        for (Vpc vpc : vpcs) {
            vpcMap.put(vpc.getVpcId(), vpc);
        }
        for (VpcModel model : models) {
            Vpc vpc = new Vpc();
            if (vpcMap.containsKey(model.getVpcId())) {
                vpc = vpcMap.get(model.getVpcId());
                BeanUtils.copyProperties(model, vpc);
                vpc.setRouterUuid(model.getRouterId());
                vpc.setGmtModify(new Date());
                vpc.setVendorId(vendorId);
                vpc.setRegionId(region.getRegionId());
                vpcRepository.update(vpc);
                vpcMap.remove(model.getVpcId());
            } else {
                BeanUtils.copyProperties(model, vpc);
                vpc.setRouterUuid(model.getRouterId());
                vpc.setCreatorId(userId);
                vpc.setMenderId(userId);
                vpc.setGmtCreate(new Date());
                vpc.setVendorId(vendorId);
                vpc.setRegionId(region.getRegionId());
                vpc.setTenantId(0L);
                vpc.setProjectId(0L);
                vpcRepository.save(vpc);
                vpcMap.remove(model.getVpcId());
            }
            syncTag(model.getTagModels(), model.getVpcId(), TagType.VPC.name(), vendorId, region.getRegionId());
            syncCidr(model.getCidrBlockModels(), vendorId, userId, region.getRegionId(), vpc.getVpcId());
        }
        for (Entry<String, Vpc> entry : vpcMap.entrySet()) {
            vpcRepository.delete(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendorId, region.getRegionId(), entry.getValue().getVpcId(), TagType.VPC.name());
        }
    }

    /**
     * 同步Cidr
     *
     * @param models
     * @param vendorId
     * @param userId
     * @throws Exception
     */
    private void syncCidr(List<CidrBlockModel> models, Long vendorId, Long userId, String region, String targetId)
            throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            cidrBlockRepository.removeByVid(vendorId, region, userId, targetId);
            return;
        }
        List<CidrBlock> cidrBlocks = cidrBlockRepository.listByVid(vendorId, region, targetId);
        Map<String, CidrBlock> cidrBlockMap = Maps.newHashMap();
        for (CidrBlock cidrBlock : cidrBlocks) {
            cidrBlockMap.put(cidrBlock.getTargetId() + "_" + cidrBlock.getCidrBlock(), cidrBlock);
        }
        for (CidrBlockModel model : models) {
            CidrBlock cidrBlock = new CidrBlock();
            if (cidrBlockMap.containsKey(model.getTargetId() + "_" + model.getCidrBlock())) {
                cidrBlock = cidrBlockMap.get(model.getTargetId() + "_" + model.getCidrBlock());
                BeanUtils.copyProperties(model, cidrBlock);
                cidrBlock.setMenderId(userId);
                cidrBlock.setGmtModify(new Date());
                cidrBlock.setVendorId(vendorId);
                cidrBlock.setRegionId(region);
                cidrBlockRepository.update(cidrBlock);
                cidrBlockMap.remove(model.getTargetId() + "_" + model.getCidrBlock());
                continue;
            }
            BeanUtils.copyProperties(model, cidrBlock);
            cidrBlock.setCreatorId(userId);
            cidrBlock.setGmtCreate(new Date());
            cidrBlock.setVendorId(vendorId);
            cidrBlock.setRegionId(region);
            cidrBlockRepository.save(cidrBlock);
            cidrBlockMap.remove(model.getTargetId() + "_" + model.getCidrBlock());
        }
        for (Map.Entry<String, CidrBlock> entry : cidrBlockMap.entrySet()) {
            cidrBlockRepository.remove(entry.getValue().getId(), userId);
        }
    }

    /**
     * 同步密钥
     *
     * @param models
     * @param vendorId
     * @param userId
     * @throws Exception
     */
    private void syncKeypair(List<KeypairModel> models, String regionId, Long vendorId, Long userId) throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            keypairRepository.removeByVid(vendorId, regionId, userId);
            tagRepository.removeByRes(vendorId, regionId, null, TagType.keypair.name());
            return;
        }
        List<Keypair> keypairs = keypairRepository.listByVid(vendorId, regionId);
        Map<String, Keypair> keypairMap = Maps.newHashMap();
        for (Keypair keypair : keypairs) {
            if (keypairMap.containsKey(keypair.getFingerprint())) {
                keypairRepository.remove(keypair.getId(), userId);
            } else {
                keypairMap.put(keypair.getFingerprint(), keypair);
            }
        }
        for (KeypairModel model : models) {
            Keypair keypair = new Keypair();
            if (keypairMap.containsKey(model.getFingerprint())) {
                keypair = keypairMap.get(model.getFingerprint());
                model.setGmtCreate(keypair.getGmtCreate());
                model.setUserUuid(keypair.getUserUuid());
                BeanUtils.copyProperties(model, keypair);
                keypair.setMenderId(userId);
                keypair.setVendorId(vendorId);
                keypair.setRegionId(regionId);
                keypair.setGmtModify(new Date());
                keypairRepository.update(keypair);
                keypairMap.remove(model.getFingerprint());
            } else {
                BeanUtils.copyProperties(model, keypair);
                keypair.setCreatorId(userId);
                keypair.setGmtCreate(new Date());
                keypair.setVendorId(vendorId);
                keypair.setRegionId(regionId);
                keypair.setVendorId(vendorId);
                keypair.setTenantId(0L);
                keypair.setProjectId(0L);
                keypairRepository.save(keypair);
                keypairMap.remove(model.getFingerprint());
            }
            syncTag(model.getTagModels(), model.getFingerprint(), TagType.keypair.name(), vendorId, regionId);
        }
        for (Map.Entry<String, Keypair> entry : keypairMap.entrySet()) {
            keypairRepository.remove(entry.getValue().getId(), userId);
            tagRepository.removeByRes(vendorId, regionId, entry.getValue().getFingerprint(), TagType.keypair.name());
        }
    }

    /***
     * 同步 tag
     *
     * @param models
     * @param resourceId
     * @param resourceType
     * @param vendorId
     * @param regionId
     * @throws Exception
     */
    private void syncTag(List<TagModel> models, String resourceId, String resourceType, Long vendorId, String regionId)
            throws Exception {
        if (null == models) {
            return;
        }
        if (ListTool.isEmpty(models)) {
            tagRepository.removeByRes(vendorId, regionId, resourceId, resourceType);
            return;
        }
        List<Tag> tagList = tagRepository.listByRes(vendorId, regionId, resourceId, resourceType);
        Map<String, Tag> tagMap = Maps.newHashMap();
        for (Tag tag : tagList) {
            tagMap.put(tag.getKey() + resourceId + resourceType, tag);
        }
        for (TagModel model : models) {
            Tag tag = new Tag();
            if (tagMap.containsKey(model.getKey() + resourceId + resourceType)) {
                tag = tagMap.get(model.getKey() + resourceId + resourceType);
                BeanUtils.copyProperties(model, tag);
                tag.setResourceType(resourceType);
                tag.setVendorId(vendorId);
                tag.setGmtModify(new Date());
                tag.setRegionId(regionId);
                tagRepository.update(tag);
                tagMap.remove(model.getKey() + resourceId + resourceType);
                continue;
            }
            BeanUtils.copyProperties(model, tag);
            tag.setResourceType(model.getResourceType());
            tag.setVendorId(vendorId);
            tag.setRegionId(regionId);
            tagRepository.save(tag);
            tagMap.remove(model.getKey() + resourceId + resourceType);
        }
        for (Map.Entry<String, Tag> entry : tagMap.entrySet()) {
            tagRepository.remove(entry.getValue().getId());
        }
    }

    public BocloudResult syncCostForMonth(CloudVendor vendor, RequestContext context) throws Exception {
        try {
            BocloudResult result = new BocloudResult(true, "账单同步成功！");
            logger.info("Starting sync aliyun cost for month......");
            SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            Date month = calendar.getTime();
            String monthS = monthFormat.format(month);
            // MONTHLY：月。DAILY：日。
            result = locationDriver.syncAliCost(vendor.getUuid(), monthS, "MONTHLY", null);
            if (result.isFailed()) {
                logger.info("sync aliyun cost failed:" + result.getMessage());
                return new BocloudResult(false, "账单同步失败" + result.getMessage());
            }
            AliyunSyncModel syncModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                    AliyunSyncModel.class);
            List<AliCostModel> models = syncModel.getCostModels();

            List<AliCost> aliCostList = aliCostRepository.listByVid(vendor.getId(), "MONTHLY", monthS);
            Map<String, AliCost> costMap = Maps.newHashMap();
            for (AliCost cost : aliCostList) {
                costMap.put(cost.getPeriod() + cost.getPeriodTime() + cost.getProductCode() + cost.getInstanceId(),
                        cost);
            }
            for (AliCostModel model : models) {
                AliCost cost = new AliCost();
                if (costMap.containsKey(
                        model.getPeriod() + model.getPeriodTime() + model.getProductCode() + model.getInstanceId())) {
                    continue;
                }
                BeanUtils.copyProperties(model, cost);
                cost.setVendorId(vendor.getId());
                cost.setCreatorId(context.getTarget());
                aliCostRepository.save(cost);
                costMap.remove(
                        model.getPeriod() + model.getPeriodTime() + model.getProductCode() + model.getInstanceId());
            }
            logger.info("End sync aliyun cost......");
            return new BocloudResult(true, "账单同步成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e);
            return new BocloudResult(false, "账单同步失败:" + e.getMessage());
        }
    }

    public BocloudResult syncCostForDay(CloudVendor vendor, RequestContext context) throws Exception {
        try {
            BocloudResult result = new BocloudResult(true, "账单同步成功！");
            logger.info("Starting sync aliyun cost for day......");
            SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -1);
            Date day = calendar.getTime();
            String dayS = dayFormat.format(day);
            String monthS = monthFormat.format(day);
            // MONTHLY：月。DAILY：日。
            result = locationDriver.syncAliCost(vendor.getUuid(), monthS, "DAILY", dayS);
            if (result.isFailed()) {
                logger.info("sync aliyun cost failed:" + result.getMessage());
                return new BocloudResult(false, "账单同步失败" + result.getMessage());
            }
            AliyunSyncModel syncModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                    AliyunSyncModel.class);
            List<AliCostModel> models = syncModel.getCostModels();

            List<AliCost> aliCostList = aliCostRepository.listByVid(vendor.getId(), "DAILY", dayS);
            Map<String, AliCost> costMap = Maps.newHashMap();
            for (AliCost cost : aliCostList) {
                costMap.put(cost.getPeriod() + cost.getPeriodTime() + cost.getProductCode() + cost.getInstanceId(),
                        cost);
            }
            for (AliCostModel model : models) {
                AliCost cost = new AliCost();
                if (costMap.containsKey(
                        model.getPeriod() + model.getPeriodTime() + model.getProductCode() + model.getInstanceId())) {
                    continue;
                }
                BeanUtils.copyProperties(model, cost);
                cost.setVendorId(vendor.getId());
                cost.setCreatorId(context.getTarget());
                aliCostRepository.save(cost);
                costMap.remove(
                        model.getPeriod() + model.getPeriodTime() + model.getProductCode() + model.getInstanceId());
            }
            logger.info("End sync aliyun cost......");
            return new BocloudResult(true, "账单同步成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e);
            return new BocloudResult(false, "账单同步失败:" + e.getMessage());
        }
    }

	@Override
	protected void register() {
		// TODO Auto-generated method stub
		 
	}

	@Override
	protected void beforeTransport() {
		// TODO Auto-generated method stub
		 
	}

	@Override
	protected void afterTransport() {
		// TODO Auto-generated method stub
		 
	}

}
