package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.compute.HostSeaDriver;
import com.bocloud.cmp.driver.network.NetworkDriver;
import com.bocloud.cmp.driver.network.SubnetDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.entity.enums.NetworkType;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.*;
import com.bocloud.cmp.provider.utils.IPAddress;
import com.bocloud.common.model.*;
import com.bocloud.common.model.OperateResult.OperateCategory;
import com.bocloud.common.utils.*;
import com.bocloud.ims.entity.common.Project;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.powervc.HostSeaAdapter;
import com.bocloud.ims.entity.resource.powervc.NetworkSeaAdapter;
import com.bocloud.ims.interfaces.resource.NetworkService;
import com.bocloud.ims.interfaces.resource.VendorProjectService;
import com.bocloud.ims.interfaces.resource.VpcService;
import com.bocloud.ims.repository.powervc.HostSeaRepository;
import com.bocloud.ims.repository.powervc.NetworkSeaRepository;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.service.internal.SmsProjectService;
import com.bocloud.ims.service.transportor.PowervcTransportor;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

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

/**
 * 网络Service接口实现
 *
 * @author weiwei
 */
@Service("networkService")
public class NetworkServiceImpl implements NetworkService {

	private static OperateCategory operateCategory = OperateCategory.ResourceEvent;
	private static Logger logger = LoggerFactory.getLogger(NetworkServiceImpl.class);
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private NetworkRepository networkRepository;
	@Autowired
	private NetworkSeaRepository networkSeaRepository;
	@Autowired
	private HostSeaRepository hostSeaRepository;
	@Autowired
	private PowervcTransportor powervcTransportor;
	@Autowired
	private NetworkHostRepository networkHostRepository;
	@Autowired
	private PortGroupRepository portGroupRepository;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private RegionRepository regionRepository;
	@Autowired
	private SubnetRepository subnetRepository;
	@Autowired
	private PortRepository portRepository;
	@Autowired
	private ServerRepository serverRepository;
	@Autowired
	private HostSeaDriver hostSeaDriver;
	@Autowired
	private ServerConfigRepository serverConfigRepository;
	@Autowired
	private NetworkCardRepository networkCardRepository;
	@Autowired
	private CloudServerRepository cloudServerRepository;
	@Autowired
	private ClusterRepository clusterRepository;
	@Autowired
	private SnapshotRepository snapshotRepository;
	@Autowired
	private SwitcherRepository switcherRepository;
	@Autowired
	private VdcRepository vdcRepository;
	@Autowired
	private IpRepository ipRepository;
	@Autowired
	private TenantNetworkRepository tenantNetworkRepository;
	@Autowired
	private NetworkDriver networkDriver;
	@Autowired
	private SubnetDriver subnetDriver;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private SmsProjectService smsProjectService;
	@Autowired
	private VendorProjectService vendorProjectService;
	@Autowired
	private OSTenantRepository oSTenantRepository;
	@Autowired
	private AmqpTemplate amqpTemplate;
	@Autowired
	private RouterRepository routerRepository;
	@Autowired
	private VpcRepository vpcRepository;
	@Autowired
	private VpcService vpcService;

	@Override
	public BocloudResult<GridBean<Network>> list(Pager pager, RequestContext context) {
		try {
			int page = pager.getPage();
			int rows = pager.getRows();
			List<Param> params = pager.getParams();
			Map<String, String> sorter = pager.getSorter();
			boolean simple = pager.getSimple();

			GridBean gridBean = null;
			int total = 0;
			List<Network> list = Lists.newArrayList();
			params = Optional.ofNullable(params).orElse(new ArrayList<>());
			sorter = Optional.ofNullable(sorter).orElse(Maps.newHashMap());
			sorter.put("gmtCreate", Common.ONE);
			Long tenantId = context.getTenant();
			if (null != tenantId && 0L != tenantId) {
				total = this.networkRepository.count(params, tenantId, context.getProject());
				list = this.networkRepository.list(page, rows, params, sorter, tenantId, context.getProject());
				gridBean = GridHelper.getBean(page, rows, total, list);
			} else {
				total = networkRepository.count(params);
				if (simple) {
					List<SimpleBean> beans = networkRepository.list(params, sorter, tenantId);
					gridBean = new GridBean(1, 1, total, beans);
				} else {
					list = networkRepository.list(page, rows, params, sorter);
					for (Network network : list) {
						List<TenantNetwork> tenantNetworks = tenantNetworkRepository.listByNetworkId(network.getId());
						String tenantName = "";
						for (TenantNetwork tenantNetwork : tenantNetworks) {
							if (null != tenantNetwork && !StringUtils.isEmpty(tenantNetwork.getTenantName())) {
								tenantName += tenantNetwork.getTenantName() + ",";
							}
						}
						if (tenantName.length() > 0) {
							tenantName = tenantName.substring(0, tenantName.length() - 1);
							// 天津港 项目需要
							network.setProjectVisibility("TenantProject");
						}
						network.setTenantName(tenantName);

						List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
						for (Subnet subnet : subnets) {
							IPAddress address = IPAddress
									.getIPAddress(subnet.getCidr().substring(0, subnet.getCidr().indexOf("/")));
							subnet.setNetmask(address.getMask(subnet.getCidr()));
						}
						network.setSubnets(subnets);
						network.setSubnetNum((long) subnets.size());
					}
					gridBean = GridHelper.getBean(page, rows, total, list);
				}
			}
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("list network failure:", e);
			return new BocloudResult<>(false, "查询失败", null, null);
		}
	}

	@Override
	public BocloudResult condition(String condition, RequestContext context) {
		try {

			JSONObject object = JSONObject.parseObject(condition);
			if ("listNetAndSubNet".equalsIgnoreCase(object.getString("condition"))) {
				return this.listNetAndSubNet(object.getLong(Common.VENDORID), object.getString("tenantUuid"), context);
			} else if ("listRouterAndSubNet".equalsIgnoreCase(object.getString("condition"))) {
				return this.listRouterAndSubNet(condition, context);
			} else if ("listServerRouters".equalsIgnoreCase(object.getString("condition"))) { // 虚机批量查询网卡信息
				return this.listServerRouters(condition, context);
			} else if ("externals".equalsIgnoreCase(object.getString("condition"))) {
				return this.listExternal(object.getLong(Common.VENDORID), context);
			} else if ("listNetworkByHostId".equalsIgnoreCase(object.getString("condition"))) {
				return this.listNetworkByHostId(object.getLong("hostId"));
			} else if ("hosts".equalsIgnoreCase(object.getString("condition"))) {
				return this.listHost(object.getLong("vdcId"));
			} else if ("listOpaqueNetworks".equalsIgnoreCase(object.getString("condition"))) {
				List<Network> networks = networkRepository.listOpaqueNetworks("nsx.LogicalSwitch",
						object.getLong("hostId"));
				return new BocloudResult<>(true, networks, "查询成功");
			} else if ("networkAndSubnets".equalsIgnoreCase(object.getString("condition"))) {
				return this.networkAndSubnets(object, context);
			}
			return new BocloudResult<>(false, "查询失败");
		} catch (Exception e) {
			logger.error("list network failure:", e);
			return new BocloudResult<>(false, "查询失败", null, null);
		}
	}

	@Override
	public BocloudResult create(NetworkModel networkModel, RequestContext context, String callback) {
		Long vendorId = networkModel.getVendorId();
		try {
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			Assert.notNull(vendor, "云平台不存在");
			NetworkModel model = networkModel;
			// Powervc直接走自己的逻辑
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				return createPowervcNetwork(model, vendor, context.getTarget());
			}
			Network database = networkRepository.getByName(model.getName(), vendorId);
			Assert.isNull(database, "网络名称已存在");
			model.setPhyNetwork(null);
			model.setSegmentationId(null);
			Long tenantId = context.getTenant();
			// 租户下创建网络
			model.setIsTenant(0 != tenantId);
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".network";
				BocloudResult result = new BocloudResult<>(false, "创建网络失败");
				Network network = null;
				try {
					Long region = networkModel.getRegion();
					if (!CloudProvider.OPENSTACK.name().equals(vendor.getType())
							&& !CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())
							&& !CloudProvider.MANAGEONE.name().equals(vendor.getType())
							&& !CloudProvider.HUAWEI.name().equals(vendor.getType())) {
						Region reg = regionRepository.query(region);
						if (null == reg) {
							logger.error("get region failure!");
							resourceEventPublisher.send(new OperateResult(false, "创建失败：区域不存在！", operate,
									MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
							return;
						}
						result = networkDriver.create(vendor.getUuid(), reg.getCode(), model);
					} else {
						TenantProvider provider = vendorProjectService.getAncestorProject(vendor.getId(),
								context.getTenant());
						if (null == provider) {
							result = networkDriver.create(vendor.getUuid(), networkModel.getOsTenantName(), null,
									model);
						} else {
							result = networkDriver.create(vendor.getUuid(), provider.getProjectName(), null, model);
						}
					}
					if (result.isFailed()) {
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
						return;
					}
					network = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Network.class);
					network.setRegion(region);
					network.preSave(context.getTarget(), context.getTarget(), vendorId, null);
					networkRepository.save(network);
					if (0L != context.getTenant()) {
						TenantNetwork tenantNetwork = new TenantNetwork(network.getId(), vendorId, context.getTenant(),
								context.getProject());
						tenantNetworkRepository.save(tenantNetwork);
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), "创建成功！", operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
				} catch (Exception e) {
					logger.error("创建失败：" + e.getMessage());
					resourceEventPublisher.send(new OperateResult(false, "创建失败：" + e.getMessage(), operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
				}
				if (!StringUtils.isEmpty(callback)) {
					BocloudResult bocloudResult = new BocloudResult<>(false, "创建网络失败");
					if (result.isSuccess() && null != network && null != network.getId()) {
						bocloudResult.setSuccess(true);
						bocloudResult.setMessage("创建网络成功");
						bocloudResult.setData(network);
					}
					amqpTemplate.convertAndSend(callback, JSONObject.toJSON(bocloudResult));
				}
			}).start();
			return new BocloudResult<>(true, "任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("create network failure:", e);
			return new BocloudResult<>(false, e.getMessage());
		}
	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = Network.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			// if (0L == context.getTenant()) {
			// List<TenantNetwork> tenantNetworks =
			// tenantNetworkRepository.listByNetworkId(id);
			// if (!ListTool.isEmpty(tenantNetworks)) {
			// return new BocloudResult<>(false, "有租户正在使用该网络");
			// }
			// }
			Network network = networkRepository.query(id);
			if (null == network) {
				logger.warn("network data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(network.getVendorId());
			if (null == vendor) {
				logger.error("get vendor failure");
				return new BocloudResult<>(false, "云平台不存在");
			}
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				List<Port> ports = portRepository.listAllByNetworkId(id);
				if (ports != null && ports.size() > 0) {
					return new BocloudResult<>(false, "此网络下存在端口占用，无法删除");
				}
			} else {
				List<Subnet> subnets = subnetRepository.list(network.getVendorId(), network.getId());
				if (!subnets.isEmpty()) {
					logger.warn("subnets is not null");
					return new BocloudResult<>(false, "此网络存在子网，无法删除!");
				}
			}
			BocloudResult result = null;
			if (CloudProvider.OPENSTACK.name().equals(vendor.getType())
					|| CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())
					|| CloudProvider.MANAGEONE.name().equals(vendor.getType())
					|| CloudProvider.HUAWEI.name().equals(vendor.getType())
					|| CloudProvider.POWERVC.name().equals(vendor.getType())) {
				result = networkDriver.remove(network.getNetworkUuid(), vendor.getUuid(), null);
			} else {
				Region region = regionRepository.query(network.getRegion());
				if (null == region) {
					logger.error("get region failure");
					return new BocloudResult<>(false, "所属域不存在");
				}
				result = networkDriver.remove(network.getNetworkUuid(), vendor.getUuid(), region.getCode());
			}

			if (result.isFailed()) {
				return new BocloudResult<>(false, result.getMessage());
			}
			networkRepository.remove(id, context.getTarget());
			tenantNetworkRepository.deleteByNetworkId(id);
			ipRepository.deleteByNetworkId(id);
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				subnetRepository.removeByNetworkId(id, context.getTarget());
				networkSeaRepository.deleteByNetworkId(id);
			}
			vpcRepository.deleteByNetworkId(id, context.getTarget());
			return new BocloudResult<>(true, "删除成功");
		} catch (Exception e) {
			logger.error("remove network fail:", e);
			return new BocloudResult<>(false, "删除失败");
		}
	}

	@Override
	public BocloudResult<Network> detail(Long id) {
		try {
			Network network = networkRepository.query(id);
			List<TenantNetwork> tenantNetworks = tenantNetworkRepository.listByNetworkId(id);
			String tenantName = "";
			for (TenantNetwork tenantNetwork : tenantNetworks) {
				if (null != tenantNetwork && !StringUtils.isEmpty(tenantNetwork.getTenantName())) {
					tenantName += tenantNetwork.getTenantName() + ",";
				}
			}
			if (tenantName.length() > 0) {
				tenantName = tenantName.substring(0, tenantName.length() - 1);
			}
			if (null != network) {
				network.setTenantName(tenantName);
				List<Subnet> subnets = subnetRepository.listByNetwork(id);
				for (Subnet subnet : subnets) {
					IPAddress address = IPAddress
							.getIPAddress(subnet.getCidr().substring(0, subnet.getCidr().indexOf("/")));
					subnet.setNetmask(address.getMask(subnet.getCidr()));
				}
				network.setSubnets(subnets);
				network.setSubnetNum((long) subnets.size());
				if (!StringUtils.isEmpty(network.getTenantUuid())) {
					OSTenant osTenant = oSTenantRepository.getByTenantUuid(network.getTenantUuid(),
							network.getVendorId());
					if (null != osTenant) {
						network.setOsTenantName(osTenant.getName());
					}
				}
			}
			return new BocloudResult<>(true, network, "查询详情成功!");
		} catch (Exception e) {
			logger.error("query network detail failure:", e);
			return new BocloudResult<>(false, "查询详情失败!");
		}
	}

	@Override
	public BocloudResult modify(NetBean bean, RequestContext context) {
		String path = Network.class.getSimpleName() + "_" + bean.getId();
		BocloudResult result = null;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Network network = networkRepository.query(bean.getId());
			if (null == network) {
				logger.warn("network data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(network.getVendorId());
			if (null == vendor) {
				logger.error("get cloud vendor failure");
				return new BocloudResult<>(false, "修改失败");
			}
			NetworkModel model = new NetworkModel();
			if (null != context.getTenant() && 0L != context.getTenant()) {
				model.setName(bean.getName());
				model.setNetworkUuid(network.getNetworkUuid());
				model.setAdminStateup(network.getAdminStateup());
				model.setShared(network.getShared());
			} else {
				model.setName(bean.getName());
				model.setNetworkUuid(network.getNetworkUuid());
				model.setAdminStateup(bean.getAdminStateup());
				model.setShared(bean.getShared());
				network.setAdminStateup(bean.getAdminStateup());
				network.setShared(bean.getShared());
			}
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				// 处理网络信息
				network.setMtu(bean.getMtu());
				model.setName(bean.getName());
				model.setMtu(bean.getMtu());
				result = networkDriver.modify(vendor.getUuid(), null, model);
				if (result.isFailed()) {
					return new BocloudResult<>(false, "修改失败: " + result.getMessage());
				}
				// 处理子网信息
				if (bean.getSubnets() == null || bean.getSubnets().size() != 1) {
					return new BocloudResult<>(false, "PowerVC的网络中必须包含且只能包含一个子网");
				}
				if (bean.getSubnets().get(0).getDhcpEnabled()) {
					// 子网开启dhcp，则要删除子网
					List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
					for (Subnet subnet : subnets) {
						List<Port> ports = portRepository.listBySubnetId(subnet.getId());
						if (ports != null && ports.size() > 0) {
							return new BocloudResult<>(false, "该网络中存在已经被使用的端口，不能将该网络调整为DHCP");
						}
						result = subnetDriver.remove(subnet.getSubnetUuid(), vendor.getUuid(), null);
						if (result.isFailed()) {
							return new BocloudResult<>(false, "修改失败: " + result.getMessage());
						}
						subnetRepository.remove(subnet.getId(), context.getTarget());
					}
				} else {
					// 子网没有开启dhcp，则创建或编辑子网
					List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
					if (subnets.size() == 0) {
						for (SubnetModel subnetBean : bean.getSubnets()) {
							// 前端通过cidr字段传过来的是子网掩码，所以这里要转换成真正的cidr
							SubnetModel subnetModel = new SubnetModel();
							subnetModel.setName(bean.getName());
							subnetModel.setNetworkUuid(network.getNetworkUuid());
							subnetModel.setDhcpEnabled(false);
							subnetModel.setIpPools(subnetBean.getIpPools());
							subnetModel.setGateway(subnetBean.getGateway());
							subnetModel.setCidr(subnetBean.getGateway() + "/" + IPAddress
									.getIPAddress(subnetBean.getGateway()).getMaskLength(subnetBean.getCidr()));
							subnetModel.setDnsNames(subnetBean.getDnsNames());
							result = subnetDriver.create(vendor.getUuid(), null, subnetModel);
							if (result.isFailed()) {
								return new BocloudResult<>(false, "修改失败: " + result.getMessage());
							}
							subnetModel = (SubnetModel) result.getData();
							powervcTransportor.insertOrUpdate(network, subnetModel, context.getTarget());
						}
					} else {
						for (Subnet subnet : subnets) {
							SubnetModel subnetModel = new SubnetModel();
							subnetModel.setSubnetUuid(subnet.getSubnetUuid());
							subnetModel.setDnsNames(bean.getSubnets().get(0).getDnsNames());
							subnetModel.setIpPools(bean.getSubnets().get(0).getIpPools());
							result = subnetDriver.modify(vendor.getUuid(), null, subnetModel);
							if (result.isFailed()) {
								return new BocloudResult<>(false, "修改失败: " + result.getMessage());
							}
							subnet.setDnsNames(bean.getSubnets().get(0).getDnsNames());
							subnet.setIpPools(bean.getSubnets().get(0).getIpPools());
							subnetRepository.update(subnet);
						}
					}
				}
				// 处理sea信息
				for (HostSeaAdapter sea : JSONArray.parseArray(JSONObject.toJSONString(bean.getSeas()),
						HostSeaAdapter.class)) {
					if (sea.getLparId() == -1) {
						sea.setId(-1L);
						sea.setSeaName("not-applicable");
					} else {
						HostSeaAdapter seaFromDB = hostSeaRepository.getByName(sea.getSeaName(), sea.getLparId(),
								sea.getServerHost(), vendor.getId());
						if (seaFromDB == null) {
							return new BocloudResult<>(false, "未找到SEA");
						}
						sea.setId(seaFromDB.getId());
					}
					sea.setNetworkId(network.getNetworkUuid());
				}
				result = hostSeaDriver.createMapping(vendor.getUuid(), bean.getSeas());
				if (result.isFailed()) {
					return new BocloudResult<>(false, "修改失败: " + result.getMessage());
				}
				networkSeaRepository.deleteByNetworkId(network.getId());
				for (HostSeaAdapter sea : JSONArray.parseArray(JSONObject.toJSONString(bean.getSeas()),
						HostSeaAdapter.class)) {
					if (sea.getId() != -1) {
						NetworkSeaAdapter adapter = new NetworkSeaAdapter();
						adapter.setNetworkId(network.getId());
						adapter.setSeaId(sea.getId());
						networkSeaRepository.save(adapter);
					}
				}
			} else if (CloudProvider.OPENSTACK.name().equals(vendor.getType())
					|| CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())
					|| CloudProvider.MANAGEONE.name().equals(vendor.getType())
					|| CloudProvider.HUAWEI.name().equals(vendor.getType())) {
				result = networkDriver.modify(vendor.getUuid(), null, model);
			} else {
				Region region = regionRepository.query(network.getRegion());
				if (null == region) {
					logger.error("get region failure");
					return new BocloudResult<>(false, "修改失败");
				}
				result = networkDriver.modify(vendor.getUuid(), region.getCode(), model);
			}
			if (result.isFailed()) {
				return new BocloudResult<>(false, "修改失败");
			}
			network.setName(bean.getName());
			networkRepository.update(network);
			List<Vpc> vpcs = vpcRepository.listByNetworkId(network.getId());
			for (Vpc vpc : vpcs) {
				vpc.setName(network.getName());
				vpcRepository.update(vpc);
			}
			return new BocloudResult<>(true, network, "修改网络成功");
		} catch (Exception e) {
			logger.error("modify network fail:", e);
			return new BocloudResult<>(false, "修改网络失败");
		}
	}

	@Override
	public BocloudResult createDSwitch(SwitchModel model, RequestContext context) {
		try {
			Long userId = context.getTarget();
			CloudVendor vendor = cloudVendorRepository.query(model.getVendorId());
			if (null == vendor) {
				logger.error("get vendor and region failure");
				return new BocloudResult<>(false, "未获取到云供应商");
			}
			Vdc vdc = vdcRepository.query(model.getVdcId());
			if (null == vdc) {
				return new BocloudResult<>(false, "虚拟数据中心不存在");
			}
			boolean exists = networkRepository.exists(model.getName(), model.getVendorId(), "DVSWITCH");
			if (exists) {
				return new BocloudResult<>(false, "该名称" + model.getName() + "已存在");
			}
			Map<Long, List<Long>> hosts = model.getHosts();
			Map<String, List<String>> values = Maps.newHashMap();
			List<NetworkCard> networkCards = Lists.newArrayList();
			// 获取宿主机名称和网卡名称
			for (Long hostId : hosts.keySet()) {
				List<Long> cardIds = hosts.get(hostId);
				List<String> cards = Lists.newArrayList();
				for (Long cardId : cardIds) {
					NetworkCard card = this.networkCardRepository.query(cardId);
					cards.add(card.getName());
					networkCards.add(card);
				}
				Server host = this.serverRepository.query(hostId);
				values.put(host.getName(), cards);
			}
			model.setValues(values);
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".network";
				// 创建交换机
				BocloudResult result = networkDriver.createDSwitch(vendor.getUuid(), model);
				String content = "创建分布式交换机失败";
				try {
					// 创建成功则更新网卡为已使用
					if (result.isSuccess()) {
						String data = JSONObject.toJSONString(result.getData());
						// 保存分布式交换机
						Switcher switcher = JSONObject.parseObject(data, Switcher.class);
						Network network = switcher.getNetwork();
						switcher.preSave(userId, userId, vendor.getId(), model.getVdcId(), null);
						switcherRepository.save(switcher);
						// 更新网卡的状态
						for (NetworkCard card : networkCards) {
							card.setUsed(true);
							card.setMenderId(userId);
							card.setSwitcherId(switcher.getId());
							networkCardRepository.update(card);
						}
						// 保存新增的网络
						network.preSave(userId, userId, vendor.getId(), model.getVdcId());
						network.setSwitcherId(switcher.getId());
						networkRepository.save(network);
						for (Long hostId : hosts.keySet()) {
							networkHostRepository.save(new NetworkHost(network.getId(), hostId, vendor.getId(), "PM"));
						}
						List<PortGroup> groups = switcher.getGroups();
						// 保存分布式交换机端口组
						for (PortGroup group : groups) {
							group.preSave(userId, userId, vendor.getId(), switcher.getId());
							portGroupRepository.save(group);
						}
						content = "创建分布式交换机成功";
					} else {
						content = result.getMessage();
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
				} catch (Exception e) {
					logger.error("Get Message Exception:", e);
					resourceEventPublisher.send(new OperateResult(false, content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
				}

			}).start();
			return new BocloudResult<>(true, "创建任务已下发，正在执行……");
		} catch (Exception e) {
			logger.error("exception info", e);
			return new BocloudResult<>(false, "创建分布式交换机失败");
		}
	}

	@Override
	public BocloudResult<GridBean<CloudServer>> servers(Pager pager, Long id) {
		try {
			int page = pager.getPage();
			int rows = pager.getRows();
			List<Param> params = pager.getParams();
			Map<String, String> sorter = pager.getSorter();
			boolean simple = pager.getSimple();

			if (null == params) {
				params = new ArrayList<>();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			int total = cloudServerRepository.count(ResourceCategory.Network.name(), id, params);
			List<CloudServer> servers = this.cloudServerRepository.listServers(page, rows, params, sorter, id,
					ResourceCategory.Network.name());
			for (CloudServer server : servers) {
				// 设置主机名称
				Server host = serverRepository.query(server.getHostId());
				if (null != host) {
					server.setHostName(host.getName());
					// 设置集群名称
					if (null != host.getClusterId()) {
						Cluster cluster = clusterRepository.query(host.getClusterId());
						if (null != cluster) {
							server.setClusterName(cluster.getName());
						}
					}
				}
				// 设置快照数量
				List<Snapshot> snapshots = snapshotRepository.listByVMid(server.getId());
				server.setSnapshotCount(snapshots.size());
			}
			GridBean gridBean = GridHelper.getBean(page, rows, total, servers);
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("list servers failure:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<GridBean<Server>> hosts(Pager pager, Long id) {
		try {
			int page = pager.getPage();
			int rows = pager.getRows();
			List<Param> params = pager.getParams();
			Map<String, String> sorter = pager.getSorter();
			boolean simple = pager.getSimple();

			if (null == params) {
				params = new ArrayList<>();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			int total = serverRepository.count(ResourceCategory.Network.name(), id, params);
			List<Server> servers = this.serverRepository.listServers(page, rows, params, sorter, id,
					ResourceCategory.Network.name());
			for (Server server : servers) {
				// 设置集群名称
				if (null != server.getClusterId()) {
					Cluster cluster = clusterRepository.query(server.getClusterId());
					if (null != cluster) {
						server.setClusterName(cluster.getName());
					}
				}
				ServerConfig config = serverConfigRepository.getBySid(server.getId());
				server.setConfig(config);
			}
			GridBean gridBean = GridHelper.getBean(page, rows, total, servers);
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("list servers failure:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@SuppressWarnings("unchecked")
	private BocloudResult<Map<Long, List<Router>>> listServerRouters(String params, RequestContext context) {
		JSONObject object = JSONObject.parseObject(params);
		try {
			Long vendorId = object.getLong("vendorId");
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult<>(false, "平台信息异常！");
			}
			List<Long> serverIds = JSONObject.parseArray(object.getString("serverIds"), Long.class);
			if (ListTool.isEmpty(serverIds)) {
				return new BocloudResult<>(false, "至少选择一台虚拟机！");
			}
			Map<Long, List<Router>> map = new HashMap<>();
			for (Long serverId : serverIds) {
				JSONObject obj = new JSONObject();
				obj.put("vendorId", vendorId);
				obj.put("serverId", serverId);
				BocloudResult listRouterAndSubNet = listRouterAndSubNet(obj.toJSONString(), context);
				if (listRouterAndSubNet.isSuccess()) {
					List<Router> routerList = (List<Router>) listRouterAndSubNet.getData();
					map.put(serverId, routerList);
				}
			}
			return new BocloudResult<>(true, map, "查询成功！");
		} catch (Exception e) {
			logger.error("list network and subnet error：", e);
			return new BocloudResult<>(false, "查询网络失败");
		}

	}

	@Override
	public BocloudResult<List<Router>> listRouterAndSubNet(String params, RequestContext context) {
		JSONObject object = JSONObject.parseObject(params);
		try {
			Long vendorId = object.getLong("vendorId");
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult<>(false, "平台信息异常！");
			}
			Long serverId = object.getLong("serverId");
			CloudServer cloudServer = cloudServerRepository.query(serverId);
			if (null == cloudServer) {
				return new BocloudResult<>(false, "虚拟机信息异常！");
			}
			switch (CloudProvider.valueOf(vendor.getType())) {
			case MANAGEONE:
				List<String> subnetUuids = new ArrayList<String>();
				String privateIps = cloudServer.getPrivateIps();
				List<JSONObject> parseArray = JSONObject.parseArray(privateIps, JSONObject.class);
				if (!ListTool.isEmpty(parseArray)) {
					for (JSONObject jsonObject : parseArray) {
						List<JSONObject> javaList = jsonObject.getJSONArray("addresses").toJavaList(JSONObject.class);
						for (JSONObject obj : javaList) {
							String subnetUuid = obj.getString("subnetUuid");
							if (!StringUtils.isEmpty(subnetUuid)) {
								subnetUuids.add(subnetUuid);
							}
						}
					}
				}
				List<Router> routerList = new ArrayList<Router>();
				Router oldRouter = routerRepository.query(cloudServer.getRouterUuid(), vendorId);
				if (null == oldRouter) {
					routerList = routerRepository.listByVid(vendorId);
				} else {
					routerList.add(oldRouter);
				}
				if (ListTool.isEmpty(routerList)) {
					// manageone 只允许挂载同以VPC下的子网，但没有找到原VPC数据
					return new BocloudResult<>(false, "暂无可以网络！");
				}
				// 查询每个网络下所有子网
				for (Router router : routerList) {
					List<Subnet> subnets = subnetRepository.listByVpcId(vendorId, router.getRouterUuid());
					for (int i = subnets.size() - 1; i >= 0; i--) {
						if (subnetUuids.contains(subnets.get(i).getSubnetUuid())) {
							subnets.remove(subnets.get(i));
						}
					}
					if (subnets.isEmpty()) {
						router.setSubnets(new ArrayList<>());
					} else {
						router.setSubnets(subnets);
					}
				}
				return new BocloudResult<>(true, routerList, "查询成功！");
			default:
				return new BocloudResult<>(false, "暂不支持该操作！");
			}
		} catch (Exception e) {
			logger.error("list network and subnet error：", e);
			return new BocloudResult<>(false, "查询网络失败");
		}
	}

	@Override
	public BocloudResult listNetAndSubNet(Long vendorId, String tenantUuid, RequestContext context) {
		try {
			Long projectId = context.getProject();
			if (null != projectId && 0L != projectId) {
				BocloudResult<Project> projResult = smsProjectService.detail(projectId);
				if (projResult.isFailed()) {
					return new BocloudResult<>(false, projResult.getMessage());
				}
				Project project = projResult.getData();
				if (null == project) {
					return new BocloudResult<>(false, "当前项目不存在");
				}
			}
			List<Network> networks = null;
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			switch (CloudProvider.valueOf(vendor.getType())) {
			case OPENSTACK:
				networks = networkRepository.listByVid(vendorId, context.getTenant());
				if (ListTool.isEmpty(networks)) {
					return new BocloudResult<>(false, "该云平台下没有可用网络");
				}
				List<Network> newNets = new ArrayList<>();
				// 查询每个网络下所有子网
				for (Network network : networks) {
					// 共享网络
					if (null != network.getShared() && network.getShared()) {
						List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
						if (subnets.isEmpty()) {
							network.setSubnets(new ArrayList<>());
						} else {
							network.setSubnets(subnets);
						}
						newNets.add(network);
						continue;
					}
					if (StringUtils.isEmpty(tenantUuid)) {
						// 如果是租户下的网络，则只查本租户关联底层项目下的网络
						if (null != context.getTenant() && 0L != context.getTenant()) {
							TenantProvider provider = vendorProjectService.getAncestorProject(vendorId,
									context.getTenant());
							if (null != provider) {
								OSTenant tenant = oSTenantRepository.getByName(provider.getProjectName(), vendorId);
								if (null != tenant) {
									tenantUuid = tenant.getTenantUuid();
								}
							}
						}
					}
					if (!StringUtils.isEmpty(tenantUuid) && tenantUuid.equalsIgnoreCase(network.getTenantUuid())) {
						List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
						if (subnets.isEmpty()) {
							network.setSubnets(new ArrayList<>());
						} else {
							network.setSubnets(subnets);
						}
						newNets.add(network);
					}
				}
				return new BocloudResult<>(true, newNets, "查询成功");
			case FUSIONCLOUD:
				networks = networkRepository.listByVid(vendorId, context.getTenant());
				if (ListTool.isEmpty(networks)) {
					return new BocloudResult<>(false, "该云平台下没有可用网络");
				}
				// 去掉外部网络
				networks.removeIf(Network::getIsRouterExternal);
				// 查询每个网络下所有子网
				for (Network network : networks) {
					List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
					if (subnets.isEmpty()) {
						network.setSubnets(new ArrayList<>());
					} else {
						network.setSubnets(subnets);
					}
				}
				break;
			case MANAGEONE:
				List<Router> routerList = routerRepository.listByVid(vendorId);
				if (ListTool.isEmpty(routerList)) {
					return new BocloudResult<>(false, "该云平台下没有可用VPC");
				}
				// 查询每个网络下所有子网
				for (Router router : routerList) {
					List<Subnet> subnets = subnetRepository.listByVpcId(vendorId, router.getRouterUuid());
					if (subnets.isEmpty()) {
						router.setSubnets(new ArrayList<>());
					} else {
						router.setSubnets(subnets);
					}
				}
				return new BocloudResult<>(true, routerList, "查询成功！");
			case HUAWEI:
				networks = networkRepository.listByVid(vendorId, context.getTenant());
				// 查询每个网络下所有子网
				for (Network network : networks) {
					List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
					if (subnets.isEmpty()) {
						network.setSubnets(new ArrayList<>());
					} else {
						network.setSubnets(subnets);
					}
				}
				break;
			case VMWARE:
				networks = networkRepository.listByVid(vendorId);
				if (ListTool.isEmpty(networks)) {
					return new BocloudResult<>(false, "该云平台下没有可用网络");
				}
				break;
			case POWERVC:
				networks = networkRepository.listByVid(vendorId);
				if (ListTool.isEmpty(networks)) {
					return new BocloudResult<>(false, "该云平台下没有可用网络");
				}
				// 查询每个网络下所有子网
				for (Network network : networks) {
					List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
					if (subnets.isEmpty()) {
						network.setSubnets(new ArrayList<>());
					} else {
						network.setSubnets(subnets);
					}
				}
				break;
			default:
				break;
			}
			return new BocloudResult<>(true, networks, "查询成功");
		} catch (Exception e) {
			logger.error("list network and subnet error：", e);
			return new BocloudResult<>(false, "查询网络失败");
		}
	}

	@Override
	public BocloudResult<List<Network>> listExternal(Long vendorId, RequestContext context) {
		try {
			List<Network> networks = null;
			CloudVendor cloudVendor = cloudVendorRepository.query(vendorId);
			if (null == cloudVendor) {
				return new BocloudResult<>(false, "云平台信息异常！");
			}
			switch (CloudProvider.valueOf(cloudVendor.getType())) {
			case OPENSTACK:
				// 全局项目直接查询所有平台下外部网络
				if (null != context.getTenant() && context.getTenant() <= 0L) {
					networks = networkRepository.listExternalByVid(vendorId, null);
				} else {
					networks = networkRepository.listExternalByVid(vendorId, null);
				}
				break;
			case MANAGEONE:
				List<Param> params = new ArrayList<>();
				params.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
				params.add(new Param(MapTools.simpleMap("type", "eip_external_net"), Sign.EQ));
				networks = networkRepository.list(1, Integer.MAX_VALUE, params, null, null, null);
			default:
				break;
			}
			return new BocloudResult<>(true, networks, "查询外部网络成功");
		} catch (Exception e) {
			logger.error("list external network error：", e);
			return new BocloudResult<>(false, "查询外部网络失败");
		}
	}

	@Override
	public BocloudResult removeDSwitch(Long id, RequestContext context) {
		String path = Network.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Network network = networkRepository.query(id);
			if (null == network) {
				logger.warn("network data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			List<NetworkHost> hosts = networkHostRepository.listByNetworkId(id, "VM");
			if (!ListTool.isEmpty(hosts)) {
				return new BocloudResult<>(false, "删除失败：该分布式交换机下存在虚拟机");
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(network.getVendorId());
			if (null == vendor) {
				logger.error("get vendor failure");
				return new BocloudResult<>(false, "云平台不存在");
			}
			Long userId = context.getTarget();
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".network";
				BocloudResult result = networkDriver.removeDSwitch(vendor.getUuid(), network.getName());
				String content = "分布式交换机【" + network.getName() + "】删除失败";
				try {
					if (result.isSuccess()) {
						content = "分布式交换机【" + network.getName() + "】删除成功";
						networkHostRepository.deleteByNetwork(id);
						networkCardRepository.release(network.getSwitcherId(), userId);
						portGroupRepository.removeBySwitcher(network.getSwitcherId(), userId);
						switcherRepository.remove(network.getSwitcherId(), userId);
						networkRepository.remove(id, userId);
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
				} catch (Exception e) {
					logger.error("Get Message Exception:", e);
					resourceEventPublisher.send(new OperateResult(false, content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
				}

			}).start();
			return new BocloudResult<>(true, "删除任务已经下发，正在执行……");
		} catch (Exception e) {
			logger.error("Remove distribute virtual switch error:", e);
			return new BocloudResult<>(false, "删除分布式交换机失败");
		}
	}

	/**
	 * 删除交换机
	 *
	 * @param id
	 * @param hostId
	 * @param context
	 * @return
	 */
	@Override
	public BocloudResult removeSwitch(Long id, Long hostId, RequestContext context) {
		if (null != hostId && 0L != hostId) {
			return this.removeVSwitch(hostId, id, context);
		} else {
			return this.removeDSwitch(id, context);
		}
	}

	@Override
	public BocloudResult modifyDSwitch(SwitchBean bean, RequestContext context) {
		Long id = bean.getId();
		String path = Network.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Switcher switcher = switcherRepository.query(id);
			if (null == switcher) {
				logger.warn("Switcher data not exist");
				return new BocloudResult<>(false, "交换机不存在");
			}
			bean.setOldName(switcher.getName());
			List<Network> networks = networkRepository.listBySwitcher(id);
			if (ListTool.isEmpty(networks)) {
				logger.warn("network data not exist");
				return new BocloudResult<>(false, "网络数据不存在");
			}
			Network network = networks.get(0);
			if (!switcher.getName().equals(bean.getName())) {
				boolean exists = networkRepository.exists(bean.getName(), network.getVdcId(), "DVSWITCH");
				if (exists) {
					return new BocloudResult<>(false, "该名称" + bean.getName() + "已存在");
				}
			}
			// 云供应商
			CloudVendor vendor = cloudVendorRepository.query(network.getVendorId());
			if (null == vendor) {
				logger.error("get vendor failure");
				return new BocloudResult<>(false, "云平台不存在");
			}
			Vdc vdc = vdcRepository.query(switcher.getVdcId());
			if (null == vdc) {
				logger.error("get data center failure");
				return new BocloudResult<>(false, "数据中心不存在");
			}
			bean.setVdcName(vdc.getName());
			Long userId = context.getTarget();
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = vendor.getType().toLowerCase() + ".network";
					SwitchModel model = new SwitchModel();
					BeanUtils.copyProperties(bean, model);
					BocloudResult result = networkDriver.updateDVSwitch(vendor.getUuid(), model);
					String content = "分布式交换机【" + network.getName() + "】修改失败";
					try {
						if (result.isSuccess()) {
							content = "分布式交换机【" + network.getName() + "】修改成功";
							network.setName(bean.getName());
							network.setMenderId(userId);
							networkRepository.update(network);
							model = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
									SwitchModel.class);
							model.setVendorId(switcher.getVendorId());
							model.setVdcId(switcher.getVdcId());
							BeanUtils.copyProperties(model, switcher);
							switcher.setDvportNames(JSONObject.toJSONString(model.getDvportNames()));
							switcher.setMenderId(userId);
							switcher.setType(switcher.getType());
							switcherRepository.update(switcher);
						}
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
						resourceEventPublisher.send(new OperateResult(false, content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					}
				}
			}).start();
			return new BocloudResult<>(true, "编辑任务已经下发，正在执行……");
		} catch (Exception e) {
			logger.error("Modify distribute virtual switch error:", e);
			return new BocloudResult<>(false, "修改分布式交换机失败");
		}
	}

	@Override
	public BocloudResult modifySwitch(SwitchBean bean, RequestContext context) {
		try {
			Switcher switcher = switcherRepository.query(bean.getId());
			if (null == switcher) {
				logger.warn("Switcher data not exist");
				return new BocloudResult<>(false, "交换机不存在");
			}
			if ("VSWITCH".equalsIgnoreCase(switcher.getType())) {
				return this.modifyVSwitch(bean, context);
			} else {
				return this.modifyDSwitch(bean, context);
			}
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "交换机修改失败");
		}
	}

	@Override
	public BocloudResult<Map<String, Object>> listNetworkByHostId(Long hostId) {
		try {
			Server server = serverRepository.query(hostId);
			if (null == server) {
				logger.warn("Server data does not exist!");
				return new BocloudResult<>(false, "主机不存在");
			}
			Map<String, Object> switcherMap = Maps.newHashMap();
			List<Switcher> vswitchers = Lists.newArrayList();// 虚拟交换机
			List<Switcher> dvSwitchers = Lists.newArrayList();// 分布式交换机
			// 查询宿主机绑定的标准交换机网络
			List<Switcher> switchers = switcherRepository.listByHostId(hostId);
			// 查询宿主机绑定的网络
			List<NetworkHost> networkHosts = networkHostRepository.list(hostId, "PM");
			// 组装标准交换机网络数据
			for (Switcher switcher : switchers) {
				// 查询交换机绑定的端口组
				List<PortGroup> vGroups = portGroupRepository.listBySwitcher(switcher.getId());
				for (NetworkHost networkHost : networkHosts) {
					Network network = networkRepository.query(networkHost.getNetworkId());
					if (null != network) {
						for (PortGroup group : vGroups) {
							// 网络名称和端口组名称相同
							if (NetworkType.PortGroupType.VIRTUAL.name().equals(group.getType())
									&& group.getName().equals(network.getName())) {
								List<CloudServer> cloudServers = cloudServerRepository
										.listServersByNetwork(networkHost.getNetworkId(), hostId);
								group.setCloudServers(cloudServers);
							}
						}
					}
				}
				switcher.setGroups(vGroups);
				if (NetworkType.SwitchType.VSWITCH.name().equals(switcher.getType())) {
					// 查询虚拟交换机所连接的物理适配器
					List<NetworkCard> networkCards = networkCardRepository.listBySwitcher(switcher.getId(), "PM");
					switcher.setNetworkCards(networkCards);
					vswitchers.add(switcher);
				}
			}
			// 组装分布式交换机网络数据
			for (NetworkHost networkHost : networkHosts) {
				Network network = networkRepository.query(networkHost.getNetworkId());
				if (null == network) {
					continue;
				}
				if (NetworkType.SwitchType.DVSWITCH.name().equals(network.getType())) {
					Switcher dvSwitcher = switcherRepository.query(network.getSwitcherId());
					if (null != dvSwitcher) {
						List<PortGroup> dvGroups = portGroupRepository.listBySwitcher(dvSwitcher.getId());
						for (PortGroup group : dvGroups) {
							if (group.getType().equals(NetworkType.PortGroupType.DVPORT.name())) {
								// 查询与此分布式端口组绑定的虚拟机
								List<CloudServer> cloudServers = cloudServerRepository
										.listServersByNetwork(networkHost.getNetworkId(), hostId);
								group.setCloudServers(cloudServers);
							}
						}
						dvSwitcher.setGroups(dvGroups);
						// 查询虚拟交换机所连接的物理适配器
						List<NetworkCard> networkCards = networkCardRepository.listBySwitcher(dvSwitcher.getId(), "PM");
						dvSwitcher.setNetworkCards(networkCards);
						dvSwitchers.add(dvSwitcher);
					}
				}
			}
			// 组装nsx网络
			List<Network> networks = networkRepository.listOpaqueNetworks("nsx.LogicalSwitch", hostId);
			switcherMap.put("vswitchers", vswitchers);
			switcherMap.put("dvSwitchers", dvSwitchers);
			switcherMap.put("nsxNetworks", networks);
			return new BocloudResult<>(true, switcherMap, "查询宿主机网络成功");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "查询宿主机网络失败");
		}
	}

	@Override
	public BocloudResult removeVSwitch(Long hostId, Long vswitchId, RequestContext context) {
		String path = Switcher.class.getSimpleName() + "-" + vswitchId;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Server server = serverRepository.query(hostId);
			if (null == server) {
				logger.warn("Server not exist");
				return new BocloudResult<>(false, "宿主机不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(server.getVendorId());
			if (null == vendor) {
				logger.warn("Cloud vendor not exist");
				return new BocloudResult<>(false, "云平台不存在");
			}
			Switcher switcher = switcherRepository.query(vswitchId);
			if (null == switcher) {
				logger.warn("Virtual Switch not exist");
				return new BocloudResult<>(false, "标准交换机不存在");
			}
			List<PortGroup> groups = portGroupRepository.listBySwitcher(vswitchId);
			List<String> pgNames = Lists.newArrayList();
			for (PortGroup group : groups) {
				pgNames.add(group.getName());
			}
			Long userId = context.getTarget();
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = vendor.getType().toLowerCase() + ".switcher";
					BocloudResult result = networkDriver.removeVSwitch(vendor.getUuid(), server.getName(),
							switcher.getName(), pgNames);
					String content = "标准交换机【" + switcher.getName() + "】删除失败";
					try {
						if (result.isSuccess()) {
							content = "标准交换机【" + switcher.getName() + "】删除成功";
							// 删除端口组
							for (PortGroup group : groups) {
								portGroupRepository.remove(group.getId(), userId);
							}
							// 端口组名称与连接网络的名称相同
							for (PortGroup group : groups) {
								Network network = networkRepository.getByNameAndType(group.getName(), server.getVdcId(),
										"VSWITCH");
								if (null != network) {
									// 更新网络与宿主机绑定关系
									networkHostRepository.deleteByHostAndNetwork(hostId, network.getId(), "PM");
									// 更新网络与虚拟机绑定关系
									List<CloudServer> cloudServers = cloudServerRepository.listByHid(hostId);
									for (CloudServer cloudServer : cloudServers) {
										networkHostRepository.deleteByHostAndNetwork(cloudServer.getId(),
												network.getId(), "VM");
									}
									List<NetworkHost> pmNetworks = networkHostRepository
											.listByNetworkId(network.getId(), "PM");
									List<NetworkHost> vmNetworks = networkHostRepository
											.listByNetworkId(network.getId(), "VM");
									// 当网络所关联宿主机和虚拟机都为空时，删除标准交换机网络记录
									if (ListTool.isEmpty(pmNetworks) && ListTool.isEmpty(vmNetworks)) {
										networkRepository.remove(network.getId(), userId);
									}
								}
							}
							// 删除标准交换机本地数据
							switcherRepository.remove(vswitchId, userId);
							// 更新网卡为未使用
							List<NetworkCard> cards = networkCardRepository.listBySwitcher(vswitchId, "PM");
							for (NetworkCard card : cards) {
								card.setMenderId(userId);
								card.setGmtModify(new Date());
								card.setSwitcherId(null);
								card.setUsed(false);
								networkCardRepository.update(card);
							}
						}
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
						resourceEventPublisher.send(new OperateResult(false, content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					}
				}
			}).start();
			return new BocloudResult<>(true, "删除任务已经下发，正在执行……");
		} catch (Exception e) {
			return new BocloudResult<>(false, "删除标准交换机失败");
		}
	}

	@Override
	public BocloudResult modifyVSwitch(SwitchBean bean, RequestContext context) {
		String path = Switcher.class.getSimpleName() + "-" + bean.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Server server = serverRepository.query(bean.getHostId());
			if (null == server) {
				logger.warn("Server not exist");
				return new BocloudResult<>(false, "宿主机不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(server.getVendorId());
			if (null == vendor) {
				logger.warn("Cloud vendor not exist");
				return new BocloudResult<>(false, "云平台不存在");
			}
			Switcher switcher = switcherRepository.query(bean.getId());
			if (null == switcher) {
				logger.warn("Virtual Switch not exist");
				return new BocloudResult<>(false, "标准交换机不存在");
			}
			List<NetworkCard> networkCards = networkCardRepository.listBySwitcher(switcher.getId(), "PM");
			List<String> activeNics = Lists.newArrayList();
			for (NetworkCard networkCard : networkCards) {
				activeNics.add(networkCard.getName());
			}
			bean.setActiveNics(activeNics);
			Long userId = context.getTarget();
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = vendor.getType().toLowerCase() + ".switcher";
					SwitchModel model = new SwitchModel();
					BeanUtils.copyProperties(bean, model);
					model.setPortGroupNum(bean.getPortNum().intValue());
					BocloudResult result = networkDriver.updateVSwitch(vendor.getUuid(), server.getName(),
							switcher.getName(), model);
					String content = "标准交换机【" + switcher.getName() + "】修改失败";
					try {
						if (result.isSuccess()) {
							content = "标准交换机【" + switcher.getName() + "】修改成功";
							model.setVendorId(switcher.getVendorId());
							model.setVdcId(switcher.getVdcId());
							model.setName(switcher.getName());
							model.setType(switcher.getType());
							model.setSwitcherVal(switcher.getSwitcherVal());
							BeanUtils.copyProperties(model, switcher);
							switcher.setPortNum(model.getPortGroupNum());
							switcher.setMenderId(userId);
							if (!ListTool.isEmpty(model.getActiveNics())) {
								switcher.setActiveNics(JSONObject.toJSONString(model.getActiveNics()));
							}
							if (!ListTool.isEmpty(model.getStandbyNics())) {
								switcher.setStandbyNics(JSONObject.toJSONString(model.getStandbyNics()));
							}
							switcherRepository.update(switcher);
						}
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
						resourceEventPublisher.send(new OperateResult(false, content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					}
				}
			}).start();
			return new BocloudResult<>(true, "修改标准交换机任务已下发，正在执行......");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "标准交换机修改失败");
		}
	}

	@Override
	public BocloudResult removePortGroup(Long hostId, Long pgId, RequestContext context) {
		String path = PortGroup.class.getSimpleName() + "-" + pgId;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			PortGroup group = portGroupRepository.query(pgId);
			if (null == group) {
				logger.warn("port group not exist");
				return new BocloudResult<>(false, "端口组不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(group.getVendorId());
			if (null == vendor) {
				logger.warn("Cloud vendor not exist");
				return new BocloudResult<>(false, "云平台不存在");
			}
			BocloudResult result = null;
			switch (NetworkType.PortGroupType.valueOf(group.getType().toUpperCase())) {
			case VIRTUAL:
				Server server = serverRepository.query(hostId);
				if (null == server) {
					logger.warn("Server not exist");
					return new BocloudResult<>(false, "宿主机不存在");
				}
				result = networkDriver.removePortGroup(vendor.getUuid(), server.getName(), group.getName(),
						group.getType());
				Network network = networkRepository.getByNameAndType(group.getName(), server.getVdcId(),
						NetworkType.SwitchType.VSWITCH.name());
				if (result.isFailed()) {
					return result;
				}
				if (null != network) {
					// 更新网络与宿主机绑定关系
					networkHostRepository.deleteByHostAndNetwork(hostId, network.getId(), "PM");
					// 更新网络与虚拟机绑定关系
					List<CloudServer> cloudServers = cloudServerRepository.listByHid(hostId);
					for (CloudServer cloudServer : cloudServers) {
						networkHostRepository.deleteByHostAndNetwork(cloudServer.getId(), network.getId(), "VM");
					}
					List<NetworkHost> pmNetworks = networkHostRepository.listByNetworkId(network.getId(), "PM");
					List<NetworkHost> vmNetworks = networkHostRepository.listByNetworkId(network.getId(), "VM");
					// 当网络所关联宿主机和虚拟机都为空时，删除标准交换机网络记录
					if (ListTool.isEmpty(pmNetworks) && ListTool.isEmpty(vmNetworks)) {
						networkRepository.remove(network.getId(), context.getTarget());
					}
				}
				break;
			case DVPORT:
				List<Network> networks = networkRepository.listBySwitcher(group.getSwitcherId());
				if (ListTool.isEmpty(networks)) {
					logger.warn("network data not exist");
					return new BocloudResult<>(false, "网络数据不存在");
				}
				List<NetworkHost> hosts = networkHostRepository.listByNetworkId(networks.get(0).getId(), "VM");
				if (!ListTool.isEmpty(hosts)) {
					return new BocloudResult<>(false, "删除失败：该端口组存在虚拟机资源");
				}
				result = networkDriver.removePortGroup(vendor.getUuid(), null, group.getName(), group.getType());
				if (result.isFailed()) {
					return result;
				}
				break;
			case VMKERNEL:
			case UPLINK:
			default:
				result = new BocloudResult<>(false, "删除失败");
				break;
			}
			if (result.isFailed()) {
				return result;
			}
			// 删除端口组
			portGroupRepository.remove(group.getId(), context.getTarget());
			return new BocloudResult<>(true, "端口组删除成功");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "端口组删除失败");
		}
	}

	@Override
	public BocloudResult createPortGroup(PortGroupModel pgModel, RequestContext context) {
		try {
			Server server = null;
			Long switcherId = pgModel.getSwitcherId();
			Switcher switcher = switcherRepository.query(switcherId);
			if (null == switcher) {
				logger.warn("Virtual Switch not exist");
				return new BocloudResult<>(false, "端口组所关联的交换机不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(switcher.getVendorId());
			if (null == vendor) {
				logger.warn("Cloud vendor not exist");
				return new BocloudResult<>(false, "云平台不存在");
			}
			Vdc vdc = vdcRepository.query(switcher.getVdcId());
			if (null == vdc) {
				logger.warn("Vcenter data center not exist");
				return new BocloudResult<>(false, "数据中心不存在");
			}
			pgModel.setVdcName(vdc.getName());
			BocloudResult result = null;
			String type = pgModel.getType();
			switch (NetworkType.PortGroupType.valueOf(type.toUpperCase())) {
			case VMKERNEL:
				break;
			case VIRTUAL:
				boolean flag = portGroupRepository.exist(pgModel.getName(), switcherId);
				if (flag) {
					logger.warn("The Network tags for this port group exist");
					result = new BocloudResult<>(false, "已经有网络使用了该端口组的网络标签，请输入唯一的网络标签!");
				}
				server = serverRepository.query(pgModel.getHostId());
				if (null == server) {
					logger.warn("Server not exist");
					result = new BocloudResult<>(false, "宿主机不存在");
				}
				break;
			case DVPORT:
				String vlanType = pgModel.getVlanType();
				if (StringUtils.isEmpty(vlanType)) {
					return new BocloudResult<>(false, "未知的端口组类型");
				}
				break;
			case UPLINK:
				break;
			default:
				break;
			}
			if (null != result && result.isFailed()) {
				return result;
			}
			Server cloneServer = server;
			CloudVendor cloneVendor = vendor;
			Switcher cloneSwitcher = switcher;
			Long userId = context.getTarget();
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = cloneVendor.getType().toLowerCase() + ".portGroup";
					String content = "端口组【" + pgModel.getName() + "】创建失败";
					try {
						BocloudResult result = null;
						if (null == cloneServer) {
							result = networkDriver.createPortGroup(cloneVendor.getUuid(), null, cloneSwitcher.getName(),
									pgModel);
						} else {
							result = networkDriver.createPortGroup(cloneVendor.getUuid(), cloneServer.getName(),
									cloneSwitcher.getName(), pgModel);
						}
						if (result.isSuccess()) {
							PortGroupModel model = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
									PortGroupModel.class);
							PortGroup portGroup = new PortGroup();
							switch (NetworkType.PortGroupType.valueOf(type.toUpperCase())) {
							case VMKERNEL:
								break;
							case VIRTUAL:
								content = "虚拟端口组【" + pgModel.getName() + "】创建成功";
								NetworkModel networkModel = model.getNetworkModel();
								List<Network> networks = networkRepository.listByVdc(vdc.getId());
								Map<String, Network> maps = Maps.newHashMap();
								for (Network net : networks) {
									maps.put(net.getNetworkVal(), net);
								}
								Long networkId = null;
								if (maps.containsKey(networkModel.getNetworkVal())) {
									networkId = maps.get(networkModel.getNetworkVal()).getId();
								} else {
									Network newNetwork = new Network();
									BeanUtils.copyProperties(networkModel, newNetwork);
									newNetwork.preSave(userId, userId, vendor.getId(), vdc.getId());
									networkRepository.save(newNetwork);
									networkId = newNetwork.getId();
								}
								// 保存宿主机网络关系
								NetworkHost networkHost = new NetworkHost(networkId, pgModel.getHostId(),
										cloneVendor.getId(), "PM");
								networkHostRepository.save(networkHost);
								break;
							case UPLINK:
								break;
							case DVPORT:
								content = "分布式端口组【" + pgModel.getName() + "】创建成功";
								break;
							default:
								break;
							}
							BeanUtils.copyProperties(model, portGroup);
							if (!ListTool.isEmpty(model.getActiveNics())) {
								portGroup.setActiveNics(JSONObject.toJSONString(model.getActiveNics()));
							}
							if (!ListTool.isEmpty(model.getStandbyNics())) {
								portGroup.setStandbyNics(JSONObject.toJSONString(model.getStandbyNics()));
							}
							if (!ListTool.isEmpty(model.getActiveUplinks())) {
								portGroup.setActiveUplinks(JSONObject.toJSONString(model.getActiveUplinks()));
							}
							if (!ListTool.isEmpty(model.getStandbyUplinks())) {
								portGroup.setStandbyUplinks(JSONObject.toJSONString(model.getStandbyUplinks()));
							}
							portGroup.setCreatorId(userId);
							portGroup.setVendorId(cloneVendor.getId());
							portGroup.setSwitcherId(switcherId);
							// 保存端口组
							portGroupRepository.save(portGroup);
						} else {
							content = result.getMessage();
						}
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
								MapTools.simpleMap(Common.VENDORID, cloneVendor.getId()), operateCategory, context));
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
						resourceEventPublisher.send(new OperateResult(false, content, operate,
								MapTools.simpleMap(Common.VENDORID, cloneVendor.getId()), operateCategory, context));
					}
				}
			}).start();
			return new BocloudResult<>(true, "端口组创建任务已经下发，正在执行……");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "端口组创建失败");
		}
	}

	@Override
	public BocloudResult modifyPortGroup(PortGroupBean portGroupBean, RequestContext context) {
		String path = PortGroup.class.getSimpleName() + "-" + portGroupBean.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			PortGroup portGroup = portGroupRepository.query(portGroupBean.getId());
			if (null == portGroup) {
				logger.warn("Port group not exist");
				return new BocloudResult<>(false, "端口组不存在");
			}
			portGroupBean.setOldName(portGroup.getName());
			CloudVendor vendor = cloudVendorRepository.query(portGroup.getVendorId());
			if (null == vendor) {
				logger.warn("Cloud vendor not exist");
				return new BocloudResult<>(false, "云平台不存在");
			}
			Long switcherId = portGroupBean.getSwitcherId();
			Switcher switcher = switcherRepository.query(switcherId);
			if (null == switcher) {
				logger.warn("Virtual Switch not exist");
				return new BocloudResult<>(false, "端口组所关联的标准交换机不存在");
			}
			portGroupBean.setSwitcherName(switcher.getName());
			Vdc vdc = vdcRepository.query(switcher.getVdcId());
			if (null == vdc) {
				logger.warn("data center not exist");
				return new BocloudResult<>(false, "数据中心不存在");
			}
			portGroupBean.setVdcName(vdc.getName());
			Server server = null;
			switch (NetworkType.PortGroupType.valueOf(portGroup.getType().toUpperCase())) {
			case VIRTUAL:
				server = serverRepository.query(portGroupBean.getHostId());
				if (null == server) {
					logger.warn("Server not exist");
					return new BocloudResult<>(false, "宿主机不存在");
				}
				break;
			case VMKERNEL:
				break;
			case DVPORT:
				break;
			case UPLINK:
				break;
			default:
				break;
			}
			portGroupBean.setType(portGroup.getType());
			Server cloneServer = server;
			Long userId = context.getTarget();
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = vendor.getType().toLowerCase() + ".switcher";
					PortGroupModel pgModel = new PortGroupModel();
					BeanUtils.copyProperties(portGroupBean, pgModel);
					BocloudResult result = null;
					if (null == cloneServer) {
						result = networkDriver.updatePortGroup(vendor.getUuid(), null, pgModel);
					} else {
						result = networkDriver.updatePortGroup(vendor.getUuid(), cloneServer.getName(), pgModel);
					}
					String content = "端口组【" + portGroup.getName() + "】修改失败";
					try {
						if (result.isSuccess()) {
							PortGroupModel groupModel = JSONObject
									.parseObject(JSONObject.toJSONString(result.getData()), PortGroupModel.class);
							switch (NetworkType.PortGroupType.valueOf(pgModel.getType())) {
							case VIRTUAL:
								content = "虚拟端口组【" + portGroup.getName() + "】修改成功";
								NetworkModel networkModel = groupModel.getNetworkModel();
								List<Network> networks = networkRepository.listByVdc(vdc.getId());
								Map<String, Network> networkMap = Maps.newHashMap();
								for (Network net : networks) {
									networkMap.put(net.getNetworkVal(), net);
								}
								if (networkMap.containsKey(networkModel.getNetworkVal())) {
									Network oldNetwork = networkMap.get(networkModel.getNetworkVal());
									// 更新网络记录
									oldNetwork.setName(networkModel.getName());
									networkRepository.update(oldNetwork);

								} else {
									// 添加新的网络记录
									Network newNetwork = new Network();
									BeanUtils.copyProperties(networkModel, newNetwork);
									newNetwork.preSave(userId, userId, vendor.getId(), vdc.getId());
									// 保存网络记录
									networkRepository.save(newNetwork);
									Network oldNetwork = networkRepository.getByNameAndType(portGroup.getName(),
											vdc.getId(), NetworkType.SwitchType.VSWITCH.name());
									if (null != oldNetwork) {
										List<NetworkHost> vmHosts = networkHostRepository
												.listByNetworkId(oldNetwork.getId(), "VM");
										List<NetworkHost> pmHosts = networkHostRepository
												.listByNetworkId(oldNetwork.getId(), "PM");
										// 删除旧网络记录
										networkRepository.remove(oldNetwork.getId(), userId);
										for (NetworkHost vmHost : vmHosts) {
											networkHostRepository.delete(NetworkHost.class, vmHost.getId());
										}
										for (NetworkHost pmHost : pmHosts) {
											networkHostRepository.delete(NetworkHost.class, pmHost.getId());
										}
										// 保存网络宿主机和虚拟机关系
										for (NetworkHost vmHost : vmHosts) {
											NetworkHost newVmHost = new NetworkHost(newNetwork.getId(),
													vmHost.getVhostId(), vmHost.getVendorId(), "VM");
											networkHostRepository.save(newVmHost);
										}
										for (NetworkHost pmHost : pmHosts) {
											NetworkHost newPmHost = new NetworkHost(newNetwork.getId(),
													pmHost.getVhostId(), pmHost.getVendorId(), "PM");
											networkHostRepository.save(newPmHost);
										}
									} else {
										// 保存宿主机网络关系
										NetworkHost networkHost = new NetworkHost(newNetwork.getId(),
												pgModel.getHostId(), vendor.getId(), "PM");
										networkHostRepository.save(networkHost);
									}
								}
								break;
							case VMKERNEL:
								break;
							case UPLINK:
								break;
							case DVPORT:
								String vlanType = portGroupBean.getVlanType();
								if (!StringUtils.isEmpty(vlanType)) {
									if (!vlanType.equals(NetworkType.VlanType.TrunkVlan.name())) {
										portGroup.setTrunkVlan(null);
									}
								}
								content = "分布式端口组【" + portGroup.getName() + "】修改成功";
								break;
							default:
								break;
							}
							BeanUtils.copyProperties(portGroupBean, portGroup);
							if (!ListTool.isEmpty(portGroupBean.getActiveNics())) {
								portGroup.setActiveNics(JSONObject.toJSONString(portGroupBean.getActiveNics()));
							}
							if (!ListTool.isEmpty(portGroupBean.getStandbyNics())) {
								portGroup.setStandbyNics(JSONObject.toJSONString(portGroupBean.getStandbyNics()));
							}
							if (!ListTool.isEmpty(portGroupBean.getActiveUplinks())) {
								portGroup.setActiveUplinks(JSONObject.toJSONString(portGroupBean.getActiveUplinks()));
							}
							if (!ListTool.isEmpty(portGroupBean.getStandbyUplinks())) {
								portGroup.setStandbyUplinks(JSONObject.toJSONString(portGroupBean.getStandbyUplinks()));
							}
							portGroup.setMenderId(userId);
							portGroupRepository.update(portGroup);
						}
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
						resourceEventPublisher.send(new OperateResult(false, content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					}
				}
			}).start();
			return new BocloudResult<>(true, "修改端口组任务已下发，正在执行......");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "端口组修改失败");
		}
	}

	@Override
	public BocloudResult<PortGroup> getPortGroup(Long pgId) {
		try {
			PortGroup portGroup = portGroupRepository.query(pgId);
			return new BocloudResult<>(true, portGroup, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：{}", e.getMessage());
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<Switcher> getSwitcher(Long switcherId) {
		try {
			Switcher switcher = switcherRepository.query(switcherId);
			return new BocloudResult<>(true, switcher, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：{}", e.getMessage());
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult listBySwitcher(Long switcherId) {
		try {
			List<PortGroup> groups = portGroupRepository.listBySwitcher(switcherId);
			return new BocloudResult<>(true, groups, "查询成功");
		} catch (Exception e) {
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult addHost(SwitchBean bean, RequestContext context) {
		try {
			Switcher switcher = switcherRepository.query(bean.getId());
			if (null == switcher) {
				logger.error("Switcher does not exists");
				return new BocloudResult<>(false, "交换机不存在");
			}
			bean.setName(switcher.getName());
			CloudVendor vendor = cloudVendorRepository.query(switcher.getVendorId());
			if (null == vendor) {
				logger.error("get vendor and region failure");
				return new BocloudResult<>(false, "未获取到云供应商");
			}
			Vdc vdc = vdcRepository.query(bean.getVdcId());
			if (null == vdc) {
				logger.error("Data center does not exists");
				return new BocloudResult<>(false, "数据中心不存在");
			}
			bean.setVdcName(vdc.getName());
			Map<Long, List<Long>> hosts = bean.getHosts();
			Map<String, List<String>> values = Maps.newHashMap();
			List<NetworkCard> networkCards = Lists.newArrayList();
			// 获取宿主机名称和网卡名称
			for (Long hostId : hosts.keySet()) {
				List<Long> cardIds = hosts.get(hostId);
				List<String> cards = Lists.newArrayList();
				for (Long cardId : cardIds) {
					NetworkCard card = this.networkCardRepository.query(cardId);
					cards.add(card.getName());
					networkCards.add(card);
				}
				Server host = this.serverRepository.query(hostId);
				values.put(host.getName(), cards);
			}
			bean.setValues(values);
			Long userId = context.getTarget();
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = vendor.getType().toLowerCase() + ".switcher";
					String content = "添加主机失败";
					SwitchModel model = new SwitchModel();
					BeanUtils.copyProperties(bean, model);
					BocloudResult result = networkDriver.addHost(vendor.getUuid(), model);
					try {
						if (result.isSuccess()) {
							content = "添加主机成功";
							for (Long hostId : hosts.keySet()) {
								List<Long> cards = hosts.get(hostId);
								for (Long card : cards) {
									NetworkCard networkCard = networkCardRepository.query(card);
									networkCard.setUsed(true);
									networkCard.setMenderId(userId);
									networkCard.setSwitcherId(switcher.getId());
									networkCardRepository.update(networkCard);
									// 更新宿主机网络信息
									List<Network> networks = networkRepository.listBySwitcher(switcher.getId());
									if (!ListTool.isEmpty(networks)) {
										Network network = networks.get(0);
										NetworkHost networkHost = new NetworkHost(network.getId(), hostId,
												vendor.getId(), "PM");
										networkHostRepository.save(networkHost);
									}
								}
							}
						} else {
							content = result.getMessage();
						}
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
						resourceEventPublisher.send(new OperateResult(false, content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()), operateCategory, context));
					}
				}
			}).start();
			return new BocloudResult<>(true, "添加主机任务已下发，正在执行......");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "添加主机失败");
		}
	}

	@Override
	public BocloudResult<List<NetworkCard>> listCardBySwitcher(Long switcherId) {
		try {
			List<NetworkCard> networkCards = networkCardRepository.listBySwitcher(switcherId, "PM");
			return new BocloudResult<>(true, networkCards, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<List<Server>> listHost(Long vdcId) {
		try {
			// 查询数据中心下的宿主机
			List<Server> hosts = serverRepository.listByVdc(vdcId);
			List<Server> servers = Lists.newArrayList();
			for (Server host : hosts) {
				List<NetworkHost> networkHosts = networkHostRepository.listByVhostId(host.getId(), "PM");
				boolean flag = true;
				for (NetworkHost networkHost : networkHosts) {
					Network network = networkRepository.query(networkHost.getNetworkId());
					if (null != network && NetworkType.SwitchType.DVSWITCH.name().equals(network.getType())) {
						flag = false;
						break;
					}
				}
				if (flag) {
					List<NetworkCard> cards = Lists.newArrayList();
					List<NetworkCard> netCards = networkCardRepository.listByHost(host.getId(), "PM");
					for (NetworkCard card : netCards) {
						if (null != card.getUsed() && !card.getUsed()) {
							cards.add(card);
						}
					}
					if (!cards.isEmpty()) {
						host.setNetcards(cards);
						servers.add(host);
					}
				}
			}
			return new BocloudResult<>(true, servers, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult authNetwork(Long id, List<Long> tenantIds) {
		try {
			Network network = networkRepository.query(id);
			if (null == network) {
				logger.error("Network does not exists");
				return new BocloudResult<>(false, "网络不存在");
			}
			tenantNetworkRepository.deleteByNetworkId(id);
			if (ListTool.isEmpty(tenantIds)) {
				return new BocloudResult<>(true, "网络授权已清空");
			} else {
				for (Long tenantId : tenantIds) {
					TenantNetwork tenantNetwork = new TenantNetwork(id, network.getVendorId(), tenantId, 0L);
					tenantNetworkRepository.save(tenantNetwork);
				}
				return new BocloudResult<>(true, "授权成功");
			}
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "授权失败");
		}
	}

	@Override
	public BocloudResult listAuthTenant(Long id) {
		try {
			List<TenantNetwork> networks = tenantNetworkRepository.listByNetworkId(id);
			return new BocloudResult<>(true, networks, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult deleteByTenant(Long tenantId) {
		try {
			tenantNetworkRepository.deleteByTenantId(tenantId);
			return new BocloudResult<>(true, "删除成功");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult<>(false, "删除失败");
		}
	}

	@Override
	public BocloudResult batchRemove(List<Long> idArray, RequestContext context) {
		if (ListTool.isEmpty(idArray)) {
			return new BocloudResult<>(false, "没有需要删除的网络！");
		}
		try {
			List<BocloudResult> succList = Lists.newArrayList();
			List<BocloudResult> failList = Lists.newArrayList();
			Long vendorId = null;
			for (Long id : idArray) {
				Network network = networkRepository.query(id);
				if (null != network) {
					if (null == vendorId) {
						vendorId = network.getVendorId();
					}
					BocloudResult result = remove(id, context);
					if (result.isSuccess()) {
						succList.add(new BocloudResult<>(true, "【" + network.getName() + "】删除成功"));
					} else {
						failList.add(
								new BocloudResult<>(false, "【" + network.getName() + "】删除失败：" + result.getMessage()));
					}
				}
			}
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			String operate = vendor.getType().toLowerCase() + ".network";
			// 删除成功的数量
			int success = succList.size();
			// 删除失败的数量
			int fail = failList.size();
			String content = null;
			if (fail == idArray.size()) {
				content = "云网络批量删除失败，详情如下：\n";
				for (BocloudResult bocloudResult : failList) {
					content += bocloudResult.getMessage() + "\n";
				}
				resourceEventPublisher.send(new OperateResult(false, content, operate,
						MapTools.simpleMap(Common.VENDORID, vendor.getId()), OperateCategory.ResourceEvent, context));
			} else {
				content = "云网络批量删除成功【" + success + "】个,失败【" + fail + "】个，详情如下：\n";
				for (BocloudResult bocloudResult : succList) {
					content += bocloudResult.getMessage() + "\n";
				}
				for (BocloudResult bocloudResult : failList) {
					content += bocloudResult.getMessage() + "\n";
				}
				resourceEventPublisher.send(new OperateResult(true, content, operate,
						MapTools.simpleMap(Common.VENDORID, vendor.getId()), OperateCategory.ResourceEvent, context));
			}
		} catch (Exception e) {
			logger.error("batch remove network fail:", e);
			return new BocloudResult<>(false, "批量删除任务下发失败");
		}
		return new BocloudResult<>(true, "批量删除任务已下发，正在执行...");
	}

	private BocloudResult createPowervcNetwork(NetworkModel networkModel, CloudVendor vendor, Long userId) {
		try {
			// 先调用创建网络接口创建网络
			if (StringUtils.isEmpty(networkModel.getType())) {
				networkModel.setType("vlan");
			}
			if (StringUtils.isEmpty(networkModel.getPhyNetwork())) {
				networkModel.setPhyNetwork("default");
			}
			// 校验子网数据
			if (networkModel.getSubnets() != null && networkModel.getSubnets().size() > 0) {
				if (networkModel.getSubnets().size() > 1) {
					return new BocloudResult<>(false, "创建网络失败，一个网络只支持一个子网");
				}
				SubnetModel subnetModel = networkModel.getSubnets().get(0);
				if (!subnetModel.getDhcpEnabled()) {
					IPAddress ipAddress = IPAddress.getIPAddress(subnetModel.getGateway());
					// 前端通过cidr字段传过来的是子网掩码，所以这里要转换成真正的cidr
					subnetModel.setCidr(subnetModel.getGateway() + "/"
							+ IPAddress.getIPAddress(subnetModel.getGateway()).getMaskLength(subnetModel.getCidr()));
					// 如果用户填写的起始IP和结束IP都为空，则要根据子网掩码和网关生成IP范围
					JSONArray ipPools = JSON.parseArray(subnetModel.getIpPools());
					if (ipPools == null || ipPools.size() == 0) {
						subnetModel.setIpPools(ipAddress.getPools(subnetModel.getGateway(), subnetModel.getCidr()));
						ipPools = JSON.parseArray(subnetModel.getIpPools());
					}
					// 判断ip池是否和其他网络重复
					List<Network> networks = networkRepository.listByVid(vendor.getId());
					Map<String, String> oldIpPools = new HashMap<>();
					for (Network network : networks) {
						if (networkModel.getSegmentationId().equals(network.getSegmentationId())) {
							List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
							for (Subnet subnet : subnets) {
								if (!subnet.getDhcpEnabled() && !StringUtils.isEmpty(subnet.getIpPools())) {
									JSONArray subnetIpPools = JSON.parseArray(subnet.getIpPools());
									for (int i = 0; i < subnetIpPools.size(); i++) {
										String ipPool = subnetIpPools.getString(i);
										oldIpPools.put(network.getName(), ipPool);
									}
								}
							}
						}
					}
					for (int i = 0; i < ipPools.size(); i++) {
						String newIpPool = ipPools.getString(i);
						long newStart = ipAddress.ipToInteger(newIpPool.split("-")[0]).longValue();
						long newEnd = ipAddress.ipToInteger(newIpPool.split("-")[1]).longValue();
						for (Map.Entry<String, String> oldIpPoolEntry : oldIpPools.entrySet()) {
							String oldNetworkName = oldIpPoolEntry.getKey();
							String oldIpPool = oldIpPoolEntry.getValue();
							long oldStart = ipAddress.ipToInteger(oldIpPool.split("-")[0]).longValue();
							long oldEnd = ipAddress.ipToInteger(oldIpPool.split("-")[1]).longValue();
							if ((newStart <= oldEnd && newStart >= oldStart)
									|| (newEnd <= oldEnd && newEnd >= oldStart)) {
								return new BocloudResult<>(false, "创建网络失败，IP地址范围：" + newIpPool + "与现有网络："
										+ oldNetworkName + "的IP地址范围：" + oldIpPool + "有交叉部分，请调整后再试！");
							}
						}
					}
				} else {
					// 检查当前vlanId是不是已经有了一个dhcp的网络
					List<Network> networks = networkRepository.listByVid(vendor.getId());
					for (Network network : networks) {
						if (networkModel.getSegmentationId().equals(network.getSegmentationId())) {
							List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
							if (subnets == null || subnets.size() == 0) {
								return new BocloudResult<>(false, String.format("创建网络失败，已经存在VLAN标识为%s的动态(DHCP)网络：%s",
										networkModel.getSegmentationId(), network.getName()));
							}
						}
					}
				}
			}
			BocloudResult result = networkDriver.create(vendor.getUuid(), null, networkModel);
			if (result.isFailed()) {
				logger.error("创建网络失败{}", result);
				return result;
			}
			Network network = powervcTransportor.insertOrUpdate(vendor, (NetworkModel) result.getData(), userId);

			// 再调用创建子网接口创建子网
			if (networkModel.getSubnets() != null && networkModel.getSubnets().size() > 0) {
				SubnetModel subnetModel = networkModel.getSubnets().get(0);
				// 只需要创建非dhcp的子网
				if (!subnetModel.getDhcpEnabled()) {
					// 设定其他值
					subnetModel.setName(network.getName());
					subnetModel.setNetworkUuid(network.getNetworkUuid());
					result = subnetDriver.create(vendor.getUuid(), null, subnetModel);
					if (result.isFailed()) {
						logger.error("创建子网失败{}", result);
						return result;
					}
					Subnet subnet = powervcTransportor.insertOrUpdate(network, (SubnetModel) result.getData(), userId);

				}
			}
			// 最后创建host-sea-mapping
			for (HostSeaAdapter sea : JSONArray.parseArray(JSONObject.toJSONString(networkModel.getSeas()),
					HostSeaAdapter.class)) {
				if (sea.getLparId() == -1) {
					sea.setId(-1L);
					sea.setSeaName("not-applicable");
				} else {
					HostSeaAdapter seaFromDB = hostSeaRepository.getByName(sea.getSeaName(), sea.getLparId(),
							sea.getServerHost(), vendor.getId());
					if (seaFromDB == null) {
						return new BocloudResult<>(false, "未找到SEA");
					}
					sea.setId(seaFromDB.getId());
				}
				sea.setNetworkId(network.getNetworkUuid());
			}
			result = hostSeaDriver.createMapping(vendor.getUuid(), networkModel.getSeas());
			if (result.isFailed()) {
				logger.error("创建网络失败: 创建host-sea-mapping失败, params={},result={}",
						JSONObject.toJSONString(networkModel.getSeas()), result);
				return new BocloudResult<>(false, "创建powervc网络失败: 创建host-sea-mapping失败");
			}
			for (HostSeaAdapter sea : JSONArray.parseArray(JSONObject.toJSONString(networkModel.getSeas()),
					HostSeaAdapter.class)) {
				if (sea.getId() != -1) {
					NetworkSeaAdapter adapter = new NetworkSeaAdapter();
					adapter.setNetworkId(network.getId());
					adapter.setSeaId(sea.getId());
					networkSeaRepository.save(adapter);
				}
			}
			return new BocloudResult<>(true, network, "创建powervc网络[" + networkModel.getName() + "]成功");
		} catch (Exception e) {
			logger.error("创建网络失败:", e);
			return new BocloudResult<>(false, "创建powervc网络失败");
		}
	}

	@Override
	public BocloudResult<?> networkAndSubnets(JSONObject object, RequestContext context) {
		try {
			Long vendorId = object.getLong("vendorId");
			Long tenantId = object.getLong("tenantId");
			List<Param> params = new ArrayList<>();
			params.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
			Pager pager = new Pager(1, Integer.MAX_VALUE, params, null);
			BocloudResult<GridBean<Vpc>> list = vpcService.list(pager, context);
			if (list.isFailed()) {
				return list;
			}
			List<Vpc> vpcs = null;
			if (null != list.getData()) {
				vpcs = list.getData().getRows();
			}
			Assert.notEmpty(vpcs, "VPC列表为空");
			List<Long> networkIds = new ArrayList<>();
			List<Long> routerIds = new ArrayList<>();
			for (Vpc vpc : vpcs) {
				if (null != vpc.getNetworkId() && 0L != vpc.getNetworkId()) {
					networkIds.add(vpc.getNetworkId());
				}
				if (null != vpc.getRouterId() && 0L != vpc.getRouterId()) {
					routerIds.add(vpc.getRouterId());
				}
			}
			List<Network> networks = null;
			List<Router> routers = null;
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			Assert.notNull(vendor, "云平台不存在");
			switch (CloudProvider.valueOf(vendor.getType())) {
			case OPENSTACK:
				Assert.notEmpty(networkIds, "该云平台下没有可用网络");
				networks = networkRepository.listByNetworkIds(networkIds);
				Assert.notEmpty(networks, "该云平台下没有可用网络");
				List<Network> newNets = new ArrayList<>();
				// 查询每个网络下所有子网
				for (Network network : networks) {
					// 共享网络
					if (null != network.getShared() && network.getShared()) {
						List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
						if (subnets.isEmpty()) {
							network.setSubnets(new ArrayList<>());
						} else {
							network.setSubnets(subnets);
						}
						newNets.add(network);
						continue;
					}
					String tenantUuid = null;
					// 如果是租户下的网络，则只查本租户关联底层项目下的网络
					if ((null != context.getTenant() && 0L != context.getTenant()) || null != tenantId) {
						TenantProvider provider = vendorProjectService.getAncestorProject(vendorId,
								tenantId == null ? context.getTenant() : tenantId);
						if (null != provider) {
							OSTenant tenant = oSTenantRepository.getByName(provider.getProjectName(), vendorId);
							if (null != tenant) {
								tenantUuid = tenant.getTenantUuid();
							}
						}
					}
					if (!StringUtils.isEmpty(tenantUuid) && tenantUuid.equalsIgnoreCase(network.getTenantUuid())) {
						List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
						if (subnets.isEmpty()) {
							network.setSubnets(new ArrayList<>());
						} else {
							network.setSubnets(subnets);
						}
						newNets.add(network);
					}
				}
				return new BocloudResult<>(true, newNets, "查询成功");
			case FUSIONCLOUD:
				Assert.notEmpty(networkIds, "该云平台下没有可用网络");
				networks = networkRepository.listByNetworkIds(networkIds);
				Assert.notEmpty(networks, "该云平台下没有可用网络");
				// 去掉外部网络
				networks.removeIf(Network::getIsRouterExternal);
				// 查询每个网络下所有子网
				for (Network network : networks) {
					List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
					if (subnets.isEmpty()) {
						network.setSubnets(new ArrayList<>());
					} else {
						network.setSubnets(subnets);
					}
				}
				break;
			case MANAGEONE:
				Assert.notEmpty(routerIds, "该云平台下没有可用VPC");
				routers = routerRepository.listByRouterIds(routerIds);
				Assert.notEmpty(routers, "该云平台下没有可用VPC");
				// 查询每个网络下所有子网
				for (Router router : routers) {
					List<Subnet> subnets = subnetRepository.listByVpcId(vendorId, router.getRouterUuid());
					if (subnets.isEmpty()) {
						router.setSubnets(new ArrayList<>());
					} else {
						router.setSubnets(subnets);
					}
				}
				return new BocloudResult<>(true, routers, "查询成功！");
			case HUAWEI:
				break;
			case VMWARE:
				networks = networkRepository.listByVid(vendorId);
				if (ListTool.isEmpty(networks)) {
					return new BocloudResult<>(false, "该云平台下没有可用网络");
				}
				break;
			case POWERVC:
				networks = networkRepository.listByVid(vendorId);
				if (ListTool.isEmpty(networks)) {
					return new BocloudResult<>(false, "该云平台下没有可用网络");
				}
				// 查询每个网络下所有子网
				for (Network network : networks) {
					List<Subnet> subnets = subnetRepository.list(vendorId, network.getId());
					if (subnets.isEmpty()) {
						network.setSubnets(new ArrayList<>());
					} else {
						network.setSubnets(subnets);
					}
				}
				break;
			default:
				break;
			}
			return new BocloudResult<>(true, networks, "查询成功");
		} catch (Exception e) {
			logger.error("list network and subnet error：{}", e.getMessage());
			return new BocloudResult<>(false, e.getMessage());
		}
	}

	@Override
	public BocloudResult createOsNetwork(JSONObject param, RequestContext context) {
		// 位置
		JSONObject location = param.getJSONObject("location");
		JSONObject configs = param.getJSONObject("configs");
		try {
			CloudVendor vendor = cloudVendorRepository.query(location.getLong("vendorId"));
			Assert.notNull(vendor, "云平台不存在");
			NetworkModel model = new NetworkModel();
			model.setName(configs.getString("name") + "_" + IDFactory.instance().uuid());
			model.setPhyNetwork(null);
			model.setSegmentationId(null);
			model.setIsTenant(0 != context.getTenant());
			model.setAdminStateup(true);
			model.setShared(false);
			model.setIsRouterExternal(false);
			BocloudResult result = new BocloudResult<>(false, "创建网络失败");
			TenantProvider provider = vendorProjectService.getAncestorProject(vendor.getId(), context.getTenant());
			if (null == provider) {
				String projectName = param.getString("osTenantName");
				if (StringUtils.isEmpty(projectName)) {
					JSONObject auth = JSONObject.parseObject(vendor.getAuthentication());
					projectName = auth.getString("projectName");
				}
				result = networkDriver.create(vendor.getUuid(), projectName, null, model);
			} else {
				result = networkDriver.create(vendor.getUuid(), provider.getProjectName(), null, model);
			}
			Assert.isTrue(result.isSuccess(), result.getMessage());
			Network network = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Network.class);
			network.preSave(context.getTarget(), context.getTarget(), vendor.getId(), null);
			networkRepository.save(network);
			if (0L != context.getTenant()) {
				TenantNetwork tenantNetwork = new TenantNetwork(network.getId(), vendor.getId(), context.getTenant(),
						context.getProject());
				tenantNetworkRepository.save(tenantNetwork);
			}
			return new BocloudResult<>(true, network, "创建云网络成功");
		} catch (Exception e) {
			logger.error("创建失败：", e);
			return new BocloudResult<>(false, "创建网络失败：" + e.getMessage());
		}
	}

}
