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

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
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.model.AwsSyncModel;
import com.bocloud.cmp.model.CidrBlockModel;
import com.bocloud.cmp.model.CloudCostModel;
import com.bocloud.cmp.model.ElasticIpModel;
import com.bocloud.cmp.model.FlavorModel;
import com.bocloud.cmp.model.ImageModel;
import com.bocloud.cmp.model.InternetGatewayModel;
import com.bocloud.cmp.model.KeypairModel;
import com.bocloud.cmp.model.LbListenerModel;
import com.bocloud.cmp.model.LbModel;
import com.bocloud.cmp.model.LbTargetGroupModel;
import com.bocloud.cmp.model.LbTargetModel;
import com.bocloud.cmp.model.NatGatewayModel;
import com.bocloud.cmp.model.NetworkInterfaceModel;
import com.bocloud.cmp.model.RegionModel;
import com.bocloud.cmp.model.RouteModel;
import com.bocloud.cmp.model.RouteTableAssociationModel;
import com.bocloud.cmp.model.RouteTableModel;
import com.bocloud.cmp.model.SecurityGroupModel;
import com.bocloud.cmp.model.SecurityGroupRuleModel;
import com.bocloud.cmp.model.ServerModel;
import com.bocloud.cmp.model.SnapshotModel;
import com.bocloud.cmp.model.SubnetModel;
import com.bocloud.cmp.model.TagModel;
import com.bocloud.cmp.model.VolumeModel;
import com.bocloud.cmp.model.VpcModel;
import com.bocloud.cmp.model.ZoneModel;
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.resource.CidrBlock;
import com.bocloud.ims.entity.resource.CloudCost;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.ElasticIp;
import com.bocloud.ims.entity.resource.Flavor;
import com.bocloud.ims.entity.resource.Image;
import com.bocloud.ims.entity.resource.InternetGateway;
import com.bocloud.ims.entity.resource.Keypair;
import com.bocloud.ims.entity.resource.LbListener;
import com.bocloud.ims.entity.resource.LbTarget;
import com.bocloud.ims.entity.resource.LbTargetGroup;
import com.bocloud.ims.entity.resource.LoadBalancer;
import com.bocloud.ims.entity.resource.NatGateway;
import com.bocloud.ims.entity.resource.NetworkInterface;
import com.bocloud.ims.entity.resource.Region;
import com.bocloud.ims.entity.resource.Resource;
import com.bocloud.ims.entity.resource.Route;
import com.bocloud.ims.entity.resource.RouteTable;
import com.bocloud.ims.entity.resource.RouteTableAssociation;
import com.bocloud.ims.entity.resource.SecurityGroup;
import com.bocloud.ims.entity.resource.SecurityGroupRule;
import com.bocloud.ims.entity.resource.ServerKeypair;
import com.bocloud.ims.entity.resource.ServerSgroup;
import com.bocloud.ims.entity.resource.Snapshot;
import com.bocloud.ims.entity.resource.Subnet;
import com.bocloud.ims.entity.resource.Tag;
import com.bocloud.ims.entity.resource.Volume;
import com.bocloud.ims.entity.resource.Vpc;
import com.bocloud.ims.entity.resource.Zone;
import com.bocloud.ims.repository.resource.CloudCostRepository;
import com.bocloud.ims.repository.resource.LbTargetGroupRepository;
import com.bocloud.ims.repository.resource.LbTargetRepository;
import com.bocloud.ims.repository.resource.RouteTableAssociationRepository;
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.ListUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * @Company: 博云 www.bocloud.com
 * @ClassName: AwsTransportor
 * @Description:
 * @author: zhenpingLi/李振平
 * @date: 2019/10/15 16:39
 */
@Component
public class AwsTransporter extends AbstractTransporter {
	private static Logger logger = LoggerFactory.getLogger(AwsTransporter.class);

	@Autowired
	private LbTargetGroupRepository lbTargetGroupRepository;
	@Autowired
	private LbTargetRepository lbTargetRepository;
	@Autowired
	private RouteTableAssociationRepository routeTableAssociationRepository;
	@Autowired
	private CloudCostRepository cloudCostRepository;

	@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);
				AwsSyncModel model = JSONObject.parseObject(content, AwsSyncModel.class);
				/**
				 * models为null时数据拉取失败，不同步数据。
				 */
				// 同步弹性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 internet gateway......");
				this.syncInternetGateway(model.getInternetGatewayModels(), vendor.getId(), userId,
						region.getRegionId());
				logger.info("End sync internet gateway......");
				// 同步域
				logger.info("Starting sync region and zone......");
				this.syncRegion(model.getRegionModels(), vendor, region.getRegionId());
				logger.info("End sync region and zone......");
				// 同步vpc
				logger.info("Starting sync vpc......");
				this.syncVpc(model.getVpcModels(), vendor.getId(), userId, region.getRegionId());
				logger.info("End sync vpc......");
				List<Vpc> list = vpcRepository.list(vendor.getId(), region.getRegionId());
				Map<String, Long> vpcMap = Maps.newHashMap();
				for (Vpc vpc : list) {
					vpcMap.put(vpc.getVpcId(), vpc.getId());
				}
				// 同步负载均衡
				logger.info("Starting sync lb......");
				this.syncLoadBalancer(model.getLbModels(), vpcMap, vendor.getId(), userId, region.getRegionId());
				List<LoadBalancer> balancers = loadBalancerRepository.listByVid(vendor.getId(), region.getRegionId());
				Map<String, Long> balancerMap = Maps.newHashMap();
				for (LoadBalancer balancer : balancers) {
					balancerMap.put(balancer.getLbUuid(), balancer.getId());
				}
				logger.info("End sync lb......");
				// 同步目标群组
				logger.info("Starting sync lb target group......");
				this.syncLbTargetGroup(model.getLbTargetGroupModels(), vendor.getId(), userId, region.getRegionId());
				List<LbTargetGroup> targetGroups = lbTargetGroupRepository.listByVid(vendor.getId(),
						region.getRegionId());
				Map<String, Long> tgMap = Maps.newHashMap();
				for (LbTargetGroup group : targetGroups) {
					tgMap.put(group.getUuid(), group.getId());
				}
				logger.info("End sync lb target group......");
				// 同步群组目标
				logger.info("Starting sync lb target......");
				this.syncLbTarget(model.getLbTargetModels(), tgMap, vendor.getId(), userId, region.getRegionId());
				logger.info("End sync lb target......");
				// 同步侦听器
				logger.info("Starting sync listener......");
				this.syncLbListener(model.getLbListenerModels(), balancerMap, vendor.getId(), userId,
						region.getRegionId());
				logger.info("End sync lb listener......");
				// 同步路由表
				logger.info("Starting sync route tables......");
				this.syncRouteTable(vpcMap, model.getRouteTableModels(), vendor.getId(), userId, region.getRegionId());
				logger.info("End sync route tables......");
				// 同步子网
				logger.info("Starting sync subnet......");
				this.syncSubnet(model.getSubnetModels(), vendor.getId(), userId, region.getRegionId(), vpcMap);
				logger.info("End sync subnet......");
				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 keypair......");
				this.syncKeyPairs(model.getKeypairModels(), vendor.getId(), userId, region.getRegionId());
				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());
				}
				// 同步安全组
				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 flavor ......");
				this.syncFlavor(model.getFlavorModels(), vendor.getId(), region.getRegionId());
				logger.info("End sync flavor ......");
				List<Flavor> flavors = flavorRepository.listByVendorId(vendor.getId());
				Map<String, Flavor> flavorMap = Maps.newHashMap();
				for (Flavor flavor : flavors) {
					flavorMap.put(flavor.getFlavorUuid(), flavor);
				}
				// 获取数据盘大小 用于存储到云主机中
				Map<String, VolumeModel> volumeSizeMap = Maps.newHashMap();
				List<VolumeModel> volumeModels = model.getVolumeModels();
				for (VolumeModel volumeModel : volumeModels) {
					volumeSizeMap.put(volumeModel.getVolumeUuid(), volumeModel);
				}
				// 获取网络接口去更替云主机的ip 注：云主机只能获取主接口ip，获取不到第二接口ip
				Map<String, List<String>> ipMap = Maps.newHashMap();
				model.getNetworkInterfaceModels().stream().forEach(ipmodel -> {
					if (!StringUtils.isEmpty(ipmodel.getVirtualMachineUuid())
							&& ipMap.containsKey(ipmodel.getVirtualMachineUuid())) {
						ipMap.get(ipmodel.getVirtualMachineUuid()).add(ipmodel.getPrimaryPrivateIPAddress());
					} else if (!StringUtils.isEmpty(ipmodel.getVirtualMachineUuid())) {
						ipMap.put(ipmodel.getVirtualMachineUuid(),
								new ArrayList<>(Arrays.asList(ipmodel.getPrimaryPrivateIPAddress())));
					}
					if (ipmodel.getIpv6Address() != null) {
						ipMap.get(ipmodel.getVirtualMachineUuid()).add(ipmodel.getIpv6Address());
					}
				});
				// 同步云主机
				logger.info("Starting sync server......");
				this.syncServer(model.getServerModels(), vendor, userId, groupMap, region, keyPairMap, null, flavorMap,
						volumeSizeMap, ipMap);
				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());
				}

				// 同步网络接口 关联安全组 关联vpc 关联云主机
				logger.info("Starting sync networkInterface......");
				this.syncNetworkInterface(model.getNetworkInterfaceModels(), vendor, userId, groupMap, vpcMap,
						serverMap, region.getRegionId(), subnetMap);
				logger.info("End sync networkInterface......");
				List<NetworkInterface> networkInterfaces = networkInterfaceRepository.listByVendorId(vendor.getId(),
						region.getRegionId());
				Map<String, Long> networkInterfaceMap = Maps.newHashMap();
				for (NetworkInterface networkInterface : networkInterfaces) {
					networkInterfaceMap.put(networkInterface.getNetworkInterfaceUuid(), networkInterface.getId());
				}

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

				// 同步云硬盘
				logger.info("Starting sync volume......");
				this.syncVolume(model.getVolumeModels(), vendor, userId, serverMap, region.getRegionId());
				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.getRegionId());
				logger.info("End sync snapshot......");
				// 数据较大 开启线程同步
				taskExecutor.submit(() -> {
					BocloudResult awsImageResult = locationDriver.syncAwsImages(vendor.getUuid(), region.getRegionId());
					List<ImageModel> imageModels = new ArrayList<>();
					if (awsImageResult.isSuccess()) {
						String imageContent = JSONObject.toJSONString(awsImageResult.getData());
						AwsSyncModel awsSyncModel = JSONObject.parseObject(imageContent, AwsSyncModel.class);
						imageModels = awsSyncModel.getImageModels();
					} else {
						imageModels = null;
					}
					try {
						logger.info("Starting sync image......");
						this.syncImage(imageModels, vendor, userId, region.getRegionId());
						logger.info("End sync image......");
						// 同步标签
						logger.info("Starting sync tag......");
						this.syncTag(model.getTagModels(), vendor.getId(), userId, region.getRegionId());
						logger.info("End sync tag......");
						logger.info(vendor.getName() + "[" + region.getRegionId() + "]" + "线程同步成功！！！");
					} catch (Exception e) {
						logger.error("获取数据存储镜像失败：", e);
					}
				});
			}
			return new BocloudResult(true, null, "云平台【 " + vendor.getName() + " 】数据同步成功");
		} catch (Exception e) {
			logger.error("aws云同步数据失败 ： " + e);
			return new BocloudResult(false, e.getMessage(), "云平台【 " + vendor.getName() + " 】数据同步失败: " + e.getMessage());
		}
	}

	/**
	 * 云主机网络接口
	 *
	 * @param models
	 * @param vendor
	 * @param userId
	 * @param groupMap
	 * @throws Exception
	 */
	private void syncNetworkInterface(List<NetworkInterfaceModel> models, CloudVendor vendor, Long userId,
			Map<String, Long> groupMap, Map<String, Long> vpcMap, Map<String, Long> serverMap, String region,
			Map<String, Subnet> subnetMap) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			networkInterfaceRepository.removeByVid(vendor.getId(), userId, region);
			return;
		}
		List<NetworkInterface> networkInterfaces = networkInterfaceRepository.listByVendorId(vendor.getId(), 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.setMenderId(userId);
				networkInterface.setVendorId(vendor.getId());
				// 关联安全组
				networkInterface.setSgroupUuid(Optional.ofNullable(model.getSecurityGroups())
						.map(securityGroups -> JSON.toJSONString(securityGroups)).orElse(null));
				// 关联vpc
				networkInterface.setVpcId(Optional.ofNullable(model.getNetworkUuid())
						.map(networkUuid -> vpcMap.get(networkUuid)).orElse(null));
				// 关联云主机
				networkInterface.setServerId(Optional.ofNullable(model.getVirtualMachineUuid())
						.map(virtualMachineId -> serverMap.get(virtualMachineId)).orElse(null));
				// 关联子网
				networkInterface.setSubnetId(Optional.ofNullable(model.getSubnetUuid())
						.map(subnetUuid -> subnetMap.get(subnetUuid).getId()).orElse(null));
				networkInterface.setSubnetName(Optional.ofNullable(model.getSubnetUuid())
						.map(subnetUuid -> subnetMap.get(subnetUuid).getName()).orElse(null));
				networkInterface.setRegionId(region);
				networkInterfaceRepository.update(networkInterface);
				networkInterfaceMap.remove(model.getNetworkInterfaceUuid());
				continue;
			}
			BeanUtils.copyProperties(model, networkInterface);
			networkInterface.setCreatorId(userId);
			networkInterface.setVendorId(vendor.getId());
			// 关联安全组
			networkInterface.setSgroupUuid(Optional.ofNullable(model.getSecurityGroups())
					.map(securityGroups -> JSON.toJSONString(securityGroups)).orElse(null));
			// 关联vpc
			networkInterface.setVpcId(Optional.ofNullable(model.getNetworkUuid())
					.map(networkUuid -> vpcMap.get(networkUuid)).orElse(null));
			// 关联云主机
			networkInterface.setServerId(Optional.ofNullable(model.getVirtualMachineUuid())
					.map(virtualMachineId -> serverMap.get(virtualMachineId)).orElse(null));
			// 关联子网
			networkInterface.setSubnetId(Optional.ofNullable(model.getSubnetUuid())
					.map(subnetUuid -> subnetMap.get(subnetUuid).getId()).orElse(null));
			networkInterface.setSubnetName(Optional.ofNullable(model.getSubnetUuid())
					.map(subnetUuid -> subnetMap.get(subnetUuid).getName()).orElse(null));
			networkInterface.setRegionId(region);
			networkInterfaceRepository.save(networkInterface);
			networkInterfaceMap.remove(model.getNetworkInterfaceUuid());
		}
		for (Map.Entry<String, NetworkInterface> entry : networkInterfaceMap.entrySet()) {
			networkInterfaceRepository.delete(entry.getValue().getId(), userId);
		}
	}

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

	private void syncSubnet(List<SubnetModel> models, Long id, Long userId, String region, Map<String, Long> vpcMap)
			throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			subnetRepository.removeByVid(id, region, userId);
			return;
		}
		List<Subnet> subnets = subnetRepository.listByRegion(id, region);
		Map<String, Subnet> subnetMap = Maps.newHashMap();
		for (Subnet subnet : subnets) {
			subnetMap.put(subnet.getSubnetUuid(), subnet);
		}
		Subnet subnet = null;
		for (SubnetModel model : models) {
			subnet = new Subnet();
			if (subnetMap.containsKey(model.getSubnetUuid())) {
				subnet = subnetMap.get(model.getSubnetUuid());
				BeanUtils.copyProperties(model, subnet);
				if (vpcMap.containsKey(model.getVpcUuid())) {
					subnet.setNetworkId(vpcMap.get(model.getVpcUuid()));
					subnet.setVpcId(vpcMap.get(model.getVpcUuid()));
				}
				subnet.setVpcUuid(model.getVpcUuid());
				subnet.setMenderId(userId);
				subnet.setGmtModify(new Date());
				subnet.setRegionId(region);
				subnetRepository.update(subnet);
				subnetMap.remove(model.getSubnetUuid());
				// 同步cidr
				syncCidr(model.getCidrBlockModels(), id, userId, region, subnet.getSubnetUuid());
				continue;
			}
			BeanUtils.copyProperties(model, subnet);
			subnet.setSubnetUuid(model.getSubnetUuid());
			if (vpcMap.containsKey(model.getVpcUuid())) {
				subnet.setNetworkId(vpcMap.get(model.getVpcUuid()));
				subnet.setVpcId(vpcMap.get(model.getVpcUuid()));
			}
			subnet.setVpcUuid(model.getVpcUuid());
			subnet.setCreatorId(userId);
			subnet.setVendorId(id);
			subnet.setRegionId(region);
			subnetRepository.save(subnet);
			subnetMap.remove(model.getSubnetUuid());
			// 同步cidr
			syncCidr(model.getCidrBlockModels(), id, userId, region, subnet.getSubnetUuid());
		}
		for (Map.Entry<String, Subnet> entry : subnetMap.entrySet()) {
			subnetRepository.remove(entry.getValue().getId(), userId);
		}
//        subnetRepository.removeByVid(id, region, userId);
//        List<Subnet> subList = new ArrayList<Subnet>();
//        for (SubnetModel subnetModel : models) {
//            subnet = new Subnet();
//            BeanUtils.copyProperties(subnetModel, subnet);
//            subnet.setSubnetUuid(subnetModel.getSubnetUuid());
//            if (vpcMap.containsKey(subnetModel.getVpcUuid())) {
//                subnet.setNetworkId(vpcMap.get(subnetModel.getVpcUuid()));
//            }
//            subnet.setVpcUuid(subnetModel.getVpcUuid());
//            subnet.setMenderId(userId);
//            subnet.setGmtModify(new Date());
//            subnet.setCreatorId(userId);
//            subnet.setVendorId(id);
//            subnet.setRegionId(region);
//            subList.add(subnet);
//        }
//        if (subList.size() > 0) {
//            subnetRepository.batchSave(subList, subList.size() + 1);
//        }
	}

	/**
	 * 同步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 (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.getUuid(), cidrBlock);
		}
		for (CidrBlockModel model : models) {
			CidrBlock cidrBlock = new CidrBlock();
			if (cidrBlockMap.containsKey(model.getUuid())) {
				cidrBlock = cidrBlockMap.get(model.getUuid());
				BeanUtils.copyProperties(model, cidrBlock);
				cidrBlock.setMenderId(userId);
				cidrBlock.setRegionId(region);
				cidrBlockRepository.update(cidrBlock);
				cidrBlockMap.remove(model.getUuid());
				continue;
			}
			BeanUtils.copyProperties(model, cidrBlock);
			cidrBlock.setCreatorId(userId);
			cidrBlock.setVendorId(vendorId);
			cidrBlock.setRegionId(region);
			cidrBlockRepository.save(cidrBlock);
			cidrBlockMap.remove(model.getUuid());
		}
		for (Map.Entry<String, CidrBlock> entry : cidrBlockMap.entrySet()) {
			cidrBlockRepository.remove(entry.getValue().getId(), userId);
		}
	}

	private void syncVpc(List<VpcModel> models, Long vendorId, Long userId, String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			vpcRepository.deleteByVid(vendorId, region, userId);
			return;
		}
		List<Vpc> vpcs = vpcRepository.list(vendorId, region);
		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.setMenderId(userId);
				vpc.setRegionId(region);
				vpcRepository.update(vpc);
				vpcMap.remove(model.getVpcId());
				// 同步cidr
				syncCidr(model.getCidrBlockModels(), vendorId, userId, region, vpc.getVpcId());
				continue;
			}
			BeanUtils.copyProperties(model, vpc);
			vpc.setCreatorId(userId);
			vpc.setTenantId(0L);
			vpc.setProjectId(0L);
			vpc.setVendorId(vendorId);
			vpc.setRegionId(region);
			vpcRepository.save(vpc);
			vpcMap.remove(model.getVpcId());
			// 同步cidr
			syncCidr(model.getCidrBlockModels(), vendorId, userId, region, vpc.getVpcId());
		}
		for (Map.Entry<String, Vpc> entry : vpcMap.entrySet()) {
			vpcRepository.delete(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步云硬盘
	 *
	 * @param models
	 * @param vendor
	 * @param userId
	 * @param serverMap
	 * @throws Exception
	 */
	private void syncVolume(List<VolumeModel> models, CloudVendor vendor, Long userId, Map<String, Long> serverMap,
			String region) throws Exception {
		// 删除 脏数据
		volumeRepository.deleteRegionNull(vendor.getId());
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			volumeRepository.removeByVid(vendor.getId(), region, userId);
			return;
		}
		List<Volume> volumes = volumeRepository.listByVendorId(vendor.getId(), region);
		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.setMenderId(userId);
				volume.setGmtModify(new Date());
				volume.setRegionId(region);
				volume.setVendorType(vendor.getType());
				if (!StringUtils.isEmpty(model.getInstanceId())) {
					volume.setServerId(serverMap.get(model.getInstanceId()));
				}
				volumeRepository.update(volume);
				volumeMap.remove(volume.getVolumeUuid());
				continue;
			}
			BeanUtils.copyProperties(model, volume);
			volume.setCreatorId(userId);
			volume.setGmtCreate(new Date());
			volume.setVendorId(vendor.getId());
			volume.setRegionId(region);
			volume.setVendorType(vendor.getType());
			volume.setProjectId(0L);
			volume.setTenantId(0L);
			if (!StringUtils.isEmpty(model.getInstanceId())) {
				volume.setServerId(serverMap.get(model.getInstanceId()));
			}
			volumeRepository.save(volume);
			volumeMap.remove(volume.getVolumeUuid());
		}
		for (Map.Entry<String, Volume> entry : volumeMap.entrySet()) {
			volumeRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步NAT网关
	 *
	 * @param models
	 * @param vendor
	 * @param userId
	 * @throws Exception
	 */
	private void syncNatGateWay(List<NatGatewayModel> models, CloudVendor vendor, Long userId, Map<String, Long> vpcMap,
			Map<String, Subnet> subnetMap, Map<String, Long> networkInterfaceMap, String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			natGatewayRepository.removeByVid(vendor.getId(), region, userId);
			return;
		}
		List<NatGateway> natGateways = natGatewayRepository.listByVendorId(vendor.getId(), region);
		Map<String, NatGateway> natGatewayMap = Maps.newHashMap();
		for (NatGateway natGateway : natGateways) {
			natGatewayMap.put(natGateway.getUuid(), natGateway);
		}
		for (NatGatewayModel model : models) {
			NatGateway natGateway = new NatGateway();
			if (natGatewayMap.containsKey(model.getUuid())) {
				natGateway = natGatewayMap.get(model.getUuid());
				BeanUtils.copyProperties(model, natGateway);
				natGateway.setVpcId(vpcMap.get(natGateway.getVpcUuid()));
				natGateway.setSubnetId(subnetMap.get(natGateway.getSubnetUuid()).getId());
				natGateway.setNetworkInterfaceId(networkInterfaceMap.get(natGateway.getNetworkInterfaceUuid()));
				natGateway.setMenderId(userId);
				natGateway.setGmtModify(new Date());
				natGateway.setRegionId(region);
				natGatewayRepository.update(natGateway);
				natGatewayMap.remove(natGateway.getUuid());
				continue;
			}
			BeanUtils.copyProperties(model, natGateway);
			natGateway.setVpcId(vpcMap.get(natGateway.getVpcUuid()));
			natGateway.setSubnetId(subnetMap.get(natGateway.getSubnetUuid()).getId());
			natGateway.setNetworkInterfaceId(networkInterfaceMap.get(natGateway.getNetworkInterfaceUuid()));
			natGateway.setCreatorId(userId);
			natGateway.setVendorId(vendor.getId());
			natGateway.setRegionId(region);
			natGatewayRepository.save(natGateway);
			natGatewayMap.remove(natGateway.getUuid());
		}
		for (Map.Entry<String, NatGateway> entry : natGatewayMap.entrySet()) {
			natGatewayRepository.delete(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步快照
	 *
	 * @param models
	 * @param vendor
	 * @param userId
	 * @param volumeMap
	 * @param region
	 * @throws Exception
	 */
	private void syncSnapshot(List<SnapshotModel> models, CloudVendor vendor, Long userId, Map<String, Long> volumeMap,
			String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			snapshotRepository.removeByVid(vendor.getId(), region, userId);
			return;
		}
		List<Snapshot> snapshots = snapshotRepository.listByVid(vendor.getId(), region);
		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.setMenderId(userId);
				snapshot.setRegionId(region);
				snapshot.setVolumeId(volumeMap.get(model.getVolumeUuid()));
				snapshotRepository.update(snapshot);
				snapshotMap.remove(model.getSnapshotUuid());
				continue;
			}
			Snapshot snapshot = JSONObject.parseObject(JSONObject.toJSONString(model), Snapshot.class);
			snapshot.setVolumeId(volumeMap.get(model.getVolumeUuid()));
			snapshot.setRegionId(region);
			snapshot.preSave(userId, userId, vendor.getId(), null, 0L, 0L);
			snapshotRepository.save(snapshot);
		}
		for (Map.Entry<String, Snapshot> entry : snapshotMap.entrySet()) {
			snapshotRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步云主机
	 *
	 * @param models
	 * @param vendor
	 * @param userId
	 * @param groupMap
	 * @throws Exception
	 */
	private void syncServer(List<ServerModel> models, CloudVendor vendor, Long userId, Map<String, Long> groupMap,
			Region region, Map<String, Long> keyPairMap, Map<String, Image> imageMap, Map<String, Flavor> flavorMap,
			Map<String, VolumeModel> volumeSizeMap, Map<String, List<String>> ipMap) throws Exception {
		if (models == null) {
			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 (models.isEmpty()) {
			cloudServerRepository.removeByVid(vendor.getId(), region.getRegionId(), userId);
			// 删除资源表
			resourceRepository.removeByVidReg(vendor.getId(), region.getRegionId(), userId);
			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 = imageRepository.getByImageUuid(server.getImageUuid());
					if (null != image) {
						account = image.getDefaultUser();
					}
				}
				model.setAccount(account);
				model.setPassword(server.getPassword());
				BeanUtils.copyProperties(model, server);
				server.setMenderId(userId);
				server.setGmtModify(new Date());
				server.setGmtVmCreate(model.getGmtVmCreate());
				server.setRegionId(region.getRegionId());

				// ----------------------系统盘 数据盘 --------------------start
				Integer attchDiskSize = 0;
				List<VolumeModel> diskDevices = model.getDiskDevices();
				if (null != diskDevices && diskDevices.size() > 0) {
					for (VolumeModel volumeModel : diskDevices) {
						if ("/dev/xvda".equalsIgnoreCase(volumeModel.getDevice())) { // 系统盘
							server.setSystemDiskSize(volumeSizeMap.get(volumeModel.getVolumeUuid()).getSize());
							server.setSystemDiskCategory(volumeSizeMap.get(volumeModel.getVolumeUuid()).getCategory());
						} else {// 挂载盘
							attchDiskSize += volumeSizeMap.get(volumeModel.getVolumeUuid()).getSize();
						}
					}
				}
				Integer systemDiskSize = null == server.getSystemDiskSize() ? 0 : server.getSystemDiskSize();
				server.setSystemDiskSize(systemDiskSize);
				server.setDisk(server.getSystemDiskSize() + attchDiskSize);
				// ----------------------系统盘 数据盘 --------------------end

				server.setVendorType(vendor.getType());
				server.setIsTemplate(false);
				Flavor flavor = flavorMap.get(model.getFlavorUuid());
				if (null != flavor) {
					server.setCpu(flavor.getCpu());
					server.setMemory(flavor.getMemory());
				} else {
					server.setCpu(0);
					server.setMemory(BigDecimal.valueOf(0.0));
				}
				List<String> securityGroups = model.getSecurityGroups();
				if (null != securityGroups) {
					server.setSecurityGroupId(JSON.toJSONString(securityGroups));
				}
				// Image image = imageMap.get(model.getImageUuid());
				// if (null != image) {
				// server.setOsCategory(image.getOsCategory());
				// }
				server.setPrivateIps(JSON.toJSONString(ipMap.get(model.getInstanceId())));
				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);
				}
				serverMap.remove(model.getInstanceId());
				continue;
			}
			BeanUtils.copyProperties(model, server);
			List<String> securityGroups = model.getSecurityGroups();
			if (null != securityGroups) {
				server.setSecurityGroupId(JSON.toJSONString(securityGroups));
			}
			server.setCreatorId(userId);
			server.setGmtCreate(new Date());
			server.setVendorId(vendor.getId());
			server.setVendorType(vendor.getType());

			// ----------------------系统盘 数据盘 --------------------start
			Integer attchDiskSize = 0;
			List<VolumeModel> diskDevices = model.getDiskDevices();
			if (null != diskDevices && diskDevices.size() > 0) {
				for (VolumeModel volumeModel : diskDevices) {
					if ("/dev/xvda".equalsIgnoreCase(volumeModel.getDevice())) { // 系统盘
						server.setSystemDiskSize(volumeSizeMap.get(volumeModel.getVolumeUuid()).getSize());
						server.setSystemDiskCategory(volumeSizeMap.get(volumeModel.getVolumeUuid()).getCategory());
					} else {// 挂载盘
						attchDiskSize += volumeSizeMap.get(volumeModel.getVolumeUuid()).getSize();
					}
				}
			}
			Integer systemDiskSize = null == server.getSystemDiskSize() ? 0 : server.getSystemDiskSize();
			server.setSystemDiskSize(systemDiskSize);
			server.setDisk(server.getSystemDiskSize() + attchDiskSize);
			// ----------------------系统盘 数据盘 --------------------end

			server.setTenantId(0L);
			server.setProjectId(0L);
			server.setRegionId(region.getRegionId());
			server.setIsTemplate(false);
			server.setRecycle(false);
			Flavor flavor = flavorMap.get(model.getFlavorUuid());
			if (null != flavor) {
				server.setCpu(flavor.getCpu());
				server.setMemory(flavor.getMemory());
			} else {
				server.setCpu(0);
				server.setMemory(BigDecimal.valueOf(0.0));
			}
			server.setPrivateIps(JSON.toJSONString(ipMap.get(model.getInstanceId())));
			// Image image = imageMap.get(model.getImageUuid());
			// if (null != image) {
			// server.setOsCategory(image.getOsCategory());
			// }
			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);
			}
			serverMap.remove(model.getInstanceId());
		}
		for (Map.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);
			serverSgroupRepository.removeBySid(server.getId());
			serverKeypairRepository.removeBySid(server.getId());
		}
	}

	private void updateServerKeyPair(CloudServer server, Map<String, Long> keyPairMap) throws Exception {
		String keypairName = server.getKeypairName();
		if (null != keypairName && !"".equals(keypairName)) {
			List<String> keyPairList = JSON.parseArray(server.getKeypairName(), String.class);
			ServerKeypair serverKeypair = null;
			for (String keyName : keyPairList) {
				Long keyPairId = keyPairMap.get(keyName);
				serverKeypair = new ServerKeypair();
				serverKeypair.setKeypairId(keyPairId);
				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.setRegionId(region);
			resource.setMenderId(userId);
			resource.setAccurated(false);
			resource.setAuthed(false);
			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.setRegionId(region);
			resource.setPrivateIps(JSONObject.toJSONString(ips));
			resource.setOwnerId(userId);
			resource.setAccurated(false);
			resource.setAuthed(false);
			resourceRepository.save(resource);
			server.setResource(resource);
		}
	}

	/**
	 * 同步安全组
	 *
	 * @param models
	 * @param vendor
	 * @param userId
	 * @throws Exception
	 */
	private void syncSecurityGroup(List<SecurityGroupModel> models, CloudVendor vendor, Long userId, String region,
			Map<String, Long> vpcMap) throws Exception {
		// 当安全组为空时,删除数据库残留数据
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			securityGroupRepository.removeByVid(vendor.getId(), region, userId);
			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;
			if (groupMap.containsKey(model.getGroupUuid())) {
				group = groupMap.get(model.getGroupUuid());
				BeanUtils.copyProperties(model, group);
				group.setMenderId(userId);
				group.setRegionId(region);
				if (null != group.getVpcUuid()) {
					group.setVpcId(vpcMap.get(group.getVpcUuid()));
				}
				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());
				continue;
			}
			group = JSONObject.parseObject(JSONObject.toJSONString(model), SecurityGroup.class);
			BeanUtils.copyProperties(model, group);
			group.preSave(userId, userId, vendor.getId(), 0L, 0L);
			group.setRegionId(region);
			if (null != group.getVpcUuid()) {
				group.setVpcId(vpcMap.get(group.getVpcUuid()));
			}
			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.setMenderId(userId);
				securityGroupRule.setVendorId(vendor.getId());
				securityGroupRule.setGroupId(group.getId());
				securityGroupRule.setGroupUuid(group.getGroupUuid());
				securityGroupRule.setTenantId(0L);
				securityGroupRule.setProjectId(0L);
				securityGroupRuleRepository.save(securityGroupRule);
			}
		}
		// 删除不存在的安全组
		for (Map.Entry<String, SecurityGroup> entry : groupMap.entrySet()) {
			securityGroupRepository.remove(entry.getValue().getId(), userId);
		}
	}

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

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

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

	/**
	 * 同步弹性IP
	 *
	 * @param models
	 * @param vendorId
	 * @param userId
	 * @throws Exception
	 */
	private void syncElasticIp(List<ElasticIpModel> models, Long vendorId, Long userId, String region)
			throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			elasticIpRepository.removeByVid(vendorId, userId, region);
			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.setTagsJson(JSONObject.toJSONString(model.getTags()));
				elasticIp.setMenderId(userId);
				elasticIp.setVendorId(vendorId);
				elasticIp.setGmtModify(new Date());
				elasticIp.setRegionId(region);
				elasticIpRepository.update(elasticIp);
				elasticIpMap.remove(elasticIp.getElasticIpUuid());
				continue;
			}
			BeanUtils.copyProperties(model, elasticIp);
			elasticIp.setTagsJson(JSONObject.toJSONString(model.getTags()));
			elasticIp.setCreatorId(userId);
			elasticIp.setVendorId(vendorId);
			elasticIp.setGmtCreate(new Date());
			elasticIp.setRegionId(region);
			elasticIpRepository.save(elasticIp);
			elasticIpMap.remove(model.getElasticIpUuid());
		}
		for (Map.Entry<String, ElasticIp> entry : elasticIpMap.entrySet()) {
			elasticIpRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步负载均衡
	 *
	 * @param models
	 * @param vendorId
	 * @param userId
	 * @throws Exception
	 */
	private void syncLoadBalancer(List<LbModel> models, Map<String, Long> vpcMap, Long vendorId, Long userId,
			String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			loadBalancerRepository.removeByVid(vendorId, region, userId);
			return;
		}
		List<LoadBalancer> balancers = loadBalancerRepository.listByVid(vendorId, region);
		Map<String, LoadBalancer> balancerMap = Maps.newHashMap();
		for (LoadBalancer balancer : balancers) {
			balancerMap.put(balancer.getLbUuid(), balancer);
		}
		for (LbModel model : models) {
			LoadBalancer balancer = new LoadBalancer();
			if (balancerMap.containsKey(model.getLbUuid())) {
				balancer = balancerMap.get(model.getLbUuid());
				BeanUtils.copyProperties(model, balancer);
				balancer.setAvailabilityZones(model.getAvailabilityZones().toJSONString());
				balancer.setSecurityGroups(JSONObject.toJSONString(model.getSecurityGroups()));
				balancer.setVpcId(vpcMap.get(balancer.getVpcUuid()));
				balancer.setMenderId(userId);
				balancer.setVendorId(vendorId);
				balancer.setGmtModify(new Date());
				balancer.setRegion(region);
				loadBalancerRepository.update(balancer);
				balancerMap.remove(balancer.getLbUuid());
				continue;
			}
			BeanUtils.copyProperties(model, balancer);
			balancer.setAvailabilityZones(model.getAvailabilityZones().toJSONString());
			balancer.setSecurityGroups(JSONObject.toJSONString(model.getSecurityGroups()));
			balancer.setVpcId(vpcMap.get(balancer.getVpcUuid()));
			balancer.setCreatorId(userId);
			balancer.setVendorId(vendorId);
			balancer.setGmtCreate(new Date());
			balancer.setRegion(region);
			loadBalancerRepository.save(balancer);
			balancerMap.remove(balancer.getLbUuid());
		}
		for (Map.Entry<String, LoadBalancer> entry : balancerMap.entrySet()) {
			loadBalancerRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步目标群组
	 *
	 * @param models
	 * @param vendorId
	 * @param userId
	 * @throws Exception
	 */
	private void syncLbTargetGroup(List<LbTargetGroupModel> models, Long vendorId, Long userId, String region)
			throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			lbTargetGroupRepository.removeByVid(vendorId, region, userId);
			return;
		}
		List<LbTargetGroup> lbTargetGroups = lbTargetGroupRepository.listByVid(vendorId, region);
		Map<String, LbTargetGroup> targetGroupMap = Maps.newHashMap();
		for (LbTargetGroup lbTargetGroup : lbTargetGroups) {
			targetGroupMap.put(lbTargetGroup.getUuid(), lbTargetGroup);
		}
		for (LbTargetGroupModel model : models) {
			LbTargetGroup lbTargetGroup = new LbTargetGroup();
			if (targetGroupMap.containsKey(model.getUuid())) {
				lbTargetGroup = targetGroupMap.get(model.getUuid());
				BeanUtils.copyProperties(model, lbTargetGroup);
				lbTargetGroup.setMenderId(userId);
				lbTargetGroup.setVendorId(vendorId);
				lbTargetGroup.setGmtModify(new Date());
				lbTargetGroup.setRegionId(region);
				lbTargetGroupRepository.update(lbTargetGroup);
				targetGroupMap.remove(lbTargetGroup.getUuid());
				continue;
			}
			BeanUtils.copyProperties(model, lbTargetGroup);
			lbTargetGroup.setCreatorId(userId);
			lbTargetGroup.setVendorId(vendorId);
			lbTargetGroup.setGmtCreate(new Date());
			lbTargetGroup.setRegionId(region);
			lbTargetGroupRepository.save(lbTargetGroup);
			targetGroupMap.remove(lbTargetGroup.getUuid());
		}
		for (Map.Entry<String, LbTargetGroup> entry : targetGroupMap.entrySet()) {
			lbTargetGroupRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步群组目标
	 *
	 * @param models
	 * @param vendorId
	 * @param userId
	 * @throws Exception
	 */
	private void syncLbTarget(List<LbTargetModel> models, Map<String, Long> tgMap, Long vendorId, Long userId,
			String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			lbTargetRepository.removeByVid(vendorId, region, userId);
			return;
		}
		List<LbTarget> lbTargets = lbTargetRepository.listByVid(vendorId, region);
		Map<String, LbTarget> targetMap = Maps.newHashMap();
		for (LbTarget lbTarget : lbTargets) {
			targetMap.put(lbTarget.getTgUuid() + lbTarget.getUuid(), lbTarget);
		}
		for (LbTargetModel model : models) {
			LbTarget lbTarget = new LbTarget();
			if (targetMap.containsKey(model.getTgUuid() + model.getUuid())) {
				lbTarget = targetMap.get(model.getTgUuid() + model.getUuid());
				BeanUtils.copyProperties(model, lbTarget);
				lbTarget.setTgId(tgMap.get(lbTarget.getTgUuid()));
				lbTarget.setMenderId(userId);
				lbTarget.setVendorId(vendorId);
				lbTarget.setGmtModify(new Date());
				lbTarget.setRegionId(region);
				lbTargetRepository.update(lbTarget);
				targetMap.remove(lbTarget.getTgUuid() + lbTarget.getUuid());
				continue;
			}
			BeanUtils.copyProperties(model, lbTarget);
			lbTarget.setTgId(tgMap.get(lbTarget.getTgUuid()));
			lbTarget.setCreatorId(userId);
			lbTarget.setVendorId(vendorId);
			lbTarget.setGmtCreate(new Date());
			lbTarget.setRegionId(region);
			lbTargetRepository.save(lbTarget);
			targetMap.remove(lbTarget.getTgUuid() + lbTarget.getUuid());
		}
		for (Map.Entry<String, LbTarget> entry : targetMap.entrySet()) {
			lbTargetRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步路由表
	 *
	 * @param models
	 * @param vendorId
	 * @param userId
	 * @throws Exception
	 */
	private void syncRouteTable(Map<String, Long> vpcMap, List<RouteTableModel> models, Long vendorId, Long userId,
			String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			routeRepository.removeByVid(vendorId, region, userId);
			routeTableAssociationRepository.removeByVid(vendorId, region, userId);
			routeTableRepository.removeByVid(vendorId, region, userId);
			return;
		}
		List<RouteTable> routeTables = routeTableRepository.listByVid(vendorId, region);
		Map<String, RouteTable> routeTablesMap = Maps.newHashMap();
		for (RouteTable routeTable : routeTables) {
			routeTablesMap.put(routeTable.getUuid(), routeTable);
		}
		for (RouteTableModel model : models) {
			RouteTable routeTable = new RouteTable();
			if (routeTablesMap.containsKey(model.getUuid())) {
				routeTable = routeTablesMap.get(model.getUuid());
				BeanUtils.copyProperties(model, routeTable);
				routeTable.setVpcId(vpcMap.get(model.getVpcUuid()));
				routeTable.setPropagatingVgws(JSONObject.toJSONString(model.getPropagatingVgws()));
				routeTable.setMenderId(userId);
				routeTable.setGmtModify(new Date());
				routeTable.setRegionId(region);
				routeTableRepository.update(routeTable);
				routeTablesMap.remove(routeTable.getUuid());
			} else {
				BeanUtils.copyProperties(model, routeTable);
				routeTable.setVpcId(vpcMap.get(model.getVpcUuid()));
				routeTable.setPropagatingVgws(JSONObject.toJSONString(model.getPropagatingVgws()));
				routeTable.setCreatorId(userId);
				routeTable.setGmtCreate(new Date());
				routeTable.setVendorId(vendorId);
				routeTable.setRegionId(region);
				routeTableRepository.save(routeTable);
				routeTablesMap.remove(model.getUuid());
			}

			// 同步路由关系
			List<RouteTableAssociationModel> associationModels = model.getAssociations();
			if (associationModels == null) {
				return;
			}
			if (associationModels.isEmpty()) {
				routeTableAssociationRepository.removeByVid(vendorId, region, userId, routeTable.getId());
			} else {
				List<RouteTableAssociation> associations = routeTableAssociationRepository.listByVid(vendorId, region,
						routeTable.getId());
				Map<String, RouteTableAssociation> associationMap = Maps.newHashMap();
				for (RouteTableAssociation association : associations) {
					associationMap.put(association.getUuid(), association);
				}
				for (RouteTableAssociationModel associationModel : associationModels) {
					RouteTableAssociation association = new RouteTableAssociation();
					if (associationMap.containsKey(associationModel.getUuid())) {
						association = associationMap.get(associationModel.getUuid());
						BeanUtils.copyProperties(associationModel, association);
						association.setRouteTableId(routeTable.getId());
						association.setMenderId(userId);
						association.setGmtModify(new Date());
						association.setRegionId(region);
						routeTableAssociationRepository.update(association);
						associationMap.remove(association.getUuid());
					} else {
						BeanUtils.copyProperties(associationModel, association);
						association.setRouteTableId(routeTable.getId());
						association.setCreatorId(userId);
						association.setGmtCreate(new Date());
						association.setVendorId(vendorId);
						association.setRegionId(region);
						routeTableAssociationRepository.save(association);
						associationMap.remove(associationModel.getUuid());
					}
				}
				for (Map.Entry<String, RouteTableAssociation> entry : associationMap.entrySet()) {
					routeTableAssociationRepository.remove(entry.getValue().getId(), userId);
				}
			}

			// 同步路由
			List<RouteModel> routeModels = model.getRouteModels();
			if (routeModels == null) {
				return;
			}
			if (routeModels.isEmpty()) {
				routeRepository.removeByVid(vendorId, region, userId, routeTable.getId());
			} else {
				List<Route> routes = routeRepository.listByVid(vendorId, region, routeTable.getId());
				Map<String, Route> routeMap = Maps.newHashMap();
				for (Route route : routes) {
					routeMap.put(route.getDestination(), route);
				}
				for (RouteModel routeModel : routeModels) {
					Route route = new Route();
					if (routeMap.containsKey(routeModel.getDestination())) {
						route = routeMap.get(routeModel.getDestination());
						BeanUtils.copyProperties(routeModel, route);
						route.setRouteTableId(routeTable.getId());
						route.setRouteTableUuid(routeTable.getUuid());
						route.setMenderId(userId);
						route.setGmtModify(new Date());
						route.setRegionId(region);
						routeRepository.update(route);
						routeMap.remove(routeModel.getDestination());
					} else {
						BeanUtils.copyProperties(routeModel, route);
						route.setRouteTableId(routeTable.getId());
						route.setRouteTableUuid(routeTable.getUuid());
						route.setCreatorId(userId);
						route.setGmtCreate(new Date());
						route.setVendorId(vendorId);
						route.setRegionId(region);
						routeRepository.save(route);
						routeMap.remove(routeModel.getDestination());
					}
				}
				for (Map.Entry<String, Route> entry : routeMap.entrySet()) {
					routeRepository.remove(entry.getValue().getId(), userId);
				}
			}
		}
		for (Map.Entry<String, RouteTable> entry : routeTablesMap.entrySet()) {
			routeTableRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步互联网网关
	 *
	 * @param models
	 * @param vendorId
	 * @param userId
	 * @throws Exception
	 */
	private void syncInternetGateway(List<InternetGatewayModel> models, Long vendorId, Long userId, String region)
			throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			internetGatewayRepository.removeByVid(vendorId, userId, region);
			return;
		}
		List<InternetGateway> gatewayList = internetGatewayRepository.listByVid(vendorId, region);
		Map<String, InternetGateway> gatewayMap = Maps.newHashMap();
		for (InternetGateway gateway : gatewayList) {
			gatewayMap.put(gateway.getInternetGatewayUuid(), gateway);
		}
		for (InternetGatewayModel model : models) {
			InternetGateway gateway = new InternetGateway();
			if (gatewayMap.containsKey(model.getInternetGatewayUuid())) {
				gateway = gatewayMap.get(model.getInternetGatewayUuid());
				BeanUtils.copyProperties(model, gateway);
				gateway.setMenderId(userId);
				gateway.setVendorId(vendorId);
				gateway.setGmtModify(new Date());
				gateway.setRegionId(region);
				internetGatewayRepository.update(gateway);
				gatewayMap.remove(gateway.getInternetGatewayUuid());
				continue;
			}
			BeanUtils.copyProperties(model, gateway);
			gateway.setCreatorId(userId);
			gateway.setVendorId(vendorId);
			gateway.setGmtCreate(new Date());
			gateway.setRegionId(region);
			internetGatewayRepository.save(gateway);
			gatewayMap.remove(model.getInternetGatewayUuid());
		}
		for (Map.Entry<String, InternetGateway> entry : gatewayMap.entrySet()) {
			internetGatewayRepository.remove(entry.getValue().getId(), userId);
		}
	}

	/**
	 * 同步监听器
	 *
	 * @param models
	 * @param vendorId
	 * @param userId
	 * @throws Exception
	 */
	private void syncLbListener(List<LbListenerModel> models, Map<String, Long> balancerMap, Long vendorId, Long userId,
			String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			lbListenerRepository.removeByVid(vendorId, userId, region);
			return;
		}
		List<LbListener> listenerList = lbListenerRepository.listByVid(vendorId, region);
		Map<String, LbListener> listenerMap = Maps.newHashMap();
		for (LbListener lbListener : listenerList) {
			listenerMap.put(lbListener.getListenerUuid(), lbListener);
		}
		for (LbListenerModel model : models) {
			LbListener lbListener = new LbListener();
			if (listenerMap.containsKey(model.getListenerUuid())) {
				lbListener = listenerMap.get(model.getListenerUuid());
				BeanUtils.copyProperties(model, lbListener);
				lbListener.setLbId(balancerMap.get(lbListener.getLbUuid()));
				lbListener.setCertificates(
						model.getCertificates() != null ? model.getCertificates().toJSONString() : null);
				lbListener.setAlpnPolicy(model.getAlpnPolicy() != null ? model.getAlpnPolicy().toJSONString() : null);
				lbListener.setDefaultActions(model.getDefaultActions().toJSONString());
				lbListener.setVendorId(vendorId);
				lbListener.setGmtModify(new Date());
				lbListener.setRegionId(region);
				lbListenerRepository.update(lbListener);
				listenerMap.remove(model.getListenerUuid());
				continue;
			}
			BeanUtils.copyProperties(model, lbListener);
			lbListener.setLbId(balancerMap.get(lbListener.getLbUuid()));
			lbListener.setCertificates(model.getCertificates() != null ? model.getCertificates().toJSONString() : null);
			lbListener.setAlpnPolicy(model.getAlpnPolicy() != null ? model.getAlpnPolicy().toJSONString() : null);
			lbListener.setDefaultActions(model.getDefaultActions().toJSONString());
			lbListener.setVendorId(vendorId);
			lbListener.setRegionId(region);
			lbListenerRepository.save(lbListener);
			listenerMap.remove(model.getListenerUuid());
		}
		for (Map.Entry<String, LbListener> entry : listenerMap.entrySet()) {
			lbListenerRepository.remove(entry.getValue().getId(), userId);
		}
	}

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

	/**
	 * 同步镜像
	 *
	 * @param models
	 * @param vendor
	 * @param userId
	 * @throws Exception
	 */
	private void syncImage(List<ImageModel> models, CloudVendor vendor, Long userId, String region) throws Exception {
		if (models == null) {
			return;
		}
		if (models.isEmpty()) {
			imageRepository.removeByVid(vendor.getId(), region, userId);
			return;
		}
		List<Image> images = imageRepository.listByVendorId(vendor.getId(), region);
		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.setRegionId(region);
				image.setVendorType(vendor.getType());
				image.setGmtModify(new Date());
				imageRepository.update(image);
				imageMap.remove(image.getImageUuid());
				continue;
			}
			BeanUtils.copyProperties(model, image);
			image.setCreatorId(userId);
			image.setVendorId(vendor.getId());
			image.setVendorType(vendor.getType());
			image.setTenantId(0L);
			image.setProjectId(0L);
			image.setRegionId(region);
			image.setCatalog("VM");
			imageRepository.save(image);
			imageMap.remove(image.getImageUuid());
		}
		for (Map.Entry<String, Image> entry : imageMap.entrySet()) {
			imageRepository.remove(entry.getValue().getId(), userId);
		}
	}

	public BocloudResult syncAwsCost(CloudVendor vendor) throws Exception {
		try {
			logger.info("Starting sync aws cloud cost......");
			BocloudResult result = locationDriver.syncAwsCost(vendor.getUuid());
			if (result.isFailed()) {
				logger.info("sync aws cloud cost failed:" + result.getMessage());
				return new BocloudResult(false, "AWS成本同步失败" + result.getMessage());
			}
			AwsSyncModel awsSyncModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
					AwsSyncModel.class);
			List<CloudCostModel> models = awsSyncModel.getCloudCostModels();

			List<CloudCost> cloudCostList = cloudCostRepository.listByVid(vendor.getId());
			Map<String, CloudCost> costMap = Maps.newHashMap();
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for (CloudCost cloudCost : cloudCostList) {
				costMap.put(cloudCost.getGroupUuid() + format.format(cloudCost.getStart()) + cloudCost.getDimension()
						+ cloudCost.getGranularity() + cloudCost.getMetrics(), cloudCost);
			}
			for (CloudCostModel model : models) {
				CloudCost cloudCost = new CloudCost();
				if (costMap.containsKey(model.getGroupUuid() + format.format(model.getStart()) + model.getDimension()
						+ model.getGranularity() + model.getMetrics())) {
					continue;
				}
				BeanUtils.copyProperties(model, cloudCost);
				cloudCost.setVendorId(vendor.getId());
				cloudCostRepository.save(cloudCost);
				costMap.remove(model.getGroupUuid() + model.getStart() + model.getDimension() + model.getGranularity()
						+ model.getMetrics());
			}
			logger.info("End sync aws cloud cost......");
			return new BocloudResult(true, "AWS成本同步成功");
		} catch (Exception e) {
			logger.error("Get error message：{}", e);
			return new BocloudResult(false, "AWS成本同步失败:" + e.getMessage());
		}
	}

	public BocloudResult syncAwsLB(CloudVendor vendor, RequestContext context) throws Exception {
		try {
			Long userId = context.getTarget();
			List<Region> regions = regionRepository.list(vendor.getId());
			for (Region region : regions) {
				BocloudResult result = locationDriver.syncAwsLoadBalancer(vendor.getUuid(), region.getRegionId());
				AwsSyncModel model = (AwsSyncModel) result.getData();
				// 同步vpc
				logger.info("Starting sync vpc......");
				this.syncVpc(model.getVpcModels(), vendor.getId(), userId, region.getRegionId());
				logger.info("End sync vpc......");
				List<Vpc> list = vpcRepository.list(vendor.getId(), region.getRegionId());
				Map<String, Long> vpcMap = Maps.newHashMap();
				for (Vpc vpc : list) {
					vpcMap.put(vpc.getVpcId(), vpc.getId());
				}
				// 同步负载均衡
				logger.info("Starting sync lb......");
				this.syncLoadBalancer(model.getLbModels(), vpcMap, vendor.getId(), userId, region.getRegionId());
				List<LoadBalancer> balancers = loadBalancerRepository.listByVid(vendor.getId(), region.getRegionId());
				Map<String, Long> balancerMap = Maps.newHashMap();
				for (LoadBalancer balancer : balancers) {
					balancerMap.put(balancer.getLbUuid(), balancer.getId());
				}
				logger.info("End sync lb......");
				// 同步目标群组
				logger.info("Starting sync lb target group......");
				this.syncLbTargetGroup(model.getLbTargetGroupModels(), vendor.getId(), userId, region.getRegionId());
				List<LbTargetGroup> targetGroups = lbTargetGroupRepository.listByVid(vendor.getId(),
						region.getRegionId());
				Map<String, Long> tgMap = Maps.newHashMap();
				for (LbTargetGroup group : targetGroups) {
					tgMap.put(group.getUuid(), group.getId());
				}
				logger.info("End sync lb target group......");
				// 同步群组目标
				logger.info("Starting sync lb target......");
				this.syncLbTarget(model.getLbTargetModels(), tgMap, vendor.getId(), userId, region.getRegionId());
				logger.info("End sync lb target......");
				// 同步侦听器
				logger.info("Starting sync listener......");
				this.syncLbListener(model.getLbListenerModels(), balancerMap, vendor.getId(), userId,
						region.getRegionId());
				logger.info("End sync lb listener......");
			}

			return new BocloudResult(true, "AWS负载均衡同步成功");
		} catch (Exception e) {
			logger.error("Get error message：{}", e);
			return new BocloudResult(false, "AWS负载均衡同步失败:" + 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

	}

}
