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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.common.FlavorDriver;
import com.bocloud.cmp.driver.common.LocationDriver;
import com.bocloud.cmp.driver.compute.ServerDriver;
import com.bocloud.cmp.driver.network.NetworkDriver;
import com.bocloud.cmp.driver.network.PortDriver;
import com.bocloud.cmp.driver.network.SubnetDriver;
import com.bocloud.cmp.driver.storage.StorageDriver;
import com.bocloud.cmp.entity.enums.ModuleCode;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.entity.enums.ServerAssetCategory;
import com.bocloud.cmp.model.ClusterModel;
import com.bocloud.cmp.model.FlavorModel;
import com.bocloud.cmp.model.HmcHostModel;
import com.bocloud.cmp.model.HostModel;
import com.bocloud.cmp.model.ImageModel;
import com.bocloud.cmp.model.NetworkModel;
import com.bocloud.cmp.model.PortFixedIpModel;
import com.bocloud.cmp.model.PortModel;
import com.bocloud.cmp.model.PowervcSyncModel;
import com.bocloud.cmp.model.SanFabricModel;
import com.bocloud.cmp.model.ServerModel;
import com.bocloud.cmp.model.ServerVolumeModel;
import com.bocloud.cmp.model.StorageModel;
import com.bocloud.cmp.model.SubnetModel;
import com.bocloud.cmp.model.VolumeModel;
import com.bocloud.cmp.model.VolumePoolModel;
import com.bocloud.cmp.model.VolumeTemplateModel;
import com.bocloud.cmp.model.powervc.NetworkSeaAdaterModel;
import com.bocloud.cmp.model.powervc.PowervcConstant;
import com.bocloud.cmp.provider.utils.IPAddress;
import com.bocloud.common.enums.BoCloudService;
import com.bocloud.common.enums.ResourceCatalog;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.Pager;
import com.bocloud.common.utils.IDFactory;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Cluster;
import com.bocloud.ims.entity.resource.Flavor;
import com.bocloud.ims.entity.resource.FlavorExtraSpecs;
import com.bocloud.ims.entity.resource.Image;
import com.bocloud.ims.entity.resource.ImageVolume;
import com.bocloud.ims.entity.resource.Ip;
import com.bocloud.ims.entity.resource.IpPool;
import com.bocloud.ims.entity.resource.Network;
import com.bocloud.ims.entity.resource.Port;
import com.bocloud.ims.entity.resource.PortFixedIp;
import com.bocloud.ims.entity.resource.SanFabric;
import com.bocloud.ims.entity.resource.Server;
import com.bocloud.ims.entity.resource.ServerConfig;
import com.bocloud.ims.entity.resource.ServerVolume;
import com.bocloud.ims.entity.resource.Storage;
import com.bocloud.ims.entity.resource.Subnet;
import com.bocloud.ims.entity.resource.Volume;
import com.bocloud.ims.entity.resource.VolumePool;
import com.bocloud.ims.entity.resource.VolumeTemplate;
import com.bocloud.ims.entity.resource.powervc.HostSeaAdapter;
import com.bocloud.ims.entity.resource.powervc.NetworkSeaAdapter;
import com.bocloud.ims.entity.resource.powervc.PowervcHmc;
import com.bocloud.ims.entity.resource.powervc.PowervcHmcServer;
import com.bocloud.ims.repository.powervc.HostSeaRepository;
import com.bocloud.ims.repository.powervc.NetworkSeaRepository;
import com.bocloud.ims.repository.powervc.PowervcHmcRepository;
import com.bocloud.ims.repository.powervc.PowervcHmcServerRepository;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.ClusterRepository;
import com.bocloud.ims.repository.resource.FlavorExtraSpecsRepository;
import com.bocloud.ims.repository.resource.FlavorRepository;
import com.bocloud.ims.repository.resource.ImageRepository;
import com.bocloud.ims.repository.resource.ImageVolumeRepository;
import com.bocloud.ims.repository.resource.IpPoolRepository;
import com.bocloud.ims.repository.resource.IpRepository;
import com.bocloud.ims.repository.resource.NetworkRepository;
import com.bocloud.ims.repository.resource.PortFixedIpRepository;
import com.bocloud.ims.repository.resource.PortRepository;
import com.bocloud.ims.repository.resource.ResourceRepository;
import com.bocloud.ims.repository.resource.SanFabricRepository;
import com.bocloud.ims.repository.resource.ServerConfigRepository;
import com.bocloud.ims.repository.resource.ServerRepository;
import com.bocloud.ims.repository.resource.ServerVolumeRepository;
import com.bocloud.ims.repository.resource.StorageRepository;
import com.bocloud.ims.repository.resource.SubnetRepository;
import com.bocloud.ims.repository.resource.VolumePoolRepository;
import com.bocloud.ims.repository.resource.VolumeRepository;
import com.bocloud.ims.repository.resource.VolumeTemplateRepository;
import com.bocloud.ims.service.model.cmdb.CmdbInfo;
import com.bocloud.ims.service.model.cmdb.CmdbModel;
import com.bocloud.ims.service.model.cmdb.CmdbRelation;
import com.bocloud.ims.service.transporter.ResourceTransporter;
import com.bocloud.ims.service.utils.CmdbInfoConvertor;

/**
 * cube同步工具类
 *
 * @author luyanchao
 * @since 2018/12/6 16:48
 */
@Component
public class PowervcTransporter implements ResourceTransporter {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private final CloudVendorRepository cloudVendorRepository;
	private final PowervcHmcRepository powervcHmcRepository;
	private final PowervcHmcServerRepository powervcHmcServerRepository;
	private final ServerRepository serverRepository;
	private final HostSeaRepository hostSeaRepository;
	private final ServerConfigRepository serverConfigRepository;
	private final CloudServerRepository cloudServerRepository;
	private final ServerVolumeRepository serverVolumeRepository;
	private final StorageRepository storageRepository;
	private final SanFabricRepository sanFabricRepository;
	private final VolumeTemplateRepository volumeTemplateRepository;
	private final VolumeRepository volumeRepository;
	private final NetworkRepository networkRepository;
	private final NetworkSeaRepository networkSeaRepository;
	private final SubnetRepository subnetRepository;
	private final ImageRepository imageRepository;
	private final FlavorRepository flavorRepository;
	private final IpPoolRepository ipPoolRepository;
	private final IpRepository ipRepository;
	private final PortRepository portRepository;
	private final PortFixedIpRepository portFixedIpRepository;
	private final FlavorExtraSpecsRepository flavorExtraSpecsRepository;
	private final ClusterRepository clusterRepository;
	private final VolumePoolRepository volumePoolRepository;
	private final ImageVolumeRepository imageVolumeRepository;
	private final ResourceRepository resourceRepository;
	private final ServerDriver serverDriver;
	private final StorageDriver storageDriver;
	private final NetworkDriver networkDriver;
	private final SubnetDriver subnetDriver;
	private final PortDriver portDriver;
	private final FlavorDriver flavorDriver;
	private final LocationDriver locationDriver;
	private final AmqpTemplate amqpTemplate;

	@Autowired
	public PowervcTransporter(CloudVendorRepository cloudVendorRepository, PowervcHmcRepository powervcHmcRepository,
			PowervcHmcServerRepository powervcHmcServerRepository, ServerRepository serverRepository,
			HostSeaRepository hostSeaRepository, ServerConfigRepository serverConfigRepository,
			CloudServerRepository cloudServerRepository, ServerVolumeRepository serverVolumeRepository,
			StorageRepository storageRepository, SanFabricRepository sanFabricRepository,
			VolumeTemplateRepository volumeTemplateRepository, VolumeRepository volumeRepository,
			NetworkRepository networkRepository, NetworkSeaRepository networkSeaRepository,
			SubnetRepository subnetRepository, ImageRepository imageRepository, FlavorRepository flavorRepository,
			IpPoolRepository ipPoolRepository, IpRepository ipRepository, PortRepository portRepository,
			PortFixedIpRepository portFixedIpRepository, FlavorExtraSpecsRepository flavorExtraSpecsRepository,
			ClusterRepository clusterRepository, VolumePoolRepository volumePoolRepository,
			ImageVolumeRepository imageVolumeRepository, ResourceRepository resourceRepository,
			ServerDriver serverDriver, StorageDriver storageDriver, NetworkDriver networkDriver,
			SubnetDriver subnetDriver, PortDriver portDriver, FlavorDriver flavorDriver, AmqpTemplate amqpTemplate, LocationDriver locationDriver) {
		this.locationDriver = locationDriver;
		this.cloudVendorRepository = cloudVendorRepository;
		this.powervcHmcRepository = powervcHmcRepository;
		this.powervcHmcServerRepository = powervcHmcServerRepository;
		this.serverRepository = serverRepository;
		this.hostSeaRepository = hostSeaRepository;
		this.serverConfigRepository = serverConfigRepository;
		this.cloudServerRepository = cloudServerRepository;
		this.serverVolumeRepository = serverVolumeRepository;
		this.storageRepository = storageRepository;
		this.sanFabricRepository = sanFabricRepository;
		this.volumeTemplateRepository = volumeTemplateRepository;
		this.volumeRepository = volumeRepository;
		this.networkRepository = networkRepository;
		this.networkSeaRepository = networkSeaRepository;
		this.subnetRepository = subnetRepository;
		this.imageRepository = imageRepository;
		this.flavorRepository = flavorRepository;
		this.ipPoolRepository = ipPoolRepository;
		this.ipRepository = ipRepository;
		this.portRepository = portRepository;
		this.portFixedIpRepository = portFixedIpRepository;
		this.flavorExtraSpecsRepository = flavorExtraSpecsRepository;
		this.clusterRepository = clusterRepository;
		this.volumePoolRepository = volumePoolRepository;
		this.imageVolumeRepository = imageVolumeRepository;
		this.resourceRepository = resourceRepository;
		this.serverDriver = serverDriver;
		this.storageDriver = storageDriver;
		this.networkDriver = networkDriver;
		this.subnetDriver = subnetDriver;
		this.portDriver = portDriver;
		this.flavorDriver = flavorDriver;
		this.amqpTemplate = amqpTemplate;
	}

	private void saveCmdb(long userId, List<CmdbInfo> data) {
		CmdbModel cmdbModel = new CmdbModel();
		cmdbModel.setUuid(IDFactory.instance().uuid());
		cmdbModel.setServiceName(BoCloudService.IMS.name());
		cmdbModel.setManagerId(userId);
		cmdbModel.setData(data);
		amqpTemplate.convertAndSend("cmdb.message.queue", JSONObject.parseObject(JSONObject.toJSONString(cmdbModel)));
		logger.debug("发送CMDB数据：" + JSON.toJSONString(cmdbModel));
	}

	@Transactional(rollbackFor = Throwable.class)
	@Override
	public BocloudResult transport(CloudVendor vendor, Long userId) {
		
		BocloudResult bocloudResult = this.locationDriver.sync(vendor.getUuid());
        if(bocloudResult.isFailed()) {
        	return bocloudResult;
        }
        Assert.notNull(bocloudResult.getData(), "数据同步异常！");
        Long vendorId = vendor.getId();
		
		// 先把平台的数据同步到cmdb
		logger.info("开始将平台数据同步到CMDB");
		saveCmdb(userId, Collections.singletonList(CmdbInfoConvertor.getInfo(vendor, null, null)));
		// 开始执行同步
		PowervcSyncModel syncModel = (PowervcSyncModel) bocloudResult.getData();
		// 同步存储服务器
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步存储服务器");
		syncStorage(vendor, syncModel.getStorages(), userId);
		// 同步存储卷模板
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步存储卷模板");
		syncVolumeTemplate(vendor, syncModel.getTemplates(), userId);
		// 同步Hmc连接
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步HMC链接");
		syncHmc(vendor, syncModel.getHmcs(), userId);
		// 同步物理主机
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步主机");
		syncServer(vendor, syncModel.getHypervisors(), userId);
		// 同步Sea
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步主机SEA");
		syncSea(vendor, JSONArray.parseArray(JSONObject.toJSONString(syncModel.getHostSeas()), HostSeaAdapter.class),
				userId);
		// 同步物理主机组
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步主机组");
		syncCluster(vendor, syncModel.getClusters(), userId);
		// 同步配置
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步规格");
		syncFlavor(vendor, syncModel.getFlavors(), userId);
		// 同步云主机
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步云主机");
		syncCloudServer(vendor, syncModel.getServers(), userId);
		// 同步卷
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步存储卷");
		syncVolume(vendor, syncModel.getVolumes(), userId);
		// 同步镜像
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步映像");
		syncImage(vendor, syncModel.getImages(), userId);
		// 同步网络和子网
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步网络");
		syncNetwork(vendor, syncModel.getNetworks(), userId);
		// 同步网络和子网
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步网络Sea");
		syncNetworkSea(vendor, syncModel.getNetworkSeas(), userId);
		// 同步Port
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步端口");
		syncPort(vendor, syncModel.getPorts(), userId);
		// 同步已用ip
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步Ip");
		List<PortFixedIpModel> ips = new ArrayList<>();
		if (syncModel.getPorts() != null) {
			for (PortModel port : syncModel.getPorts()) {
				if (port.getPortFixedIps() != null) {
					ips.addAll(port.getPortFixedIps());
				}
			}
		}
		syncIp(vendor, ips, userId);
		// 同步光纤交换机
		logger.info("Powervc平台[" + vendor.getName() + "]：开始同步交换机");
		syncSanFabircs(vendor, syncModel.getFabrics(), userId);

		return new BocloudResult(true, "云平台【 " + vendor.getName() + "】同步任务结果:同步成功");
	}

	/**
	 * 同步一个平台下的所有Hmc
	 *
	 * @param vendor    平台
	 * @param hmcModals hmcModals
	 * @param userId    用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncHmc(CloudVendor vendor, List<HmcHostModel> hmcModals, long userId) {
		// 该平台没有任何Server则直接从数据库中删除该平台所有Hmc
		if (hmcModals == null || hmcModals.size() == 0) {
			List<PowervcHmc> hmcs = powervcHmcRepository.listByVendor(vendor.getId());
			for (PowervcHmc hmc : hmcs) {
				powervcHmcServerRepository.removeByHmc(hmc.getId());
			}
			powervcHmcRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		// 当前数据库中该平台的所有Hmc
		List<PowervcHmc> oldHmcs = powervcHmcRepository.listByVendor(vendor.getId());
		// 在PowerVC中依然存在的Hmc
		List<PowervcHmc> stillExistsHmcs = new ArrayList<>();
		for (HmcHostModel hmcModal : hmcModals) {
			insertOrUpdate(vendor, hmcModal, userId);
			for (PowervcHmc hmc : oldHmcs) {
				if (hmc.getUuid().equals(hmcModal.getUuid())) {
					stillExistsHmcs.add(hmc);
					break;
				}
			}
		}
		// 数据中该平台的所有Hmc去除在PowerVC中依然存在的Hmc，剩下的就需要删除了
		oldHmcs.removeAll(stillExistsHmcs);
		for (PowervcHmc hmc : oldHmcs) {
			powervcHmcServerRepository.removeByHmc(hmc.getId());
			powervcHmcRepository.remove(hmc.getId(), userId);
		}
	}

	/**
	 * 同步一个平台下的所有Server
	 *
	 * @param vendor     平台
	 * @param hostModels Servers
	 * @param userId     用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncServer(CloudVendor vendor, List<HostModel> hostModels, long userId) {
		// 该平台没有任何Server则直接从数据库中删除该平台所有Server
		if (hostModels == null || hostModels.size() == 0) {
			List<Server> servers = serverRepository.listByVendor(vendor.getId());
			List<CmdbInfo> cmdbInfos = new ArrayList<>();
			for (Server server : servers) {
				// 删除该主机和HMC的连接关系
				powervcHmcServerRepository.removeByServer(server.getId());
				// 组建要在cmdb中删除的数据信息
				ServerConfig serverConfig = serverConfigRepository.getBySid(server.getId());
				cmdbInfos.add(CmdbInfoConvertor.getInfo(server, serverConfig, "delete", null));
			}
			// 通知cmdb执行删除
			saveCmdb(userId, cmdbInfos);
			// 删除数据库
			serverRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		// 当前数据库中该平台的所有Server
		List<Server> oldServers = serverRepository.listByVendor(vendor.getId());
		// 在PowerVC中依然存在的Server
		List<Server> stillExistsServers = new ArrayList<>();
		for (HostModel hostModel : hostModels) {
			insertOrUpdate(vendor, hostModel, userId);
			for (Server server : oldServers) {
				if (server.getHostname().equals(hostModel.getHostName())) {
					stillExistsServers.add(server);
					break;
				}
			}
		}
		// 数据中该平台的所有Server去除在PowerVC中依然存在的Server，剩下的就需要删除了
		oldServers.removeAll(stillExistsServers);
		List<CmdbInfo> cmdbInfos = new ArrayList<>();
		for (Server server : oldServers) {
			// 通知cmdb执行删除
			ServerConfig serverConfig = serverConfigRepository.getBySid(server.getId());
			cmdbInfos.add(CmdbInfoConvertor.getInfo(server, serverConfig, "delete", null));
			saveCmdb(userId, cmdbInfos);
			// 删除数据库
			powervcHmcServerRepository.removeByServer(server.getId());
			serverRepository.remove(server.getId(), userId);
		}
	}

	/**
	 * 同步一个Server关联的所有HMC
	 *
	 * @param server   Server
	 * @param hmcUuids Hmc的uuid
	 * @param userId   用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncServerHmc(Server server, List<String> hmcUuids, long userId) {
		if (hmcUuids == null || hmcUuids.size() == 0) {
			powervcHmcServerRepository.removeByServer(server.getId());
			return;
		}
		List<PowervcHmc> oldHmcs = powervcHmcServerRepository.listHmcByServer(server.getId());
		List<PowervcHmc> stillExistsHmcs = new ArrayList<>();
		for (String hmcUuid : hmcUuids) {
			boolean finded = false;
			for (PowervcHmc oldHmc : oldHmcs) {
				if (oldHmc.getUuid().equals(hmcUuid)) {
					stillExistsHmcs.add(oldHmc);
					finded = true;
					break;
				}
			}
			if (!finded) {
				PowervcHmc powervcHmc = powervcHmcRepository.getByUuid(hmcUuid, server.getVendorId());
				PowervcHmcServer powervcHmcServer = new PowervcHmcServer();
				powervcHmcServer.setHmcId(powervcHmc.getId());
				powervcHmcServer.setServerId(server.getId());
				powervcHmcServerRepository.save(powervcHmcServer);
			}
		}
		oldHmcs.removeAll(stillExistsHmcs);
		for (PowervcHmc oldHmc : oldHmcs) {
			powervcHmcServerRepository.remove(oldHmc.getId());
		}
	}

	/**
	 * 同步一个平台下的所有CloudServer
	 *
	 * @param vendor       平台
	 * @param serverModels CloudServers
	 * @param userId       用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncCloudServer(CloudVendor vendor, List<ServerModel> serverModels, long userId) {
		// 该平台没有任何CloudServer则直接从数据库中删除该平台所有CloudServer
		if (serverModels == null || serverModels.size() == 0) {
			// 删除云主机和卷的关联关系
			serverVolumeRepository.removeByVendorid(vendor.getId(), userId);
			// 删除资源和cmdb
			List<CloudServer> servers = cloudServerRepository.listByVid(vendor.getId());
			for (CloudServer server : servers) {
				// 删除资源
				resourceRepository.remove(server.getId(), ResourceCategory.Computer.name(),
						ResourceCatalog.LOGICAL.name(), userId);
				// 删除cmdb
				saveCmdb(userId, Collections.singletonList(CmdbInfoConvertor.getInfo(server, "delete", null)));
			}
			// 删除云主机
			cloudServerRepository.removeByVid(vendor.getId(), userId);
			return;
		}
		// 当前数据库中该平台的所有CloudServer
		List<CloudServer> oldCloudServers = cloudServerRepository.listByVid(vendor.getId());
		// 在PowerVC中依然存在的CloudServer
		List<CloudServer> stillExistsCloudServers = new ArrayList<>();
		for (ServerModel serverModel : serverModels) {
			insertOrUpdate(vendor, serverModel, userId);
			for (CloudServer cloudServer : oldCloudServers) {
				if (serverModel.getInstanceId().equals(cloudServer.getInstanceId())) {
					stillExistsCloudServers.add(cloudServer);
					break;
				}
			}
		}
		// 数据中该平台的所有CloudServer去除在PowerVC中依然存在的CloudServer，剩下的就需要删除了
		oldCloudServers.removeAll(stillExistsCloudServers);
		for (CloudServer server : oldCloudServers) {
			// 删除云主机和卷的关联关系
			serverVolumeRepository.removeBySid(server.getId());
			// 删除资源
			resourceRepository.remove(server.getId(), ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
					userId);
			// 删除cmdb
			saveCmdb(userId, Collections.singletonList(CmdbInfoConvertor.getInfo(server, "delete", null)));
			// 删除云主机
			cloudServerRepository.remove(server.getId(), userId);
		}
	}

	/**
	 * 同步一个CloudServer，会同步处理其关联的卷、网络等信息
	 *
	 * @param vendor     平台
	 * @param instanceId 该cloudServer的instanceId
	 * @param userId     用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public CloudServer syncCloudServer(CloudVendor vendor, String instanceId, long userId) {
		// 获取云主机信息
		BocloudResult bocloudResult = serverDriver.detail(instanceId, vendor.getUuid(), null);
		if (bocloudResult.isFailed()) {
			throw new RuntimeException("获取云主机信息失败：" + bocloudResult.getMessage());
		}
		ServerModel serverModel = (ServerModel) bocloudResult.getData();
		// 保存云主机信息
		return syncCloudServer(vendor, serverModel, userId);
	}

	/**
	 * 同步一个CloudServer，会同步处理其关联的卷、网络等信息
	 *
	 * @param vendor      平台
	 * @param serverModel 该云主机的serverModel
	 * @param userId      用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public CloudServer syncCloudServer(CloudVendor vendor, ServerModel serverModel, long userId) {
		// 保存云主机信息
		CloudServer cloudServer = insertOrUpdate(vendor, serverModel, userId);
		// 保存云主机的卷
		for (VolumeModel volumeModel : serverModel.getDiskDevices()) {
			insertOrUpdate(vendor, volumeModel, userId);
		}
		// 更新存储服务器数据和存储池数据
		Set<String> storageHosts = new HashSet<>();
		for (VolumeModel volumeModel : serverModel.getDiskDevices()) {
			storageHosts.add(volumeModel.getStorageHost());
		}
		for (String storageHost : storageHosts) {
			Storage storage = storageRepository.getByHostName(vendor.getId(), storageHost);
			if (storage == null) {
				throw new RuntimeException("未找到存储提供者：" + storageHost);
			}
			BocloudResult bocloudResult = storageDriver.detail(vendor.getUuid(), storage.getUuid());
			if (bocloudResult.isFailed()) {
				throw new RuntimeException("获取存储提供者信息失败：" + bocloudResult.getMessage());
			}
			StorageModel storageModel = (StorageModel) bocloudResult.getData();
			insertOrUpdate(vendor, storageModel, userId);
		}
		// 更新port
		BocloudResult portResult = portDriver.sync(vendor.getUuid(), null);
		if (portResult.isFailed()) {
			throw new RuntimeException("获取Port信息失败：" + portResult.getMessage());
		}
		List<PortModel> portModels = (List<PortModel>) portResult.getData();
		for (PortModel portModel : portModels) {
			if (serverModel.getInstanceId().equals(portModel.getDeviceUuid())) {
				// 检查这个port的网络在数据库中是否存在，不存在需要同步入库
				if (StringUtils.isNotEmpty(portModel.getNetworkUuid())) {
					Network network = networkRepository.getByNetId(portModel.getNetworkUuid());
					if (network == null) {
						BocloudResult networkResult = networkDriver.detail(portModel.getNetworkUuid(), vendor.getUuid(),
								null);
						if (networkResult.isFailed()) {
							throw new RuntimeException("获取网络信息失败：" + networkResult.getMessage());
						}
						NetworkModel networkModel = (NetworkModel) networkResult.getData();
						network = insertOrUpdate(vendor, networkModel, userId);
					}
					// 检查这个port的子网在数据库中是否存在，不存在需要同步入库
					for (PortFixedIpModel portFixedIpModel : portModel.getPortFixedIps()) {
						if (StringUtils.isNotEmpty(portFixedIpModel.getSubnetUuid())) {
							Subnet subnet = subnetRepository.getBySubId(portFixedIpModel.getSubnetUuid());
							if (subnet == null) {
								BocloudResult subnetResult = subnetDriver.detail(portFixedIpModel.getSubnetUuid(),
										vendor.getUuid(), null);
								if (subnetResult.isFailed()) {
									throw new RuntimeException("获取子网信息失败：" + subnetResult.getMessage());
								}
								SubnetModel subnetModel = (SubnetModel) subnetResult.getData();
								insertOrUpdate(network, subnetModel, userId);
							}

						}
					}
				}
				// 保存这个port
				insertOrUpdate(vendor, portModel, userId);
				// 保存ip占用
				for (PortFixedIpModel portFixedIpModel : portModel.getPortFixedIps()) {
					Subnet subnet = subnetRepository.getBySubId(portFixedIpModel.getSubnetUuid());
					if (subnet != null) {
						insertOrUpdate(subnet, portFixedIpModel.getIpAddress(), userId);
					}
				}
			}
		}
		// 更新该云主机的计算模板
		if (StringUtils.isNotEmpty(serverModel.getFlavorUuid())) {
			BocloudResult flavorResult = flavorDriver.get(vendor.getUuid(), serverModel.getFlavorUuid());
			FlavorModel flavorModel = (FlavorModel) flavorResult.getData();
			insertOrUpdate(vendor, flavorModel, userId);
		}
		return cloudServer;
	}

	/**
	 * 同步一个CloudServer和所有Volume的关联关系
	 *
	 * @param cloudServer
	 * @param models
	 * @param userId
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncCloudServerVolume(CloudServer cloudServer, List<ServerVolumeModel> models, long userId)
			throws Exception {
		// 该CloudServer没有任何Volume则直接从数据库中删除该CloudServer所有和Volume的关联关系
		if (models == null || models.size() == 0) {
			serverVolumeRepository.removeBySid(cloudServer.getId());
			return;
		}
		// 当前数据库中该CloudServer的所有关联的Volume
		List<Volume> oldVolumes = volumeRepository.listVolumeByServerId(cloudServer.getId());
		// 在PowerVC中该CloudServery依然关联的Volume
		List<Volume> stillExsitsVolumes = new ArrayList<>();
		for (ServerVolumeModel model : models) {
			boolean finded = false;
			for (Volume volume : oldVolumes) {
				if (volume.getVolumeUuid().equals(model.getVolumeUuid())) {
					stillExsitsVolumes.add(volume);
					finded = true;
					break;
				}
			}
			if (!finded) {
				Volume volume = volumeRepository.getByVolumeUuid(model.getVolumeUuid());
				ServerVolume serverVolume = new ServerVolume();
				serverVolume.setVolumeId(volume.getId());
				serverVolume.setServerId(cloudServer.getId());
				serverVolumeRepository.save(serverVolume);
			}
		}
		// 删除已经不存在的关联关系
		oldVolumes.removeAll(stillExsitsVolumes);
		for (Volume volume : oldVolumes) {
			serverVolumeRepository.remove(volume.getId(), cloudServer.getId());
		}
	}

	/**
	 * 同步一个平台下的所有Volume
	 *
	 * @param vendor       平台
	 * @param volumeModels Volumes
	 * @param userId       用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncVolume(CloudVendor vendor, List<VolumeModel> volumeModels, long userId) {
		// 该平台没有任何Volumes则直接从数据库中删除该平台所有Volumes
		if (volumeModels == null || volumeModels.size() == 0) {
			serverVolumeRepository.removeByVendorid(vendor.getId(), userId);
			imageVolumeRepository.removeByVendorId(vendor.getId(), userId);
			volumeRepository.removeByVid(vendor.getId(), userId);
			return;
		}
		// 当前数据库中该平台的所有Volumes
		List<Volume> oldVolumes = volumeRepository.listByVendorId(vendor.getId());
		// 在PowerVC中依然存在的Volumes
		List<Volume> stillExistsVolumes = new ArrayList<>();
		for (VolumeModel volumeModel : volumeModels) {
			insertOrUpdate(vendor, volumeModel, userId);
			for (Volume volume : oldVolumes) {
				if (volume.getVolumeUuid().equals(volumeModel.getVolumeUuid())) {
					stillExistsVolumes.add(volume);
					break;
				}
			}
		}
		// 数据中该平台的所有Volumes去除在PowerVC中依然存在的Volumes，剩下的就需要删除了
		oldVolumes.removeAll(stillExistsVolumes);
		for (Volume volume : oldVolumes) {
			// 删除Volume
			serverVolumeRepository.removeByVid(volume.getId());
			imageVolumeRepository.removeByVolume(volume.getId());
			volumeRepository.remove(volume.getId(), userId);
		}
	}

	/**
	 * 同步一个平台下的所有Storage
	 *
	 * @param vendor        平台
	 * @param storageModels Storages
	 * @param userId        用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncStorage(CloudVendor vendor, List<StorageModel> storageModels, long userId) {
		// 该平台没有任何Storages则直接从数据库中删除该平台所有Storages
		if (storageModels == null || storageModels.size() == 0) {
			volumePoolRepository.removeByVendor(vendor.getId());
			storageRepository.removeByVendor(vendor.getId());
			return;
		}
		// 当前数据库中该平台的所有Storages
		List<Storage> oldStorages = storageRepository.listByVendor(vendor.getId());
		// 在PowerVC中依然存在的Storages
		List<Storage> stillExistsStorages = new ArrayList<>();
		for (StorageModel storageModel : storageModels) {
			insertOrUpdate(vendor, storageModel, userId);
			for (Storage storage : oldStorages) {
				if (storage.getUuid().equals(storageModel.getUuid())) {
					stillExistsStorages.add(storage);
					break;
				}
			}
		}
		// 数据中该平台的所有Storages去除在PowerVC中依然存在的Storages，剩下的就需要删除了
		oldStorages.removeAll(stillExistsStorages);
		for (Storage storage : oldStorages) {
			// 删除Storage
			volumePoolRepository.removeByStorage(storage.getId());
			storageRepository.remove(storage.getId());
		}
	}

	/**
	 * 同步一个平台下的所有VolumeTemplate
	 *
	 * @param vendor               平台
	 * @param volumeTemplateModels VolumeTemplates
	 * @param userId               用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncVolumeTemplate(CloudVendor vendor, List<VolumeTemplateModel> volumeTemplateModels, long userId) {
		// 该平台没有任何VolumeTemplate则直接从数据库中删除该平台所有VolumeTemplate
		if (volumeTemplateModels == null || volumeTemplateModels.size() == 0) {
			volumeTemplateRepository.removeByVendor(vendor.getId());
			return;
		}
		// 当前数据库中该平台的所有VolumeTemplate
		List<VolumeTemplate> oldTemplates = volumeTemplateRepository.listByVendor(vendor.getId());
		// 在PowerVC中依然存在的VolumeTemplate
		List<VolumeTemplate> stillExistsTemplates = new ArrayList<>();
		for (VolumeTemplateModel volumeTemplateModel : volumeTemplateModels) {
			insertOrUpdate(vendor, volumeTemplateModel, userId);
			for (VolumeTemplate template : oldTemplates) {
				if (template.getUuid().equals(volumeTemplateModel.getUuid())) {
					stillExistsTemplates.add(template);
					break;
				}
			}
		}
		// 数据中该平台的所有VolumeTemplate去除在PowerVC中依然存在的VolumeTemplate，剩下的就需要删除了
		oldTemplates.removeAll(stillExistsTemplates);
		for (VolumeTemplate template : oldTemplates) {
			// 删除VolumeTemplate
			volumeTemplateRepository.remove(template.getId());
		}
	}

	/**
	 * 同步一个Volume和所有CloudServer的关联关系
	 *
	 * @param volume
	 * @param models
	 * @param userId
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncVolumeCloudServer(Volume volume, List<ServerVolumeModel> models, long userId) {
		// 该Volume没有任何CloudServer则直接从数据库中删除该Volume所有和CloudServer的关联关系
		if (models == null || models.size() == 0) {
			serverVolumeRepository.removeByVid(volume.getId());
			return;
		}
		// 当前数据库中该Volume的所有关联的CloudServer
		Pager pager = new Pager(1, Integer.MAX_VALUE, new ArrayList<>(), new HashMap<>());
		List<CloudServer> oldCloudServers = cloudServerRepository.listServerByVolumeId(volume.getId(), pager);
		// 在PowerVC中该CloudServery依然关联的Volume
		List<CloudServer> stillExsitsCloudServers = new ArrayList<>();
		for (ServerVolumeModel model : models) {
			boolean finded = false;
			for (CloudServer cloudServer : oldCloudServers) {
				if (cloudServer.getInstanceId().equals(model.getInstanceId())) {
					stillExsitsCloudServers.add(cloudServer);
					finded = true;
					break;
				}
			}
			if (!finded) {
				CloudServer cloudServer = cloudServerRepository.getByInstanceId(model.getInstanceId(),
						volume.getVendorId());
				ServerVolume serverVolume = new ServerVolume();
				serverVolume.setVolumeId(volume.getId());
				serverVolume.setServerId(cloudServer.getId());
				serverVolume.setUuid(model.getUuid());
				serverVolume.setDevice(model.getDevice());
				serverVolumeRepository.save(serverVolume);
			}
		}
		// 删除已经不存在的关联关系
		oldCloudServers.removeAll(stillExsitsCloudServers);
		for (CloudServer cloudServer : oldCloudServers) {
			serverVolumeRepository.remove(volume.getId(), cloudServer.getId());
		}
	}

	/**
	 * 同步一个平台下的所有Iamge
	 *
	 * @param vendor      平台
	 * @param imageModels Images
	 * @param userId      用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncImage(CloudVendor vendor, List<ImageModel> imageModels, long userId) {
		// 该平台没有任何Image则直接从数据库中删除该平台所有Image
		if (imageModels == null || imageModels.size() == 0) {
			imageVolumeRepository.removeByVendorId(vendor.getId(), userId);
			imageRepository.removeByVid(vendor.getId(), userId);
			return;
		}
		// 当前数据库中该平台的所有Image
		List<Image> oldImages = imageRepository.listByVendorId(vendor.getId());
		// 在PowerVC中依然存在的Image
		List<Image> stillExistsImages = new ArrayList<>();
		for (ImageModel imageModel : imageModels) {
			insertOrUpdate(vendor, imageModel, userId);
			for (Image image : oldImages) {
				if (image.getImageUuid().equals(imageModel.getImageUuid())) {
					stillExistsImages.add(image);
					break;
				}
			}
		}
		// 数据中该平台的所有Image去除在PowerVC中依然存在的Image，剩下的就需要删除了
		oldImages.removeAll(stillExistsImages);
		for (Image image : oldImages) {
			imageVolumeRepository.removeByImage(image.getId());
			imageRepository.remove(image.getId(), userId);
		}
	}

	/**
	 * 同步一个平台下的所有Network
	 *
	 * @param vendor        平台
	 * @param networkModels networkModels
	 * @param userId        用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncNetwork(CloudVendor vendor, List<NetworkModel> networkModels, long userId) {
		// 该平台没有任何Network则直接从数据库中删除该平台所有Network
		if (networkModels == null || networkModels.size() == 0) {
			// 删除cmdb
			List<Network> networks = networkRepository.listByVid(vendor.getId());
			List<CmdbInfo> cmdbInfos = new ArrayList<>();
			for (Network network : networks) {
				cmdbInfos.add(CmdbInfoConvertor.getInfo(network, "delete", null));
			}
			saveCmdb(userId, cmdbInfos);
			// 删除数据库
			networkRepository.removeByVid(vendor.getId(), userId);
			subnetRepository.removeByVid(vendor.getId(), userId);
			portRepository.removeByVid(vendor.getId(), userId);
			portFixedIpRepository.deleteByVendorId(vendor.getId());
			ipPoolRepository.removeByVid(vendor.getId(), userId);
			ipRepository.deleteByVid(vendor.getId());
			return;
		}
		// 当前数据库中该平台的所有Network
		List<Network> oldNetworks = networkRepository.listByVid(vendor.getId());
		// 在PowerVC中依然存在的Network
		List<Network> stillExistsNetworks = new ArrayList<>();
		for (NetworkModel networkModel : networkModels) {
			insertOrUpdate(vendor, networkModel, userId);
			for (Network network : oldNetworks) {
				if (network.getNetworkUuid().equals(networkModel.getNetworkUuid())) {
					stillExistsNetworks.add(network);
					break;
				}
			}
		}
		// 数据中该平台的所有Network去除在PowerVC中依然存在的Network，剩下的就需要删除了
		oldNetworks.removeAll(stillExistsNetworks);
		for (Network network : oldNetworks) {
			// 删除cmdb
			saveCmdb(userId, Collections.singletonList(CmdbInfoConvertor.getInfo(network, "delete", null)));
			// 删除数据库
			networkRepository.remove(network.getId(), userId);
			subnetRepository.removeByNetworkId(network.getId(), userId);
			portRepository.removeByNetworkId(network.getId(), userId);
			portFixedIpRepository.deleteByNetworkId(network.getId());
			ipPoolRepository.removeByNetworkId(network.getId(), userId);
			ipRepository.deleteByNetworkId(network.getId());
		}
	}

	/**
	 * 同步一个平台下的所有NetworkSeaAdaterModel
	 *
	 * @param vendor
	 * @param seas
	 * @param userId
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncNetworkSea(CloudVendor vendor, List<NetworkSeaAdaterModel> seas, long userId) {
		// 该平台没有任何NetworkSeaAdater则直接从数据库中删除该平台所有NetworkSeaAdater
		if (seas == null || seas.size() == 0) {
			// 删除cmdb
			networkSeaRepository.deleteByVendorId(vendor.getId());
			return;
		}
		// 当前数据库中该平台的所有NetworkSeaAdater
		List<NetworkSeaAdapter> oldSeas = networkSeaRepository.listByVendorId(vendor.getId());
		// 在PowerVC中依然存在的NetworkSeaAdater
		List<NetworkSeaAdapter> stillExistsSeas = new ArrayList<>();
		for (NetworkSeaAdaterModel sea : seas) {
			boolean finded = false;
			for (NetworkSeaAdapter oldSea : oldSeas) {
				if (sea.getNetworkUuid().equals(oldSea.getNetworkUuid())
						&& sea.getServerHost().equals(oldSea.getServerHost())
						&& sea.getLparId().equals(oldSea.getLparId()) && sea.getSeaName().equals(oldSea.getSeaName())) {
					stillExistsSeas.add(oldSea);
					finded = true;
					break;
				}
			}
			if (!finded) {
				HostSeaAdapter hostSeaAdapter = hostSeaRepository.getByName(sea.getSeaName(), sea.getLparId(),
						sea.getServerHost(), vendor.getId());
				Network network = networkRepository.getByNetId(sea.getNetworkUuid());
				NetworkSeaAdapter networkSeaAdapter = new NetworkSeaAdapter();
				networkSeaAdapter.setNetworkId(network.getId());
				networkSeaAdapter.setSeaId(hostSeaAdapter.getId());
				networkSeaRepository.save(networkSeaAdapter);
			}
		}
		// 数据中该平台的所有Sea去除在PowerVC中依然存在的Sea，剩下的就需要删除了
		oldSeas.removeAll(stillExistsSeas);
		for (NetworkSeaAdapter sea : oldSeas) {
			networkSeaRepository.deleteById(sea.getId());
		}
	}

	/**
	 * 同步一个Network下的所有Subnet，同步处理IpPool
	 *
	 * @param network      network
	 * @param subnetModels subnetModels
	 * @param userId       用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncSubnet(Network network, List<SubnetModel> subnetModels, long userId) {
		// 该Network没有任何Subnet则直接从数据库中删除该network所有Subnet
		if (subnetModels == null || subnetModels.size() == 0) {
			// 删除cmdb
			List<CmdbInfo> cmdbInfos = new ArrayList<>();
			List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
			for (Subnet subnet : subnets) {
				cmdbInfos.add(CmdbInfoConvertor.getInfo(subnet, "delete", null));
			}
			saveCmdb(userId, cmdbInfos);
			// 删除数据库
			ipRepository.deleteByNetworkId(network.getId());
			ipPoolRepository.removeByNetworkId(network.getId(), userId);
			subnetRepository.removeByNetworkId(network.getId(), userId);
			return;
		}
		// 当前数据库中该Network的所有Subnet
		List<Subnet> oldSubnets = subnetRepository.listByNetwork(network.getId());
		// 在PowerVC中依然存在的Subnet
		List<Subnet> stillExistsSubnets = new ArrayList<>();
		for (SubnetModel subnetModel : subnetModels) {
			insertOrUpdate(network, subnetModel, userId);
			for (Subnet subnet : oldSubnets) {
				if (subnet.getSubnetUuid().equals(subnetModel.getSubnetUuid())) {
					stillExistsSubnets.add(subnet);
					break;
				}
			}
		}
		// 数据中该Network的所有Subnet去除在PowerVC中依然存在的Subnet，剩下的就需要删除了
		oldSubnets.removeAll(stillExistsSubnets);
		for (Subnet subnet : oldSubnets) {
			// 删除cmdb
			saveCmdb(userId, Collections.singletonList(CmdbInfoConvertor.getInfo(subnet, "delete", null)));
			// 删除数据库
			ipRepository.deleteBySubnetId(subnet.getId(), network.getVendorId());
			ipPoolRepository.removeBySubnetId(subnet.getId(), subnet.getVendorId(), userId);
			subnetRepository.remove(subnet.getId(), userId);
		}
	}

	/**
	 * 同步一个平台下的所有Port, 会同步处理PortFixedIpModel
	 *
	 * @param vendor
	 * @param portModels
	 * @param userId
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncPort(CloudVendor vendor, List<PortModel> portModels, long userId) {
		// 该平台没有任何Port则直接从数据库中删除该平台所有Port
		if (portModels == null || portModels.size() == 0) {
			// 删除cmdb
			List<CmdbInfo> cmdbInfos = new ArrayList<>();
			List<Port> ports = portRepository.listByVid(vendor.getId());
			for (Port port : ports) {
				CloudServer cloudServer = cloudServerRepository.getByInstanceId(port.getDeviceUuid(), vendor.getId());
				if (cloudServer != null) {
					cmdbInfos.add(getCmdbInfoFromCloudServer(cloudServer));
				}
			}
			saveCmdb(userId, cmdbInfos);
			// 删除数据库
			ipRepository.deleteByVid(vendor.getId());
			portFixedIpRepository.deleteByVendorId(vendor.getId());
			portRepository.removeByVid(vendor.getId(), userId);
			return;
		}
		// 当前数据库中该平台的所有Port
		List<Port> oldPorts = portRepository.listByVid(vendor.getId());
		// 在PowerVC中依然存在的Port
		List<Port> stillExistsPorts = new ArrayList<>();
		for (PortModel portModel : portModels) {
			insertOrUpdate(vendor, portModel, userId);
			for (Port port : oldPorts) {
				if (port.getPortUuid().equals(portModel.getPortUuid())) {
					stillExistsPorts.add(port);
					break;
				}
			}
		}
		// 数据中该平台的所有Port去除在PowerVC中依然存在的Port，剩下的就需要删除了
		oldPorts.removeAll(stillExistsPorts);
		for (Port port : oldPorts) {
			// 删除cmdb
			CloudServer cloudServer = cloudServerRepository.getByInstanceId(port.getDeviceUuid(), vendor.getId());
			if (cloudServer != null) {
				saveCmdb(userId, Collections.singletonList(getCmdbInfoFromCloudServer(cloudServer)));
			}
			// 删除数据库
			ipRepository.deleteByPortId(port.getId());
			portFixedIpRepository.deleteByPortId(port.getId());
			portRepository.remove(port.getId(), userId);
		}
	}

	/**
	 * 同步一个Port下的所有PortFixedIpModel
	 *
	 * @param port              port
	 * @param portFixedIpModels portFixedIpModels
	 * @param userId            用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncPortFixedIp(Port port, List<PortFixedIpModel> portFixedIpModels, long userId) {
		// 该Port没有任何PortFixedIpModel则直接从数据库中删除该Port所有PortFixedIpModel
		if (portFixedIpModels == null || portFixedIpModels.size() == 0) {
			portFixedIpRepository.deleteByPortId(port.getId());
			ipRepository.deleteByPortId(port.getId());
			return;
		}
		// 当前数据库中该Port的所有PortFixedIpModel
		List<PortFixedIp> oldIps = portFixedIpRepository.listByPortId(port.getId());
		// 在Port中依然存在的PortFixedIpModel
		List<PortFixedIp> stillExistsIps = new ArrayList<>();
		for (PortFixedIpModel ipModel : portFixedIpModels) {
			insertOrUpdate(port, ipModel, userId);
			for (PortFixedIp ip : oldIps) {
				if (ip.getIpAddress().equals(ipModel.getIpAddress())) {
					stillExistsIps.add(ip);
					break;
				}
			}
		}
		// 数据中该Port的所有Ip去除在PortFixedIpModel中依然存在的Ip，剩下的就需要删除了
		oldIps.removeAll(stillExistsIps);
		for (PortFixedIp ip : oldIps) {
			portFixedIpRepository.delete(ip.getId());
			ipRepository.delete(ip.getIpAddress(), ip.getSubnetId(), port.getVendorId());
		}
	}

	/**
	 * 同步一个平台下的所有已用Ip
	 *
	 * @param vendor
	 * @param ipModels
	 * @param userId
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncIp(CloudVendor vendor, List<PortFixedIpModel> ipModels, long userId) {
		// 该平台没有任何已用ip则直接从数据库中删除该平台所有已用Ip
		if (ipModels == null || ipModels.size() == 0) {
			ipRepository.deleteByVid(vendor.getId());
			return;
		}
		// 当前数据库中该平台的所有已用Ip
		List<Ip> oldIps = ipRepository.listByVendor(vendor.getId());
		// 在平台中依然存在的已用ip
		List<Ip> stillExistsIps = new ArrayList<>();
		for (PortFixedIpModel ipModel : ipModels) {
			Subnet subnet = subnetRepository.getBySubId(ipModel.getSubnetUuid());
			if (subnet == null) {
				throw new RuntimeException("未找到子网：" + ipModel.getSubnetUuid());
			}
			insertOrUpdate(subnet, ipModel.getIpAddress(), userId);
			for (Ip ip : oldIps) {
				if (ip.getIp().equals(ipModel.getIpAddress())) {
					stillExistsIps.add(ip);
					break;
				}
			}
		}
		// 数据中该Port的所有已用Ip去除在ipValues中依然存在的Ip，剩下的就需要删除了
		oldIps.removeAll(stillExistsIps);
		for (Ip ip : oldIps) {
			ipRepository.delete(ip.getId());
		}
	}

	/**
	 * 同步一个平台下的所有Flavor
	 *
	 * @param vendor       平台
	 * @param flavorModels Flavors
	 * @param userId       用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncFlavor(CloudVendor vendor, List<FlavorModel> flavorModels, long userId) {
		// 该平台没有任何Flavor则直接从数据库中删除该平台所有Flavor
		if (flavorModels == null || flavorModels.size() == 0) {
			flavorExtraSpecsRepository.removeByVendorId(vendor.getId());
			flavorRepository.removeByVid(vendor.getId());
			return;
		}
		// 当前数据库中该平台的所有Flavor
		List<Flavor> oldFlavors = flavorRepository.listByVendorId(vendor.getId());
		// 在PowerVC中依然存在的Flavor
		List<Flavor> stillExistsFlavors = new ArrayList<>();
		for (FlavorModel flavorModel : flavorModels) {
			insertOrUpdate(vendor, flavorModel, userId);
			for (Flavor flavor : oldFlavors) {
				if (flavor.getFlavorUuid().equals(flavorModel.getFlavorUuid())) {
					stillExistsFlavors.add(flavor);
					break;
				}
			}
		}
		// 数据中该平台的所有Flavor去除在PowerVC中依然存在的Flavor，剩下的就需要删除了
		oldFlavors.removeAll(stillExistsFlavors);
		for (Flavor flavor : oldFlavors) {
			// 删除Flavor
			flavorExtraSpecsRepository.removeByFlavorId(flavor.getId());
			flavorRepository.delete(flavor.getId());
		}
	}

	/**
	 * 同步一个平台下的所有Cluster
	 *
	 * @param vendor        平台
	 * @param clusterModels clusterModels
	 * @param userId        用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncCluster(CloudVendor vendor, List<ClusterModel> clusterModels, long userId) {
		// 该平台没有任何Cluster则直接从数据库中删除该平台所有Cluster
		if (clusterModels == null || clusterModels.size() == 0) {
			List<Cluster> clusters = clusterRepository.listByVendor(vendor.getId());
			List<CmdbInfo> cmdbInfos = new ArrayList<>();
			for (Cluster cluster : clusters) {
				cmdbInfos.add(CmdbInfoConvertor.getInfo(cluster, "delete", null));
			}
			saveCmdb(userId, cmdbInfos);
			clusterRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		// 当前数据库中该平台的所有Cluster
		List<Cluster> oldClusters = clusterRepository.listByVendor(vendor.getId());
		// 在PowerVC中依然存在的Cluster
		List<Cluster> stillExistsClusters = new ArrayList<>();
		// 要先插入默认主机组
		for (ClusterModel clusterModel : clusterModels) {
			if (clusterModel.getUuid().equals(PowervcConstant.DEFAULT_OS_AGGREGATE_ID)) {
				insertOrUpdate(vendor, clusterModel, userId);
				for (Cluster cluster : oldClusters) {
					if (cluster.getUuid().equals(clusterModel.getUuid())) {
						stillExistsClusters.add(cluster);
						break;
					}
				}
			}
		}
		// 然后再插入其他主机组
		for (ClusterModel clusterModel : clusterModels) {
			if (!clusterModel.getUuid().equals(PowervcConstant.DEFAULT_OS_AGGREGATE_ID)) {
				insertOrUpdate(vendor, clusterModel, userId);
				for (Cluster cluster : oldClusters) {
					if (cluster.getUuid().equals(clusterModel.getUuid())) {
						stillExistsClusters.add(cluster);
						break;
					}
				}
			}
		}
		// 数据中该平台的所有Cluster去除在PowerVC中依然存在的Cluster，剩下的就需要删除了
		oldClusters.removeAll(stillExistsClusters);
		for (Cluster cluster : oldClusters) {
			saveCmdb(userId, Collections.singletonList(CmdbInfoConvertor.getInfo(cluster, "delete", null)));
			// 删除Cluster
			clusterRepository.remove(cluster.getId(), userId);
		}
	}

	/**
	 * 同步一个存储服务器下的所有VolumePool
	 *
	 * @param storage          存储服务器
	 * @param volumePoolModels volumePoolModels
	 * @param userId           用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncVolumePool(Storage storage, List<VolumePoolModel> volumePoolModels, long userId) {
		// 该存储服务器没有任何Cluster则直接从数据库中删除该存储服务器所有VolumePool
		if (volumePoolModels == null || volumePoolModels.size() == 0) {
			volumePoolRepository.removeByStorage(storage.getId());
			return;
		}
		// 当前数据库中该存储服务器的所有VolumePool
		List<VolumePool> oldPools = volumePoolRepository.listByStorage(storage.getId());
		// 在PowerVC中依然存在的VolumePool
		List<VolumePool> stillExistsPools = new ArrayList<>();
		for (VolumePoolModel poolModel : volumePoolModels) {
			insertOrUpdate(storage, poolModel, userId);
			for (VolumePool pool : oldPools) {
				if (pool.getUuid().equals(poolModel.getUuid())) {
					stillExistsPools.add(pool);
					break;
				}
			}
		}
		// 数据中该存储服务器的所有VolumePool去除在PowerVC中依然存在的VolumePool，剩下的就需要删除了
		oldPools.removeAll(stillExistsPools);
		for (VolumePool pool : oldPools) {
			// 删除VolumePool
			volumePoolRepository.remove(pool.getId());
		}
	}

	/**
	 * 同步一个镜像下面的所有Volume
	 *
	 * @param image        镜像
	 * @param volumeModels volumePoolModels
	 * @param userId       用户id
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncImageVolume(Image image, List<VolumeModel> volumeModels, long userId) {
		// 该镜像没有任何Volume则直接从数据库中删除该镜像所有Volume
		if (volumeModels == null || volumeModels.size() == 0) {
			imageVolumeRepository.removeByImage(image.getId());
			return;
		}
		// 当前数据库中该镜像的所有Volume
		List<Volume> oldVolumes = imageVolumeRepository.listVolumeByImage(image.getId());
		// 在PowerVC中依然存在的Volume
		List<Volume> stillExistsVolumes = new ArrayList<>();
		for (VolumeModel volumeModel : volumeModels) {
			boolean finded = false;
			for (Volume volume : oldVolumes) {
				if (volumeModel.getVolumeUuid().equals(volume.getVolumeUuid())) {
					stillExistsVolumes.add(volume);
					finded = true;
					break;
				}
			}
			if (!finded) {
				Volume volume = volumeRepository.getByVolumeUuid(volumeModel.getVolumeUuid());
				if (volume != null) {
					ImageVolume imageVolume = new ImageVolume();
					imageVolume.setImageId(image.getId());
					imageVolume.setVolumeId(volume.getId());
					imageVolumeRepository.save(imageVolume);
				}
			}
		}
		// 数据中该镜像的所有Volume去除在PowerVC中依然存在的Volume，剩下的就需要删除了
		oldVolumes.removeAll(stillExistsVolumes);
		for (Volume volume : oldVolumes) {
			// 删除Volume
			imageVolumeRepository.remove(image.getId(), volume.getId());
		}
	}

	/**
	 * 同步一个平台下面的所有SanFabrics
	 *
	 * @param vendor
	 * @param sanFabricModels
	 * @param userId
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncSanFabircs(CloudVendor vendor, List<SanFabricModel> sanFabricModels, long userId) {
		if (sanFabricModels == null || sanFabricModels.size() == 0) {
			sanFabricRepository.removeByVendor(vendor.getId());
			return;
		}
		List<SanFabric> oldFabricses = sanFabricRepository.listByVendor(vendor.getId());
		List<SanFabric> stillExistsFabricses = new ArrayList<>();
		for (SanFabricModel fabricsModel : sanFabricModels) {
			insertOrUpdate(vendor, fabricsModel, userId);
			for (SanFabric sanFabric : oldFabricses) {
				if (sanFabric.getUuid().equals(fabricsModel.getName())) {
					stillExistsFabricses.add(sanFabric);
					break;
				}
			}
		}
		oldFabricses.removeAll(stillExistsFabricses);
		for (SanFabric fabrics : oldFabricses) {
			sanFabricRepository.remove(fabrics.getId());
		}
	}

	/**
	 * 同步一个平台下的所有Sea
	 *
	 * @param vendor
	 * @param seaAdapters
	 * @param userId
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void syncSea(CloudVendor vendor, List<HostSeaAdapter> seaAdapters, long userId) {
		if (seaAdapters == null || seaAdapters.size() == 0) {
			hostSeaRepository.removeByVendor(vendor.getId());
			return;
		}
		List<HostSeaAdapter> oldSeas = hostSeaRepository.listByVendor(vendor.getId());
		List<HostSeaAdapter> stillExistsSeas = new ArrayList<>();
		for (HostSeaAdapter seaAdapter : seaAdapters) {
			insertOrUpdate(vendor, seaAdapter, userId);
			for (HostSeaAdapter seaOld : oldSeas) {
				if (seaOld.getServerId().equals(seaAdapter.getServerId())
						&& seaOld.getSeaName().equals(seaAdapter.getSeaName())
						&& seaOld.getLparId().equals(seaAdapter.getLparId())) {
					stillExistsSeas.add(seaOld);
					break;
				}
			}
		}
		oldSeas.removeAll(stillExistsSeas);
		for (HostSeaAdapter seaAdapter : oldSeas) {
			// 删除Cluster
			hostSeaRepository.remove(seaAdapter.getId());
		}
	}

	/**
	 * 添加或修改一个PowervcHmc
	 *
	 * @param vendor       该PowervcHmc所属平台
	 * @param hmcHostModel 该PowervcHmc
	 * @param userId       当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public PowervcHmc insertOrUpdate(CloudVendor vendor, HmcHostModel hmcHostModel, long userId) {
		PowervcHmc hmc = powervcHmcRepository.getByUuid(hmcHostModel.getUuid(), vendor.getId());
		if (hmc == null) {
			hmc = new PowervcHmc();
		}
		transport(hmcHostModel, hmc);
		hmc.setVendorId(vendor.getId());
		hmc.setMenderId(userId);
		if (hmc.getId() == null) {
			hmc.setCreatorId(userId);
			powervcHmcRepository.save(hmc);
		} else {
			powervcHmcRepository.update(hmc);
		}
		return hmc;
	}

	/**
	 * 添加或修改一个Server
	 *
	 * @param vendor    该Server所属平台
	 * @param hostModel 该Server
	 * @param userId    当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Server insertOrUpdate(CloudVendor vendor, HostModel hostModel, long userId) {
		Server server = serverRepository.getByHostName(hostModel.getHostName(), vendor.getId());
		ServerConfig serverConfig;
		if (server == null) {
			server = new Server();
			serverConfig = new ServerConfig();
		} else {
			serverConfig = serverConfigRepository.getBySid(server.getId());
		}
		transport(hostModel, server, serverConfig);
		server.setAssetCategory(ServerAssetCategory.POWER_SERVER.name());
		server.setMenderId(userId);
		server.setVendorId(vendor.getId());
		if (server.getId() == null) {
			// 到数据库中执行创建
			server.setUuid(IDFactory.instance().uuid());
			server.setGuid(IDFactory.instance().uuid());
			server.setCreatorId(userId);
			serverRepository.save(server);
			serverConfig.setServerId(server.getId());
			serverConfigRepository.save(serverConfig);
		} else {
			// 到数据库中执行修改
			serverRepository.update(server);
			serverConfigRepository.update(serverConfig);
		}
		// 同步该server对应的hmc链接
		syncServerHmc(server, hostModel.getHmcUuids(), userId);
		// 通知cmdb执行修改
		saveCmdb(userId, Collections.singletonList(getCmdbInfoFromServer(server)));
		return server;
	}

	/**
	 * 添加或修改一个Server
	 *
	 * @param vendor      该Server所属平台
	 * @param serverModel 该Server
	 * @param userId      当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public CloudServer insertOrUpdate(CloudVendor vendor, ServerModel serverModel, long userId) {
		CloudServer cloudServer = cloudServerRepository.getByInstanceId(serverModel.getInstanceId(), vendor.getId());
		if (cloudServer == null) {
			cloudServer = new CloudServer();
		}

		Server server = serverRepository.getByHostName(serverModel.getHostName(), vendor.getId());
		if (server != null) {
			cloudServer.setHostId(server.getId());
		}

		transport(serverModel, cloudServer);
		cloudServer.setMenderId(userId);
		cloudServer.setVendorId(vendor.getId());
		cloudServer.setVendorType(vendor.getType());
		if (cloudServer.getId() == null) {
			cloudServer.setGuid(IDFactory.instance().uuid());
			cloudServer.setCreatorId(userId);
			cloudServer.setRecycle(false);
			cloudServerRepository.save(cloudServer);
		} else {
			cloudServerRepository.update(cloudServer);
		}
		// 同步cmdb
		saveCmdb(userId, Collections.singletonList(getCmdbInfoFromCloudServer(cloudServer)));
		return cloudServer;
	}

	/**
	 * 添加或修改一个Storage
	 *
	 * @param vendor       该Storage所属平台
	 * @param storageModel 该Storage
	 * @param userId       当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Storage insertOrUpdate(CloudVendor vendor, StorageModel storageModel, long userId) {
		Storage storage = storageRepository.getByUuid(storageModel.getUuid());
		if (storage == null) {
			storage = new Storage();
		}
		transport(storageModel, storage);
		storage.setMenderId(userId);
		storage.setVendorId(vendor.getId());
		if (storage.getId() == null) {
			storage.setCreatorId(userId);
			storageRepository.save(storage);
		} else {
			storageRepository.update(storage);
		}

		syncVolumePool(storage, storageModel.getPools(), userId);

		return storage;
	}

	/**
	 * 添加或修改一个VolumeTemplate
	 *
	 * @param vendor              该VolumeTemplate所属平台
	 * @param volumeTemplateModel 该VolumeTemplate
	 * @param userId              当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public VolumeTemplate insertOrUpdate(CloudVendor vendor, VolumeTemplateModel volumeTemplateModel, long userId) {
		VolumeTemplate template = volumeTemplateRepository.getByUuid(volumeTemplateModel.getUuid());
		if (template == null) {
			template = new VolumeTemplate();
		}
		transport(volumeTemplateModel, template);

		// 获取该存储器模板所在的存储提供者
		Storage storage = storageRepository.getByHostName(vendor.getId(), volumeTemplateModel.getStorageName());
		if (storage != null) {
			template.setStorageId(storage.getId());

			// 该模版卷所属存储池
			VolumePool basePool = volumePoolRepository.getByName(volumeTemplateModel.getPoolName(), storage.getId());
			if (basePool != null) {
				template.setPoolId(basePool.getId());
			}

			// 该模版卷拷贝所属存储池
			if (StringUtils.isNotEmpty(volumeTemplateModel.getCopyPoolName())) {
				VolumePool copyPool = volumePoolRepository.getByName(volumeTemplateModel.getCopyPoolName(),
						storage.getId());
				if (copyPool != null) {
					template.setCopyPoolId(copyPool.getId());
				}
			}

			// 设定存储提供者对应的默认存储器模板
			if (template.getUuid().equals(storage.getDefaultTemplateUuid())) {
				storage.setDefaultTemplateId(template.getId());
				storageRepository.update(storage);
			}
		}

		template.setMenderId(userId);
		template.setVendorId(vendor.getId());
		if (template.getId() == null) {
			template.setCreatorId(userId);
			volumeTemplateRepository.save(template);
		} else {
			volumeTemplateRepository.update(template);
		}

		return template;
	}

	/**
	 * 添加或修改一个Volume
	 *
	 * @param vendor      该Volume所属平台
	 * @param volumeModel 该Volume
	 * @param userId      当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Volume insertOrUpdate(CloudVendor vendor, VolumeModel volumeModel, long userId) {
		Volume volume = volumeRepository.getByVolumeUuid(volumeModel.getVolumeUuid());
		if (volume == null) {
			volume = new Volume();
		}
		transport(volumeModel, volume);

		Storage storage = storageRepository.getByHostName(vendor.getId(), volumeModel.getStorageHost());
		if (storage != null) {
			volume.setStorageId(storage.getId());

			if (volumeModel.getType() == null && volumeModel.getPoolName() != null) {
				VolumePool volumePool = volumePoolRepository.getByName(volumeModel.getPoolName(), storage.getId());
				if (volumePool != null) {
					volume.setPoolId(volumePool.getId());
				}
			}
		}

		if (StringUtils.isNotEmpty(volumeModel.getCategory())) {
			VolumeTemplate volumeTemplate = volumeTemplateRepository.getByOriginName(volumeModel.getCategory(),
					vendor.getId());
			if (volumeTemplate != null) {
				volume.setTemplateId(volumeTemplate.getId());
			}
		}

		volume.setMenderId(userId);
		volume.setVendorId(vendor.getId());
		if (volume.getId() == null) {
			volume.setCreatorId(userId);
			volumeRepository.save(volume);
		} else {
			volumeRepository.update(volume);
		}

		syncVolumeCloudServer(volume, volumeModel.getModels(), userId);

		return volume;
	}

	/**
	 * 添加或修改一个Image
	 *
	 * @param vendor     该Volume所属平台
	 * @param imageModel 该Volume
	 * @param userId     当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Image insertOrUpdate(CloudVendor vendor, ImageModel imageModel, long userId) {
		Image image = imageRepository.getByImageUuid(imageModel.getImageUuid());
		if (image == null) {
			image = new Image();
		}
		transport(imageModel, image);
		image.setMenderId(userId);
		image.setVendorId(vendor.getId());
		if (image.getId() == null) {
			image.setCreatorId(userId);
			imageRepository.save(image);
		} else {
			imageRepository.update(image);
		}

		syncImageVolume(image, imageModel.getDiskDeviceMappings(), userId);

		return image;
	}

	/**
	 * 添加或修改一个Network
	 *
	 * @param vendor       该Network所属平台
	 * @param networkModel 该Network
	 * @param userId       当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Network insertOrUpdate(CloudVendor vendor, NetworkModel networkModel, long userId) {
		Network network = networkRepository.getByNetId(networkModel.getNetworkUuid());
		if (network == null) {
			network = new Network();
		}
		transport(networkModel, network);
		network.setMenderId(userId);
		network.setVendorId(vendor.getId());
		if (network.getId() == null) {
			network.setGuid(IDFactory.instance().uuid());
			network.setCreatorId(userId);
			networkRepository.save(network);
		} else {
			networkRepository.update(network);
		}
		// 同步网络下的子网
		syncSubnet(network, networkModel.getSubnets(), userId);
		// 保存cmdb
		saveCmdb(userId, Collections.singletonList(getCmdbInfoFromNetwork(network)));
		return network;
	}

	/**
	 * 添加或修改一个Subnet，会同时添加修改IpPool并处理Ip列表
	 *
	 * @param network
	 * @param subnetModal
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Subnet insertOrUpdate(Network network, SubnetModel subnetModal, long userId) {
		// 处理Subnet
		Subnet subnet = subnetRepository.getBySubId(subnetModal.getSubnetUuid());
		if (subnet == null) {
			subnet = new Subnet();
		}
		transport(subnetModal, subnet);
		if (StringUtils.isEmpty(subnet.getName())) {
			subnet.setName(network.getName());
		}
		subnet.setMenderId(userId);
		subnet.setVendorId(network.getVendorId());
		subnet.setNetworkId(network.getId());
		if (subnet.getId() == null) {
			subnet.setGuid(IDFactory.instance().uuid());
			subnet.setCreatorId(userId);
			subnetRepository.save(subnet);
		} else {
			subnetRepository.update(subnet);
		}
		// 同步ipPool
		insertOrUpdate(network, subnet, userId);
		// 保存cmdb
		saveCmdb(userId, Collections.singletonList(getCmdbInfoFromSubnet(subnet)));
		return subnet;
	}

	/**
	 * 根据SubnetModel添加或修改一个IpPool
	 *
	 * @param network
	 * @param subnet
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public IpPool insertOrUpdate(Network network, Subnet subnet, long userId) {
		IpPool ipPool = ipPoolRepository.queryBySubnet(subnet.getId(), subnet.getVendorId());
		if (ipPool == null) {
			ipPool = new IpPool();
		}
		ipPool.setGateway(subnet.getGateway());
		ipPool.setCidr(subnet.getCidr());
		ipPool.setPools(subnet.getIpPools());
		ipPool.setDnsNames(subnet.getDnsNames());
		ipPool.setSubnetId(subnet.getId());
		ipPool.setNetworkId(subnet.getNetworkId());
		ipPool.setVendorId(subnet.getVendorId());
		ipPool.setVlanId(Integer.parseInt(network.getSegmentationId()));
		ipPool.setMenderId(userId);
		if (ipPool.getId() == null) {
			ipPool.setCreatorId(userId);
			ipPool.setVersion(IPAddress.getVersion(subnet.getGateway()));
			ipPoolRepository.save(ipPool);
		} else {
			ipPoolRepository.update(ipPool);
		}
		return ipPool;
	}

	/**
	 * 添加或修改一个Port
	 *
	 * @param subnet  该Ip所属的subnet
	 * @param ipValue ip地址
	 * @param userId  当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Ip insertOrUpdate(Subnet subnet, String ipValue, long userId) {
		Ip ip = ipRepository.checkExist(ipValue, subnet.getId(), subnet.getVendorId());
		IpPool ipPool = ipPoolRepository.queryBySubnet(subnet.getId(), subnet.getVendorId());
		if (ipPool == null) {
			throw new RuntimeException("未找到ip池：" + subnet.getId());
		}
		if (ip == null) {
			ip = new Ip();
		}
		ip.setIp(ipValue);
		ip.setSubnetId(subnet.getId());
		ip.setPoolId(ipPool.getId());
		ip.setGateway(subnet.getGateway());
		ip.setDns(subnet.getDnsNames());
		String mask = IPAddress.getIPAddress(ipValue).getMask(subnet.getCidr());
		ip.setMask(mask);
		ip.setNetworkId(subnet.getNetworkId());
		ip.setVendorId(subnet.getVendorId());
		if (ip.getId() == null) {
			ipRepository.save(ip);
		} else {
			ipRepository.update(ip);
		}
		return ip;
	}

	/**
	 * 添加或修改一个Port
	 *
	 * @param vendor
	 * @param portModel
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Port insertOrUpdate(CloudVendor vendor, PortModel portModel, long userId) {
		Port port = portRepository.getByPortUuid(portModel.getPortUuid(), vendor.getId());
		if (port == null) {
			port = new Port();
		}
		transport(portModel, port);

		Network network = networkRepository.getByNetId(portModel.getNetworkUuid());
		if (network != null) {
			port.setNetworkId(network.getId());
			port.setNetworkUuid(network.getNetworkUuid());
		}

		port.setVendorId(vendor.getId());
		port.setMenderId(userId);
		if (port.getId() == null) {
			port.setCreatorId(userId);
			portRepository.save(port);
		} else {
			portRepository.update(port);
		}

		syncPortFixedIp(port, portModel.getPortFixedIps(), userId);

		CloudServer cloudServer = cloudServerRepository.getByInstanceId(portModel.getDeviceUuid(), vendor.getId());
		if (cloudServer != null) {
			saveCmdb(userId, Collections.singletonList(getCmdbInfoFromCloudServer(cloudServer)));
		}

		return port;
	}

	/**
	 * 添加或修改一个PortFixedIp
	 *
	 * @param port
	 * @param portFixedIpModel
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public PortFixedIp insertOrUpdate(Port port, PortFixedIpModel portFixedIpModel, long userId) {
		PortFixedIp portFixedIp = portFixedIpRepository.getByPortIdAndIp(port.getId(), portFixedIpModel.getIpAddress());
		if (portFixedIp == null) {
			portFixedIp = new PortFixedIp();
		}
		transport(portFixedIpModel, portFixedIp);

		Subnet subnet = subnetRepository.getBySubId(portFixedIpModel.getSubnetUuid());
		if (subnet != null) {
			portFixedIp.setSubnetId(subnet.getId());
			portFixedIp.setSubnetUuid(subnet.getSubnetUuid());
		}

		portFixedIp.setPortId(port.getId());
		portFixedIp.setPortUuid(port.getPortUuid());
		if (portFixedIp.getId() == null) {
			portFixedIpRepository.save(portFixedIp);
		} else {
			portFixedIpRepository.update(portFixedIp);
		}
		return portFixedIp;
	}

	/**
	 * 添加或修改一个Flavor
	 *
	 * @param vendor      该Flavor所属Network
	 * @param flavorModel 该Flavor
	 * @param userId      当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Flavor insertOrUpdate(CloudVendor vendor, FlavorModel flavorModel, long userId) {
		Flavor flavor = flavorRepository.getByFlavorUuid(flavorModel.getFlavorUuid());
		FlavorExtraSpecs flavorExtraSpecs;
		if (flavor == null) {
			flavor = new Flavor();
			flavorExtraSpecs = new FlavorExtraSpecs();
		} else {
			flavorExtraSpecs = flavorExtraSpecsRepository.query(flavor.getExtraSpecsId());
		}
		transport(flavorModel, flavor, flavorExtraSpecs);
		flavor.setVendorId(vendor.getId());

		if (flavor.getId() == null) {
			flavorExtraSpecsRepository.save(flavorExtraSpecs);
			flavor.setExtraSpecsId(flavorExtraSpecs.getId());
			flavorRepository.save(flavor);
		} else {
			flavorExtraSpecsRepository.updateEntity(flavorExtraSpecs);
			flavorRepository.update(flavor);
		}
		return flavor;
	}

	/**
	 * 添加或修改一个主机组
	 *
	 * @param vendor
	 * @param clusterModel
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Cluster insertOrUpdate(CloudVendor vendor, ClusterModel clusterModel, long userId) {
		// 先处理Cluster中自己的信息
		Cluster cluster = clusterRepository.queryByUuid(clusterModel.getUuid(), vendor.getId());
		if (cluster == null) {
			cluster = new Cluster();
		}
		transport(clusterModel, cluster);
		cluster.setVendorId(vendor.getId());

		if (cluster.getId() == null) {
			cluster.setGuid(IDFactory.instance().uuid());
			clusterRepository.save(cluster);
		} else {
			clusterRepository.update(cluster);
		}
		// 再处理该cluster对应的主机
		List<Server> oldServers = serverRepository.listByCluster(cluster.getId());
		List<String> oldHostNames = new ArrayList<>();
		for (Server oldServer : oldServers) {
			oldHostNames.add(oldServer.getHostname());
		}
		List<String> newHostNames = clusterModel.getHostNames();
		List<String> hostsToAdd = new ArrayList<>(newHostNames);
		List<String> hostsToDelete = new ArrayList<>(oldHostNames);
		hostsToAdd.removeAll(oldHostNames);
		hostsToDelete.removeAll(newHostNames);
		Cluster defaultCluster = clusterRepository.queryByUuid(PowervcConstant.DEFAULT_OS_AGGREGATE_ID, vendor.getId());
		for (String hostName : hostsToAdd) {
			Server server = serverRepository.getByHostName(hostName, vendor.getId());
			server.setClusterId(cluster.getId());
			serverRepository.update(server);
		}
		for (String hostName : hostsToDelete) {
			Server server = serverRepository.getByHostName(hostName, vendor.getId());
			server.setClusterId(defaultCluster.getId());
			serverRepository.update(server);
		}
		// 通知cmdb
		List<Server> servers = serverRepository.listByCluster(cluster.getId());
		List<String> serverGuids = new ArrayList<>();
		for (Server server : servers) {
			serverGuids.add(server.getGuid());
		}
		List<CmdbRelation> cmdbRelations = Collections
				.singletonList(new CmdbRelation(ModuleCode.PM.name(), 1L, serverGuids));
		List<CmdbInfo> cmdbInfos = Collections.singletonList(CmdbInfoConvertor.getInfo(cluster, null, cmdbRelations));
		saveCmdb(userId, cmdbInfos);

		servers = serverRepository.listByCluster(defaultCluster.getId());
		serverGuids = new ArrayList<>();
		for (Server server : servers) {
			serverGuids.add(server.getGuid());
		}
		cmdbRelations = Collections.singletonList(new CmdbRelation(ModuleCode.PM.name(), 1L, serverGuids));
		cmdbInfos = Collections.singletonList(CmdbInfoConvertor.getInfo(defaultCluster, null, cmdbRelations));
		saveCmdb(userId, cmdbInfos);

		// 最终返回cluster
		return cluster;
	}

	/**
	 * 添加或修改一个存储池
	 *
	 * @param storage
	 * @param volumePoolModel
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public VolumePool insertOrUpdate(Storage storage, VolumePoolModel volumePoolModel, long userId) {
		VolumePool volumePool = volumePoolRepository.getByUuid(volumePoolModel.getUuid(), storage.getId());
		if (volumePool == null) {
			volumePool = new VolumePool();
		}
		transport(volumePoolModel, volumePool);
		volumePool.setMenderId(userId);
		volumePool.setVendorId(storage.getVendorId());
		volumePool.setStorageId(storage.getId());
		if (volumePool.getId() == null) {
			volumePool.setCreatorId(userId);
			volumePoolRepository.save(volumePool);
		} else {
			volumePoolRepository.update(volumePool);
		}
		return volumePool;
	}

	/**
	 * 添加或修改一个Sea
	 *
	 * @param vendor     该ClusterModel所属平台
	 * @param seaAdapter seaAdapter
	 * @param userId     当前用户
	 */
	@Transactional(rollbackFor = Throwable.class)
	public HostSeaAdapter insertOrUpdate(CloudVendor vendor, HostSeaAdapter seaAdapter, long userId) {
		HostSeaAdapter adapterOld = hostSeaRepository.getByName(seaAdapter.getSeaName(), seaAdapter.getLparId(),
				seaAdapter.getServerHost(), vendor.getId());
		if (adapterOld != null) {
			seaAdapter.setId(adapterOld.getId());
		}

		Server server = serverRepository.getByHostName(seaAdapter.getServerHost(), vendor.getId());
		if (server != null) {
			seaAdapter.setServerId(server.getId());
		}

		seaAdapter.setVendorId(vendor.getId());
		if (seaAdapter.getId() == null) {
			hostSeaRepository.save(seaAdapter);
		} else {
			hostSeaRepository.updateEntity(seaAdapter);
		}
		return seaAdapter;
	}

	/**
	 * 添加或修改一个SanFabrics
	 *
	 * @param vendor
	 * @param fabricsModel
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Throwable.class)
	public SanFabric insertOrUpdate(CloudVendor vendor, SanFabricModel fabricsModel, long userId) {
		SanFabric fabrics = sanFabricRepository.getByUuid(fabricsModel.getName(), vendor.getId());
		if (fabrics == null) {
			fabrics = new SanFabric();
		}
		transport(fabricsModel, fabrics);
		fabrics.setMenderId(userId);
		fabrics.setVendorId(vendor.getId());
		if (fabrics.getId() == null) {
			fabrics.setCreatorId(userId);
			sanFabricRepository.save(fabrics);
		} else {
			sanFabricRepository.update(fabrics);
		}
		return fabrics;
	}

	public void transport(HmcHostModel hmcHostModel, PowervcHmc powervcHmc) {
		if (hmcHostModel == null || powervcHmc == null) {
            return;
        }

		powervcHmc.setIp(hmcHostModel.getIp());
		powervcHmc.setUuid(hmcHostModel.getUuid());
		powervcHmc.setUsername(hmcHostModel.getUsername());
		powervcHmc.setPassword(hmcHostModel.getPassword());
		powervcHmc.setGmtCreate(hmcHostModel.getGmtCreate());
		powervcHmc.setName(hmcHostModel.getName());
		powervcHmc.setStatus(hmcHostModel.getStatus().getStatus());
	}

	public void transport(HostModel hostModel, Server server, ServerConfig serverConfig) {
		if (hostModel == null || server == null || serverConfig == null) {
            return;
        }

		server.setUuid(hostModel.getUuid());
		server.setName(hostModel.getName());
		server.setHostname(hostModel.getHostName());
		server.setManageIp(hostModel.getHostIp());
		server.setCategory(hostModel.getCategory());
		server.setPowerState(hostModel.getPowerState());
		server.setStatus(hostModel.getStatus());
		server.setVmNum(hostModel.getVmNum());

		serverConfig.setCpuVendor(hostModel.getCpuVendor());
		serverConfig.setCpuMode(hostModel.getCpuModel());
		serverConfig.setCpuHz(hostModel.getCpuHz());
		serverConfig.setCpuAmount(hostModel.getCpuNum());
		serverConfig.setCpuCore(hostModel.getCpuCore());
		serverConfig.setCpuUsed(hostModel.getCpuUsed());
		serverConfig.setHmcCpu(hostModel.getHmcCpu());
		serverConfig.setHmcCpuReserved(hostModel.getHmcCpuReserved());
		serverConfig.setHmcCpuUsed(hostModel.getHmcCpuUsed());
		serverConfig.setDiskCapacity(hostModel.getDiskTotal());
		serverConfig.setDiskUsed(hostModel.getDiskUsed());
		serverConfig.setMemoryCapacity(hostModel.getMemTotal());
		serverConfig.setMemUsed(hostModel.getMemUsed());
		serverConfig.setMemReserved(hostModel.getMemReserved());
	}

	public void transport(ServerModel serverModel, CloudServer cloudServer) {
		if (serverModel == null || cloudServer == null) {
            return;
        }

		cloudServer.setInstanceId(serverModel.getInstanceId());
		cloudServer.setName(serverModel.getName());
		cloudServer.setStatus(serverModel.getStatus());
		cloudServer.setImageUuid(serverModel.getImageUuid());
		cloudServer.setHostName(serverModel.getHostName());
		cloudServer.setFlavorUuid(serverModel.getFlavorUuid());
		cloudServer.setGmtCreate(serverModel.getGmtVmCreate());
		cloudServer.setGmtModify(serverModel.getGmtModify());
		cloudServer.setCpu(serverModel.getCpu());
		cloudServer.setHmcCpu(serverModel.getHmcCpu());
		cloudServer.setMemory(serverModel.getMemory());
		cloudServer.setDisk(serverModel.getDisk());
		cloudServer.setPrivateIps(serverModel.getPrivateIps());
		cloudServer.setOsName(serverModel.getOsName());
		cloudServer.setIsTemplate(false);
		cloudServer.setRecycle(false);
		cloudServer.setProps(serverModel.getProps());

		if (serverModel.getDiskDevices() == null) {
			cloudServer.setDiskDevices(null);
		} else if (serverModel.getDiskDevices().size() == 0) {
			cloudServer.setDiskDevices(new ArrayList<>(0));
		} else {
			List<Volume> oldVolumes = cloudServer.getDiskDevices() == null ? new ArrayList<>()
					: cloudServer.getDiskDevices();
			List<Volume> newVolumes = new ArrayList<>();
			for (VolumeModel driverVolume : serverModel.getDiskDevices()) {
				boolean driverVolumeInOldVolumes = false;
				for (Volume oldVolume : oldVolumes) {
					if (oldVolume.getVolumeUuid().equals(driverVolume.getVolumeUuid())) {
						transport(driverVolume, oldVolume);
						newVolumes.add(oldVolume);
						driverVolumeInOldVolumes = true;
						break;
					}
				}
				if (!driverVolumeInOldVolumes) {
					Volume newVolume = new Volume();
					transport(driverVolume, newVolume);
					newVolumes.add(newVolume);
				}
			}
			cloudServer.setDiskDevices(newVolumes);
		}
	}

	public void transport(StorageModel storageModel, Storage storage) {
		if (storageModel == null || storage == null) {
            return;
        }

		storage.setUuid(storageModel.getUuid());
		storage.setName(storageModel.getName());
		storage.setStatus(storageModel.getStatus());
		storage.setIp(storageModel.getIp());
		storage.setHost(storageModel.getHost());
		storage.setType(storageModel.getType());
		storage.setTotalCapacity(storageModel.getTotalCapacity());
		storage.setFreeCapaticy(storageModel.getFreeCapaticy());
		storage.setCompressionSuppoerd(storageModel.getCompressionSuppoerd());
		storage.setDefaultTemplateUuid(storageModel.getDefaultTemplateUuid());

	}

	public void transport(VolumeTemplateModel volumeTemplateModel, VolumeTemplate volumeTemplate) {
		if (volumeTemplateModel == null || volumeTemplate == null) {
            return;
        }

		volumeTemplate.setUuid(volumeTemplateModel.getUuid());
		volumeTemplate.setName(volumeTemplateModel.getName());
		volumeTemplate.setDescription(volumeTemplateModel.getDescription());
		volumeTemplate.setIsPublic(volumeTemplateModel.getIsPublic());
		volumeTemplate.setAutoExpand(volumeTemplateModel.getAutoExpand());
		volumeTemplate.setCompress(volumeTemplateModel.getCompress());
		volumeTemplate.setIoGroup(volumeTemplateModel.getIoGroup());
		volumeTemplate.setCopyCount(volumeTemplateModel.getCopyCount());
		volumeTemplate.setMultipath(volumeTemplateModel.getMultipath());
		volumeTemplate.setCapacityPercent(volumeTemplateModel.getCapacityPercent());
		volumeTemplate.setWarningPercent(volumeTemplateModel.getWarningPercent());
		volumeTemplate.setGrainsize(volumeTemplateModel.getGrainsize());
		volumeTemplate.setOriginName(volumeTemplateModel.getOriginName());
		if (volumeTemplateModel.getCapacityPercent() == null && volumeTemplateModel.getCompress() == null) {
			volumeTemplate.setType(PowervcConstant.VOLUME_TEMPLATE_TYPE_HOT);
		} else if (volumeTemplateModel.getCapacityPercent() == -1) {
			volumeTemplate.setType(PowervcConstant.VOLUME_TEMPLATE_TYPE_COMMON);
		} else if (volumeTemplateModel.getCompress() == false) {
			volumeTemplate.setType(PowervcConstant.VOLUME_TEMPLATE_TYPE_SIMPLE);
		} else {
			volumeTemplate.setType(PowervcConstant.VOLUME_TEMPLATE_TYPE_COMPRESS);
		}
	}

	public void transport(VolumeModel volumeModel, Volume volume) {
		if (volumeModel == null || volume == null) {
            return;
        }

		volume.setInstanceId(volumeModel.getInstanceId());
		volume.setVolumeUuid(volumeModel.getVolumeUuid());
		volume.setName(volumeModel.getName());
		volume.setBootVolume(volumeModel.getBootVolume());
		volume.setType(volumeModel.getType());
		volume.setCategory(volumeModel.getCategory());
		volume.setSize(volumeModel.getSize());
		volume.setStatus(volumeModel.getStatus());
		volume.setZone(volumeModel.getZone());
		volume.setCreateTime(volumeModel.getCreateTime());
		volume.setProps(volumeModel.getProps());
		volume.setRemark(volumeModel.getRemark());
		volume.setModels(volumeModel.getModels());
		volume.setMultiattach(volumeModel.getMultiattach());
		volume.setPoolId(volumeModel.getPoolId());
	}

	public void transport(ImageModel imageModel, Image image) {
		if (imageModel == null || image == null) {
            return;
        }

		image.setImageUuid(imageModel.getImageUuid());
		image.setName(imageModel.getName());
		image.setStatus(imageModel.getStatus());
		image.setFilePath(imageModel.getFilePath());
		image.setMinDisk(imageModel.getMinDisk());
		image.setOsName(imageModel.getOsName());
		image.setGmtCreate(imageModel.getGmtCreate());
		image.setProps(imageModel.getProps());
		image.setRemark(imageModel.getRemark());
	}

	public void transport(SubnetModel subnetModel, Subnet subnet) {
		if (subnetModel == null || subnet == null) {
            return;
        }

		subnet.setSubnetUuid(subnetModel.getSubnetUuid());
		subnet.setName(subnetModel.getName());
		subnet.setNetworkUuid(subnetModel.getNetworkUuid());
		subnet.setGateway(subnetModel.getGateway());
		subnet.setDnsNames(subnetModel.getDnsNames());
		subnet.setIpVersion(subnetModel.getIpVersion());
		subnet.setDhcpEnabled(subnetModel.getDhcpEnabled());
		subnet.setIpPools(subnetModel.getIpPools());
		subnet.setCidr(subnetModel.getCidr());
	}

	public void transport(PortModel portModel, Port port) {
		if (portModel == null || port == null) {
            return;
        }

		port.setPortUuid(portModel.getPortUuid());
		port.setDeviceUuid(portModel.getDeviceUuid());
		port.setDeviceOwner(portModel.getDeviceOwner());
		port.setStatus(portModel.getStatus());
		port.setMacAddress(portModel.getMacAddress());
		port.setRemark(portModel.getRemark());

		List<PortFixedIp> oldIps = port.getPortFixedIps() == null ? new ArrayList<>() : port.getPortFixedIps();
		List<PortFixedIp> newIps = new ArrayList<>();
		for (PortFixedIpModel driverIp : portModel.getPortFixedIps()) {
			boolean driverIpInOldIps = false;
			for (PortFixedIp oldIp : oldIps) {
				if (oldIp.getIpAddress().equals(driverIp.getIpAddress())) {
					transport(driverIp, oldIp);
					newIps.add(oldIp);
					driverIpInOldIps = true;
					break;
				}
			}
			if (!driverIpInOldIps) {
				PortFixedIp newIp = new PortFixedIp();
				transport(driverIp, newIp);
				newIps.add(newIp);
			}
		}
		port.setPortFixedIps(newIps);
	}

	public void transport(PortFixedIpModel portFixedIpModel, PortFixedIp portFixedIp) {
		if (portFixedIpModel == null || portFixedIp == null) {
            return;
        }

		portFixedIp.setSubnetUuid(portFixedIpModel.getSubnetUuid());
		portFixedIp.setIpAddress(portFixedIpModel.getIpAddress());
	}

	public void transport(NetworkModel networkModel, Network network) {
		if (networkModel == null || network == null) {
            return;
        }

		network.setNetworkUuid(networkModel.getNetworkUuid());
		network.setName(networkModel.getName());
		network.setType(networkModel.getType());
		network.setShared(networkModel.getShared());
		network.setStatus(networkModel.getStatus());
		network.setSegmentationId(networkModel.getSegmentationId());
		network.setAdminStateup(networkModel.getAdminStateup());
		network.setIsRouterExternal(networkModel.getIsRouterExternal());
		network.setPhyNetwork(networkModel.getPhyNetwork());
		network.setMtu(networkModel.getMtu());

		if (networkModel.getSubnets() == null) {
			network.setSubnets(null);
		} else if (networkModel.getSubnets().size() == 0) {
			network.setSubnets(new ArrayList<>(0));
		} else {
			List<Subnet> oldSubnets = network.getSubnets() == null ? new ArrayList<>() : network.getSubnets();
			List<Subnet> newSubjects = new ArrayList<>();
			for (SubnetModel driverSubnet : networkModel.getSubnets()) {
				boolean driverSubnetInOldSubnet = false;
				for (Subnet oldSubject : oldSubnets) {
					if (oldSubject.getSubnetUuid().equals(driverSubnet.getSubnetUuid())) {
						transport(driverSubnet, oldSubject);
						newSubjects.add(oldSubject);
						driverSubnetInOldSubnet = true;
						break;
					}
				}
				if (!driverSubnetInOldSubnet) {
					Subnet newSubject = new Subnet();
					transport(driverSubnet, newSubject);
					newSubjects.add(newSubject);
				}
			}
			network.setSubnets(newSubjects);
		}
	}

	public void transport(FlavorModel flavorModel, Flavor flavor, FlavorExtraSpecs flavorExtraSpecs) {
		if (flavorModel == null || flavor == null || flavorExtraSpecs == null) {
            return;
        }

		flavor.setFlavorUuid(flavorModel.getFlavorUuid());
		flavor.setName(flavorModel.getName());
		flavor.setStatus(flavorModel.getStatus());
		flavor.setCpu(flavorModel.getCpu());
		flavor.setMemory(flavorModel.getMemory());
		flavor.setDisk(flavorModel.getDisk());

		flavorExtraSpecs.setPriority(flavorModel.getExtraSpecs().getPriority());
		flavorExtraSpecs.setDedicatedProc(flavorModel.getExtraSpecs().getDedicatedProc());
		flavorExtraSpecs.setPriority(flavorModel.getExtraSpecs().getPriority());
		flavorExtraSpecs.setMaxMem(flavorModel.getExtraSpecs().getMaxMem());
		flavorExtraSpecs.setMinMem(flavorModel.getExtraSpecs().getMinMem());
		flavorExtraSpecs.setMaxProcUnits(flavorModel.getExtraSpecs().getMaxProcUnits());
		flavorExtraSpecs.setMinProcUnits(flavorModel.getExtraSpecs().getMinProcUnits());
		flavorExtraSpecs.setProcUnits(flavorModel.getExtraSpecs().getProcUnits());
		flavorExtraSpecs.setMaxVcpu(flavorModel.getExtraSpecs().getMaxVcpu());
		flavorExtraSpecs.setMinVcpu(flavorModel.getExtraSpecs().getMinVcpu());
		flavorExtraSpecs.setSharedWeight(flavorModel.getExtraSpecs().getSharedWeight());
		flavorExtraSpecs.setUncapped(flavorModel.getExtraSpecs().getUncapped());
		flavorExtraSpecs.setProcCompatibility(flavorModel.getExtraSpecs().getProcCompatibility());
	}

	public void transport(ClusterModel clusterModel, Cluster cluster) {
		if (clusterModel == null || cluster == null) {
            return;
        }

		cluster.setUuid(clusterModel.getUuid());
		cluster.setName(clusterModel.getName());
		cluster.setStatus(clusterModel.getStatus());
		cluster.setInitialPolicy(clusterModel.getInitialPolicy());
	}

	public void transport(VolumePoolModel volumePoolModel, VolumePool volumePool) {
		if (volumePoolModel == null || volumePool == null) {
            return;
        }

		volumePool.setName(volumePoolModel.getName());
		volumePool.setStatus(volumePoolModel.getStatus());
		volumePool.setUuid(volumePoolModel.getUuid());
		volumePool.setWarning(volumePoolModel.getWarning());
		volumePool.setOverallocation(volumePoolModel.getOverallocation());
		volumePool.setExtentSize(volumePoolModel.getExtentSize());
		volumePool.setCapacity(volumePoolModel.getCapacity());
		volumePool.setRealCapacity(volumePoolModel.getRealCapacity());
		volumePool.setUsedCapacity(volumePoolModel.getUsedCapacity());
		volumePool.setVirtualCapacity(volumePoolModel.getVirtualCapacity());
		volumePool.setFreeCapacity(volumePoolModel.getFreeCapacity());
		volumePool.setCompressionActive(volumePoolModel.getCompressionActive());
		volumePool.setCompressionVirtualCapacity(volumePoolModel.getCompressionVirtualCapacity());
		volumePool.setCompressionCompressedCapacity(volumePoolModel.getCompressionCompressedCapacity());
		volumePool.setCompressionUncompressedCapacity(volumePoolModel.getCompressionUncompressedCapacity());
		volumePool.setEasytier(volumePoolModel.getEasytier());
		volumePool.setEasytierStatus(volumePoolModel.getEasytierStatus());
		volumePool.setMdiskCount(volumePoolModel.getMdiskCount());
		volumePool.setVdiskCount(volumePoolModel.getVdiskCount());
	}

	public void transport(SanFabricModel sanFabricModel, SanFabric sanFabric) {
		if (sanFabricModel == null || sanFabric == null) {
            return;
        }

		sanFabric.setUuid(sanFabricModel.getName());
		sanFabric.setName(sanFabricModel.getNickName());
		sanFabric.setIp(sanFabricModel.getIp());
		sanFabric.setUsername(sanFabricModel.getUsername());
		sanFabric.setPassword(sanFabricModel.getPassword());
		sanFabric.setType(sanFabricModel.getType());
		sanFabric.setPolicy(sanFabricModel.getPolicy());
		sanFabric.setProtocol(sanFabricModel.getProtocol());
	}

	public CmdbInfo getCmdbInfoFromCloudVendor(long cloudVendorId) {
		CloudVendor cloudVendor = cloudVendorRepository.query(cloudVendorId);
		return getCmdbInfoFromCloudVendor(cloudVendor);
	}

	public CmdbInfo getCmdbInfoFromCloudVendor(CloudVendor cloudVendor) {
		return CmdbInfoConvertor.getInfo(cloudVendor, null, null);
	}

	public CmdbInfo getCmdbInfoFromServer(long serverId) {
		Server server = serverRepository.query(serverId);
		return getCmdbInfoFromServer(server);
	}

	public CmdbInfo getCmdbInfoFromServer(Server server) {
		List<CmdbRelation> cmdbRelations = new ArrayList<>();
		// 主机和平台关系
		CloudVendor cloudVendor = cloudVendorRepository.query(server.getVendorId());
		if (cloudVendor != null) {
			cmdbRelations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 1L, Arrays.asList(cloudVendor.getGuid())));
			cmdbRelations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 2L, Arrays.asList(cloudVendor.getGuid())));
		}
		// 主机和云主机关系
		List<CloudServer> cloudServers = cloudServerRepository.listByHid(server.getId());
		if (cloudServers.size() > 0) {
			List<String> cloudServerGuids = new ArrayList<>();
			for (CloudServer cloudServer : cloudServers) {
				cloudServerGuids.add(cloudServer.getGuid());
			}
			cmdbRelations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 1L, cloudServerGuids));
			cmdbRelations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 2L, cloudServerGuids));
		}
		// 主机和主机组关系
		Cluster cluster = clusterRepository.query(server.getClusterId());
		if (cluster != null) {
			cmdbRelations.add(new CmdbRelation(ModuleCode.CLUSTER.name(), 1L, Arrays.asList(cluster.getGuid())));
		}
		// 主机信息
		ServerConfig serverConfig = serverConfigRepository.getBySid(server.getId());
		return CmdbInfoConvertor.getInfo(server, serverConfig, null, cmdbRelations);
	}

	public CmdbInfo getCmdbInfoFromCloudServer(long cloudServerId) {
		CloudServer cloudServer = cloudServerRepository.query(cloudServerId);
		return getCmdbInfoFromCloudServer(cloudServer);
	}

	public CmdbInfo getCmdbInfoFromCloudServer(CloudServer cloudServer) {
		List<CmdbRelation> cmdbRelations = new ArrayList<>();
		// 云主机和主机关系
		Server server = serverRepository.query(cloudServer.getHostId());
		if (server != null) {
			cmdbRelations.add(new CmdbRelation(ModuleCode.PM.name(), 1L, Arrays.asList(server.getGuid())));
			cmdbRelations.add(new CmdbRelation(ModuleCode.PM.name(), 2L, Arrays.asList(server.getGuid())));
		}
		// 云主机和网络关系
		List<Port> ports = portRepository.listByDeviceId(cloudServer.getInstanceId(), cloudServer.getVendorId());
		if (ports.size() > 0) {
			List<String> networkGuids = new ArrayList<>();
			List<String> subnetGuids = new ArrayList<>();
			for (Port port : ports) {
				Network network = networkRepository.query(port.getNetworkId());
				networkGuids.add(network.getGuid());
				List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
				for (Subnet subnet : subnets) {
					subnetGuids.add(subnet.getGuid());
				}
			}
			cmdbRelations.add(new CmdbRelation(ModuleCode.NETWORK.name(), 1L, networkGuids));
			cmdbRelations.add(new CmdbRelation(ModuleCode.NETWORK.name(), 2L, networkGuids));
			cmdbRelations.add(new CmdbRelation(ModuleCode.SUBNET.name(), 2L, subnetGuids));
		}
		return CmdbInfoConvertor.getInfo(cloudServer, null, cmdbRelations);
	}

	public CmdbInfo getCmdbInfoFromCluster(long clusterId) {
		Cluster cluster = clusterRepository.query(clusterId);
		return getCmdbInfoFromCluster(cluster);
	}

	public CmdbInfo getCmdbInfoFromCluster(Cluster cluster) {
		List<CmdbRelation> cmdbRelations = new ArrayList<>();
		// 主机组和主机关系
		List<Server> servers = serverRepository.listByCluster(cluster.getId());
		if (servers.size() > 0) {
			List<String> serverGuids = new ArrayList<>();
			for (Server server : servers) {
				serverGuids.add(server.getGuid());
			}
			cmdbRelations.add(new CmdbRelation(ModuleCode.PM.name(), 1L, serverGuids));
		}
		// 主机组信息
		return CmdbInfoConvertor.getInfo(cluster, null, cmdbRelations);
	}

	public CmdbInfo getCmdbInfoFromNetwork(long networkId) {
		Network network = networkRepository.query(networkId);
		return getCmdbInfoFromNetwork(network);
	}

	public CmdbInfo getCmdbInfoFromNetwork(Network network) {

		List<CmdbRelation> cmdbRelations = new ArrayList<>();
		// 网络和平台关系
		CloudVendor cloudVendor = cloudVendorRepository.query(network.getVendorId());
		if (cloudVendor != null) {
			cmdbRelations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 1L, Arrays.asList(cloudVendor.getUuid())));
			cmdbRelations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 2L, Arrays.asList(cloudVendor.getUuid())));
			cmdbRelations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 2L, Arrays.asList(cloudVendor.getUuid())));
		}
		// 网络和云主机关系
		List<CloudServer> cloudServers = cloudServerRepository.listByNetworkId(network.getId());
		if (cloudServers.size() > 0) {
			List<String> networkGuids = new ArrayList<>();
			for (CloudServer cloudServer : cloudServers) {
				networkGuids.add(cloudServer.getGuid());
			}
			cmdbRelations.add(new CmdbRelation(ModuleCode.VM.name(), 1L, networkGuids));
			cmdbRelations.add(new CmdbRelation(ModuleCode.VM.name(), 2L, networkGuids));
		}
		// 网络和子网关系
		List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
		if (subnets.size() > 0) {
			List<String> subnetGuids = new ArrayList<>();
			for (Subnet subnet : subnets) {
				subnetGuids.add(subnet.getGuid());
			}
			cmdbRelations.add(new CmdbRelation(ModuleCode.SUBNET.name(), 1L, subnetGuids));
			cmdbRelations.add(new CmdbRelation(ModuleCode.SUBNET.name(), 2L, subnetGuids));
		}
		// 网络信息
		return CmdbInfoConvertor.getInfo(network, null, cmdbRelations);
	}

	public CmdbInfo getCmdbInfoFromSubnet(long subnetId) {
		Subnet subnet = subnetRepository.query(subnetId);
		return getCmdbInfoFromSubnet(subnet);
	}

	public CmdbInfo getCmdbInfoFromSubnet(Subnet subnet) {
		List<CmdbRelation> cmdbRelations = new ArrayList<>();
		// 子网和网络关系
		Network network = networkRepository.query(subnet.getNetworkId());
		if (network != null) {
			cmdbRelations.add(new CmdbRelation(ModuleCode.NETWORK.name(), 1L, Arrays.asList(network.getGuid())));
			cmdbRelations.add(new CmdbRelation(ModuleCode.NETWORK.name(), 2L, Arrays.asList(network.getGuid())));
		}
		// 子网和云主机关系
		List<Port> ports = portRepository.listBySubnetId(subnet.getId());
		if (ports.size() > 0) {
			List<String> cloudServerGuids = new ArrayList<>();
			for (Port port : ports) {
				if (StringUtils.isNotEmpty(port.getDeviceUuid())) {
					CloudServer cloudServer = cloudServerRepository.getByInstanceId(port.getDeviceUuid(),
							subnet.getVendorId());
					if (cloudServer != null) {
						cloudServerGuids.add(cloudServer.getGuid());
					}
				}
			}
			cmdbRelations.add(new CmdbRelation(ModuleCode.VM.name(), 2L, cloudServerGuids));
		}
		// 子网信息
		return CmdbInfoConvertor.getInfo(subnet, null, cmdbRelations);
	}
}
