package com.bocloud.ims.service.resource;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.common.LocationDriver;
import com.bocloud.cmp.driver.network.PortDriver;
import com.bocloud.cmp.driver.network.RouteTableDriver;
import com.bocloud.cmp.driver.network.SubnetDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.model.CidrBlockModel;
import com.bocloud.cmp.model.OSSyncModel;
import com.bocloud.cmp.model.SubnetModel;
import com.bocloud.cmp.model.SubnetParam;
import com.bocloud.cmp.provider.utils.IPAddress;
import com.bocloud.cmp.provider.utils.IPv4Address;
import com.bocloud.cmp.provider.utils.IPv6Address;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.*;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.manageone.ManageOneAccount;
import com.bocloud.ims.interfaces.manageone.ManageOneAccountService;
import com.bocloud.ims.interfaces.resource.SubnetService;
import com.bocloud.ims.interfaces.resource.VendorProjectService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.service.transportor.OpenstackTransportor;
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 com.google.common.util.concurrent.ThreadFactoryBuilder;

/**
 * 子网Service接口实现
 *
 * @author dongkai
 */
@Service("subnetService")
public class SubnetServiceImpl implements SubnetService {

    private static Logger logger = LoggerFactory.getLogger(SubnetServiceImpl.class);
    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private NetworkRepository networkRepository;
    @Autowired
    private SubnetRepository subnetRepository;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private CloudServerRepository cloudServerRepository;
    @Autowired
    private RegionRepository regionRepository;
    @Autowired
    private SubnetDriver subnetDriver;
    @Autowired
    private PortRepository portRepository;
    @Autowired
    private RouterSubnetRepository routerSubnetRepository;
    @Autowired
    private IpRepository ipRepository;
    @Autowired
    private IpPoolRepository ipPoolRepository;
    @Autowired
    private LocationDriver locationDriver;
    @Autowired
    private PortFixedIpRepository portFixedIpRepository;
    @Autowired
    private PortDriver portDriver;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;
    @Autowired
    private RouteTableDriver routeTableDriver;

    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("pool-%d").build();
    private ExecutorService threadQueue =
        new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), namedThreadFactory);
    @Autowired
    private VpcRepository vpcRepository;
    @Autowired
    private SecurityGroupRepository securityGroupRepository;
    @Autowired
    private ZoneRepository zoneRepository;
    @Autowired
    private VendorProjectService vendorProjectService;
    @Autowired
    private OSTenantRepository osTenantRepository;
    @Autowired
    private RouterRepository routerRepository;
    @Autowired
    private ManageOneAccountService accountService;
    @Autowired
    private CidrBlockRepository cidrBlockRepository;
    @Autowired
    private RouteTableRepository routeTableRepository;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Override
    public BocloudResult<GridBean<Subnet>> list(Pager pager) {

        GridBean gridBean = null;
        try {

            int page = pager.getPage();
            int rows = pager.getRows();
            List<Param> params = pager.getParams();
            Map<String, String> sorter = pager.getSorter();
            boolean simple = pager.getSimple();

            Long routerId = null;
            Boolean hasIpv6 = false;
            if (null == params) {
                params = new ArrayList<>();
            } else {
                for (Param param : params) {
                    Map<String, Object> paramMap = param.getParam();
                    if (paramMap.containsKey("routerId")) {
                        if (!StringUtils.isEmpty(paramMap.get("routerId").toString())) {
                            routerId = Long.valueOf(paramMap.get("routerId").toString());
                            simple = false;
                        }
                        paramMap.remove("routerId");
                    }
                    if (paramMap.containsKey("hasIpv6")) {
                        hasIpv6 = Boolean.valueOf(paramMap.get("hasIpv6").toString());
                        simple = false;
                        paramMap.remove("hasIpv6");
                    }
                }
            }

            if (null == sorter) {
                sorter = Maps.newHashMap();
            }
            sorter.put("gmtCreate", Common.ONE);
            int total = subnetRepository.count(params, routerId);
            if (simple) {
                List<SimpleBean> beans = subnetRepository.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                List<Subnet> list = this.subnetRepository.list(page, rows, params, sorter, routerId, hasIpv6);
                List<Long> vpcIds = new ArrayList<>();
                List<Long> routeTableIds = new ArrayList<>();
                List<String> subnetUuidList = new ArrayList<>();
                // 处理关联资源
                for (Subnet subnet : list) {
                    Long vpcId = subnet.getVpcId();
                    vpcIds.add(vpcId);
                    routeTableIds.add(subnet.getRouterTableId());
                    subnetUuidList.add(subnet.getSubnetUuid());
                }
                Map<Long, String> routeTableNameMap = null;
                Map<Long, String> vpcNameMap = null;
                Map<String, Long> serverCountMap = null;

                if (CollectionUtils.isNotEmpty(vpcIds)) {
                    List<Vpc> vpcList = vpcRepository
                            .queryProxy()
                            .col(Vpc::getId).in(vpcIds)
                            .list();
                    vpcNameMap = vpcList.stream().collect(Collectors.toMap(Vpc::getId, Vpc::getName));
                }
                if (CollectionUtils.isNotEmpty(routeTableIds)) {
                    List<RouteTable> routeTables = routeTableRepository
                            .queryProxy()
                            .col(RouteTable::getId).in(routeTableIds)
                            .list();
                    routeTableNameMap = routeTables.stream().collect(Collectors.toMap(RouteTable::getId, RouteTable::getName));
                }
                if (CollectionUtils.isNotEmpty(subnetUuidList)) {
                    List<CloudServer> cloudServers = cloudServerRepository.queryProxy()
                            .col(CloudServer::getSubnetUuid).in(subnetUuidList)
                            .select(CloudServer::getSubnetUuid, CloudServer::getId)
                            .end()
                            .list();
                    serverCountMap = cloudServers.stream()
                            .collect(Collectors.groupingBy(CloudServer::getSubnetUuid, Collectors.counting()));
                }


                for (Subnet subnet : list) {
                    if (vpcNameMap != null) {
                        subnet.setVpcName(vpcNameMap.get(subnet.getVpcId()));
                    }
                    if (routeTableNameMap != null) {
                        subnet.setRouteTableName(routeTableNameMap.get(subnet.getRouterTableId()));
                    }
                    if (serverCountMap != null) {
                        subnet.setServerCount(Math.toIntExact(serverCountMap.computeIfAbsent(subnet.getSubnetUuid(), (key) -> 0L)));
                    }
                }

                gridBean = GridHelper.getBean(page, rows, total, list);
            }
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("Query subnet list fail:", e);
            return new BocloudResult<>(false, "查询失败", null, null);
        }
    }

    @Override
    public BocloudResult create(Subnet subnetParam, RequestContext context) {
        Long region = subnetParam.getRegion();
        String name = subnetParam.getName();
        Long networkId = subnetParam.getNetworkId();
        String ipPools = subnetParam.getIpPools();
        String cidr = subnetParam.getCidr();
        String gateway = subnetParam.getGateway();
        String dnsNames = subnetParam.getDnsNames();
        String hostRoutes = subnetParam.getHostRoutes();
        boolean dhcpEnabled = subnetParam.getDhcpEnabled() == null ? false : subnetParam.getDhcpEnabled();
        Region reg = null;
        Long vid = subnetParam.getVendorId();
        try {
            // 公有云没有network
            Network network = networkRepository.query(networkId);
            if (null == network && null == vid) {
                logger.error("get cloudVendor failure!");
                return new BocloudResult<>(false, "网络不存在!");
            } else {
                if (null != network) {
                    vid = network.getVendorId();
                }
            }
            CloudVendor vendor = cloudVendorRepository.query(vid);
            if (null == vendor) {
                logger.error("get cloudVendor failure!");
                return new BocloudResult<>(false, "云平台不存在!");
            }
            if (CloudProvider.TENCENT.name().equals(vendor.getType())
                || CloudProvider.QCLOUD.name().equals(vendor.getType())
                || CloudProvider.TCE.name().equals(vendor.getType())
                || CloudProvider.PQCLOUD.name().equals(vendor.getType())) {
                return createPublicSubnet(subnetParam, context, vendor);
            } else if (CloudProvider.MANAGEONE.name().equals(vendor.getType())) {
                return createManageOneSubnet(subnetParam, context, vendor);
            } else if (CloudProvider.AZURE.name().equals(vendor.getType())) {
                return createAzureSubnet(subnetParam, context, vendor);
            } else if (CloudProvider.AWS.name().equals(vendor.getType())) {
                Long vpcId = subnetParam.getId();
                Vpc vpc = vpcRepository.query(vpcId);
                if (null == vpc) {
                    logger.error("get vpc failure!");
                    return new BocloudResult<>(false, "网络不存在!");
                }
                String sonCidr = subnetParam.getCidr();
                // 检查输入准确性
                BocloudResult validate = validateSubnet(sonCidr);
                if (validate.isFailed()) {
                    return validate;
                }
                Long zoneId = subnetParam.getZoneId();
                Zone zone = zoneRepository.query(zoneId);
                if (null == zone) {
                    logger.error("get zone failure!");
                    return new BocloudResult<>(false, "可用区不存在!");
                }
                SubnetModel model = new SubnetModel();
                model.setName(name);
                model.setVpcUuid(vpc.getVpcId());
                model.setCidr(sonCidr);
                model.setIpv6Cidr(subnetParam.getIpv6Cidr());
                model.setZone(zone.getName());
                BocloudResult result = subnetDriver.create(vendor.getUuid(), vpc.getRegionId(), model);
                if (result.isFailed()) {
                    logger.info(result.getMessage());
                    return new BocloudResult<>(false, "创建失败：" + result.getMessage());
                }
                SubnetModel newSubnetModel =
                    JSONObject.parseObject(JSONObject.toJSONString(result.getData()), SubnetModel.class);
                Subnet subnet = new Subnet();
                BeanUtils.copyProperties(newSubnetModel, subnet);
                subnet.setNetworkId(vpc.getId());
                subnet.setCreatorId(context.getTarget());
                subnet.setVendorId(vendor.getId());
                subnet.setVpcUuid(vpc.getVpcId());
                subnet.setRegionId(vpc.getRegionId());
                subnet.setVpcId(vpc.getId());
                subnetRepository.save(subnet);
                if (!ListTool.isEmpty(newSubnetModel.getCidrBlockModels())) {
                    for (CidrBlockModel cidrBlockModel : newSubnetModel.getCidrBlockModels()) {
                        CidrBlock cidrBlock = new CidrBlock();
                        BeanUtils.copyProperties(cidrBlockModel, cidrBlock);
                        cidrBlock.setCreatorId(context.getTarget());
                        cidrBlock.setVendorId(vendor.getId());
                        cidrBlock.setRegionId(subnet.getRegionId());
                        cidrBlockRepository.save(cidrBlock);
                    }
                }
                return new BocloudResult<>(true, subnet, "创建成功!");
            } else if (CloudProvider.HUAWEI.name().equals(vendor.getType())) {
                return createHuaweiSubnet(vendor, subnetParam, context);
            } else if (CloudProvider.JDCLOUD.name().equals(vendor.getType())) {
                return createJdCloudSubnet(vendor, subnetParam, context);
            } else if (CloudProvider.ALIYUN.name().equals(vendor.getType())) {
                return aliyunSubnet(vendor, subnetParam, context);
            } else if (CloudProvider.TIANYI.name().equals(vendor.getType())) {
                return createTianyiSubnet(vendor, subnetParam, context);
            } else {
                final Long vendorId = vendor.getId();
                if (!CloudProvider.OPENSTACK.name().equals(vendor.getType())
                    && !CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())
                    && !CloudProvider.MANAGEONE.name().equals(vendor.getType())) {
                    reg = regionRepository.query(region);
                    if (null == reg) {
                        logger.error("get region failure!");
                        return new BocloudResult<>(false, "创建失败!");
                    }
                }
                if (null == network) {
                    return new BocloudResult<>(false, "网络不存在!");
                }
                // 检查输入准确性
                BocloudResult validate = validateSubnet(cidr, ipPools, gateway, dnsNames, hostRoutes);
                if (validate.isFailed()) {
                    return validate;
                }
                Map<String, Object> param = JSONObject.parseObject(JSONObject.toJSONString(validate.getData()));
                param.put("name", name);
                param.put("networkUuid", network.getNetworkUuid());
                param.put("dhcpEnabled", dhcpEnabled);
                param.put("hostRoutes", hostRoutes);
                SubnetModel model = JSONObject.parseObject(JSONObject.toJSONString(param), SubnetModel.class);
                BocloudResult result = null;
                TenantProvider provider = vendorProjectService.getAncestorProject(vendor.getId(), context.getTenant());
                String projectName = null;
                if (null != provider) {
                    projectName = provider.getProjectName();
                } else {
                    OSTenant osTenant = osTenantRepository.getByTenantUuid(network.getTenantUuid(), vendorId);
                    if (null != osTenant) {
                        projectName = osTenant.getName();
                    }
                }
                if (null == reg) {
                    result = subnetDriver.create(vendor.getUuid(), projectName, null, model);
                } else {
                    result = subnetDriver.create(vendor.getUuid(), projectName, reg.getCode(), model);
                }
                if (result.isFailed()) {
                    logger.info(result.getMessage());
                    return new BocloudResult<>(false, "创建失败：" + result.getMessage());
                }
                Subnet subnet = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Subnet.class);
                subnet.setRegion(region);
                subnet.setIpPools(subnet.getIpPools());
                subnet.setNetworkUuid(network.getNetworkUuid());
                subnet.setHostRoutes(hostRoutes);
                subnet.preSave(context.getTarget(), context.getTarget(), vendorId, networkId);
                subnet.setTenantUuid(network.getTenantUuid());
                subnet.setVpcId(subnetParam.getVpcId());
                subnetRepository.save(subnet);
                // syncIpPool(subnet, true, vendorId, context.getTarget(), networkId);
                // 同步端口
                threadQueue.execute(() -> {
                    if (CloudProvider.OPENSTACK.name().equals(vendor.getType())) {
                        try {
                            Thread.sleep(10000);
                            OpenstackTransportor toolOS = new OpenstackTransportor(subnetRepository, portRepository,
                                ipRepository, ipPoolRepository, portFixedIpRepository);
                            BocloudResult resultPort =
                                locationDriver.syncPortByNetworkUuid(vendor.getUuid(), network.getNetworkUuid());
                            if (resultPort.isSuccess()) {
                                Object data = resultPort.getData();
                                if (null != data) {
                                    String content = JSONObject.toJSONString(data);
                                    OSSyncModel modelObj = JSONObject.parseObject(content, OSSyncModel.class);
                                    toolOS.syncPort4Network(modelObj.getPortModels(), vendorId, context.getTarget(),
                                        context.getTenant(), network);
                                }
                            }
                        } catch (Exception e) {
                            logger.info("同步端口失败", e);
                        }
                    }
                });
                return new BocloudResult<>(true, subnet, "创建成功!");
            }
        } catch (Exception e) {
            logger.error("create subnet failure:", e);
            return new BocloudResult<>(false, "创建失败:" + e.getMessage());
        }
    }

    private BocloudResult createAzureSubnet(Subnet subnetParam, RequestContext context, CloudVendor vendor) {
        try {
            String name = subnetParam.getName();
            String cidr = subnetParam.getCidr();
            Long vpcId = subnetParam.getId();
            Long securityGroupId = subnetParam.getSecurityGroupId();
            Vpc vpc = vpcRepository.query(vpcId);
            if (null == vpc) {
                logger.error("get vpc failure!");
                return new BocloudResult<>(false, "网络不存在!");
            }
            // 检查输入准确性
            BocloudResult validate = validateSubnet(cidr);
            if (validate.isFailed()) {
                return validate;
            }
            SecurityGroup securityGroup = securityGroupRepository.query(securityGroupId);
            SubnetModel model = new SubnetModel();
            model.setName(name);
            model.setVpcUuid(vpc.getVpcId());
            model.setCidr(cidr);
            if (null != securityGroup) {
                model.setSecurityGroupUuid(securityGroup.getGroupUuid());
            }
            taskExecutor.execute(() -> {
                String operate = vendor.getType().toLowerCase() + ".subnet";
                String message = "创建子网失败";
                BocloudResult result = subnetDriver.create(vendor.getUuid(), vpc.getRegionId(), model);
                try {
                    if (result.isSuccess()) {
                        message = "尊敬的客户，您好！您的子网【" + name + "】于"
                            + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "创建成功，请登录控制台查看及管理。";
                        SubnetModel newSubnetModel =
                            JSONObject.parseObject(JSONObject.toJSONString(result.getData()), SubnetModel.class);
                        Subnet subnet = new Subnet();
                        BeanUtils.copyProperties(newSubnetModel, subnet);
                        subnet.setNetworkId(vpc.getId());
                        subnet.setCreatorId(context.getTarget());
                        subnet.setVendorId(vendor.getId());
                        subnet.setVpcUuid(vpc.getVpcId());
                        subnet.setRegionId(vpc.getRegionId());
                        subnet.setVpcId(vpc.getId());
                        if (null != securityGroup) {
                            subnet.setSecurityGroupId(securityGroup.getId());
                        }
                        subnetRepository.save(subnet);
                    } else {
                        message = "尊敬的客户，您好！您的子网【" + name + "】于"
                            + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "创建失败，失败信息："
                            + result.getMessage();
                        logger.error("创建子网失败：" + result.getMessage());
                        message = result.getMessage();
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate,
                        MapTools.simpleMap("vendorId", vendor.getId()), OperateResult.OperateCategory.ResourceEvent,
                        context));
                    // //站内信推送
                    // NotifyMessage notifyMessage = new NotifyMessage(context, "子网:", message, null,
                    // true, false);
                    // amqpTemplate.convertAndSend("event.notice.queue", notifyMessage);
                } catch (Exception e) {
                    logger.error("create subnet fail:", e);
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate,
                        MapTools.simpleMap("vendorId", vendor.getId()), OperateResult.OperateCategory.ResourceEvent,
                        context));
                }
            });
            return new BocloudResult(true, "创建子网任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("create subnet error!", e);
            return new BocloudResult(false, e.getMessage());
        }

    }

    private BocloudResult aliyunSubnet(CloudVendor vendor, Subnet subnetParam, RequestContext context) {
        try {
            Long vpcId = subnetParam.getId();
            Vpc vpc = vpcRepository.query(vpcId);
            Assert.notNull(subnetParam, "VPC不存在");
            String cidr = subnetParam.getCidr();
            // 检查输入准确性
            BocloudResult validate = validateSubnet(cidr);
            if (validate.isFailed()) {
                return validate;
            }
            Long zoneId = subnetParam.getZoneId();
            Zone zone = zoneRepository.query(zoneId);
            Assert.notNull(zone, "可用区不存在!");
            boolean ipv6Enable = subnetParam.getIpV6Enable();
            String ipv6Cidr = subnetParam.getIpv6Cidr();
            SubnetModel model = new SubnetModel();
            model.setName(subnetParam.getName());
            model.setVpcUuid(vpc.getVpcId());
            model.setCidr(cidr);
            model.setZone(zone.getZoneId());
            model.setResourceGroupUuid(vpc.getResourceGroupUuid());
            model.setRemark(subnetParam.getRemark());
            model.setIpV6Enable(ipv6Enable);
            model.setIpv6Cidr(ipv6Cidr);
            model.setRegionId(vpc.getRegionId());
            new Thread(() -> {
                BocloudResult result = null;
                String content = "申请创建交换机失败";
                String operate = vendor.getType().toLowerCase() + ".subnet";
                try {
                    result = subnetDriver.create(vendor.getUuid(), vpc.getRegionId(), model);
                    if (result.isSuccess()) {
                        SubnetModel newSubnetModel =
                            JSONObject.parseObject(JSONObject.toJSONString(result.getData()), SubnetModel.class);
                        Subnet subnet = new Subnet();
                        BeanUtils.copyProperties(newSubnetModel, subnet);
                        subnet.setNetworkId(vpc.getId());
                        subnet.setCreatorId(context.getTarget());
                        subnet.setVendorId(vendor.getId());
                        subnet.setVpcUuid(vpc.getVpcId());
                        subnet.setRegionId(vpc.getRegionId());
                        subnet.setVpcId(vpc.getId());
                        subnetRepository.save(subnet);
                        // 保存 CidrBlock
                        if (!StringUtils.isEmpty(newSubnetModel.getIpv6Cidr())) {
                            CidrBlock cidrBlock = new CidrBlock();
                            cidrBlock.setCidrBlock(newSubnetModel.getIpv6Cidr());
                            cidrBlock.setType("IPV6");
                            cidrBlock.setMenderId(context.getTarget());
                            cidrBlock.setTargetId(subnet.getSubnetUuid());
                            cidrBlock.setCreatorId(context.getTarget());
                            cidrBlock.setGmtModify(new Date());
                            cidrBlock.setVendorId(vendor.getId());
                            cidrBlock.setRegionId(subnet.getRegionId());
                            cidrBlockRepository.save(cidrBlock);
                        }
                        content = "交换机创建成功";
                    } else {
                        content = result.getMessage();
                    }
                } catch (Exception e) {
                    logger.error("Get error message:", e);
                    content = e.getMessage();
                }
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                    MapTools.simpleMap(Common.VENDORID, vendor.getId()), OperateResult.OperateCategory.ResourceEvent,
                    context));
            }).start();
            return new BocloudResult(true, "子网创建任务已下发，正在执行...");

        } catch (Exception e) {
            logger.error("子网创建失败：" + e.getMessage());
            return new BocloudResult<>(false, "子网创建失败：" + e.getMessage());
        }
    }

    private BocloudResult<String> createManageOneSubnet(Subnet subnetParam, RequestContext context,
        CloudVendor vendor) {
        try {
            Long routerId = subnetParam.getRouterId();
            Router router = routerRepository.query(routerId);
            if (null == router) {
                logger.error("get vpc failure!");
                return new BocloudResult<>(false, "虚拟VPC数据异常!");
            }
            String cidr = subnetParam.getCidr();
            // 检查输入准确性
            BocloudResult validate = validateSubnet(cidr);
            if (validate.isFailed()) {
                return validate;
            }
            SubnetModel model = JSONObject.parseObject(JSON.toJSONString(subnetParam), SubnetModel.class);
            model.setRouterUuid(router.getRouterUuid());
            new Thread(new Runnable() {

                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".subnet";
                    String content = "子网创建失败！";
                    BocloudResult result = new BocloudResult<>(false, content);
                    try {
                        if (CloudProvider.MANAGEONE.name().equals(vendor.getType()) && null != context.getTenant()
                            && 0L != context.getTenant()) {
                            ManageOneAccount account = accountService.queryAccount(vendor.getId(), context.getTenant());
                            Assert.notNull(account, "认证失败！");
                            result = subnetDriver.create(vendor.getUuid(), model, account.getUsername(),
                                account.getPassword(), account.getProjectId(), account.getDomainName());
                        } else {
                            result = subnetDriver.create(vendor.getUuid(), model.getRegionId(), model);
                        }
                        if (result.isSuccess()) {
                            Subnet subnet =
                                JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Subnet.class);
                            // 为了数据完整性 保存网络 and 路由关系表数据
                            Network network = new Network();
                            network.setNetworkUuid(subnet.getNetworkUuid());
                            network.setVendorId(vendor.getId());
                            network.setCreatorId(context.getTarget());
                            network.setMenderId(context.getTarget());
                            networkRepository.save(network);

                            subnet.setRegionId(model.getRegionId());
                            subnet.setZone(model.getZone());
                            subnet.preSave(context.getTarget(), context.getTarget(), vendor.getId(), null);
                            subnet.setNetworkId(network.getId());
                            subnet.setRouterId(routerId);
                            String vpcUuid = subnet.getVpcUuid();
                            if (!StringUtils.isEmpty(vpcUuid)) {
                                Vpc vpc = vpcRepository.getByUuid(vpcUuid, vendor.getId());
                                if (null != vpc) {
                                    subnet.setVpcId(vpc.getId());
                                }
                            }
                            subnetRepository.save(subnet);

                            // 保存关系表数据
                            RouterSubnet routerSubnet =
                                new RouterSubnet(router.getId(), subnet.getId(), vendor.getId());
                            routerSubnetRepository.save(routerSubnet);

                            content = "子网创建成功！";
                        } else {
                            content = result.getMessage();
                        }
                    } catch (Exception e) {
                        logger.error("子网创建失败：" + result.getMessage());
                        content = result.getMessage();
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
                }
            }).start();
            return new BocloudResult<>(true, "创建子网任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("子网创建失败：" + e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }

    }

    private BocloudResult<String> createPublicSubnet(Subnet subnetParam, RequestContext context, CloudVendor vendor) {
        try {
            Long vpcId = subnetParam.getId();
            Vpc vpc = vpcRepository.query(vpcId);
            if (null == vpc) {
                logger.error("get vpc failure!");
                return new BocloudResult<>(false, "网络不存在!");
            }
            String name = subnetParam.getName();
            String cidr = subnetParam.getCidr();
            String zone = subnetParam.getZone();
            String regionId = subnetParam.getRegionId();
            Long routerId = subnetParam.getRouterId();
            String zoneNum = subnetParam.getZoneNum();
            String gateway = subnetParam.getGateway();
            // 检查输入准确性
            BocloudResult validate = validateSubnet(cidr);
            if (validate.isFailed()) {
                return validate;
            }
            Map<String, Object> param = new HashMap<String, Object>(8);
            param.put("vpcUuid", vpc.getVpcId());
            param.put("name", name);
            param.put("cidr", cidr);
            param.put("zone", zone);
            param.put("zoneNum", zoneNum);
            param.put("regionId", regionId);

            SubnetModel model = JSONObject.parseObject(JSONObject.toJSONString(param), SubnetModel.class);
            new Thread(new Runnable() {

                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".subnet";
                    String content = "子网创建失败！";
                    BocloudResult result = new BocloudResult<>(false, content);
                    try {
                        Long vpcId = subnetParam.getId();
                        Vpc vpc = vpcRepository.query(vpcId);
                        result = subnetDriver.create(vendor.getUuid(), model.getRegionId(), model);
                        if (result.isSuccess()) {
                            Subnet subnet =
                                JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Subnet.class);
                            subnet.setNetworkUuid(vpc.getVpcId());
                            subnet.setRegionId(vpc.getRegionId());
                            subnet.setVpcUuid(vpc.getVpcId());
                            subnet.setZone(model.getZone());
                            subnet.preSave(context.getTarget(), context.getTarget(), vendor.getId(), null);
                            subnet.setNetworkId(vpc.getId());
                            subnet.setVpcId(vpc.getId());
                            subnetRepository.save(subnet);
                            content = "子网创建成功！";
                        } else {
                            content = result.getMessage();
                        }
                    } catch (Exception e) {
                        logger.error("子网创建失败：" + result.getMessage());
                        content = result.getMessage();
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
                }
            }).start();
            return new BocloudResult<>(true, "创建子网任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("子网创建失败：" + e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    private BocloudResult createHuaweiSubnet(CloudVendor vendor, Subnet subnetParam, RequestContext context)
        throws Exception {
        Long id = subnetParam.getId();
        SubnetModel model = new SubnetModel();
        String cidr = subnetParam.getCidr();
        String ipPools = subnetParam.getIpPools();
        String dnsNames = subnetParam.getDnsNames() == null ? subnetParam.getDnsName() : subnetParam.getDnsNames();
        String gateway = subnetParam.getGateway();
        String zone = subnetParam.getZone();
        String name = subnetParam.getName();
        Vpc vpc = vpcRepository.query(id);
        if (null == vpc) {
            logger.error("get cloudVendor failure!");
            return new BocloudResult<>(false, "vpc不存在!");
        }
        // 华为云 dnsIP 最多可以指定两个IP
        if (null != dnsNames && dnsNames.length() > 0) {
            List<String> dnsList = new ArrayList<>();
            String[] dnsArr = dnsNames.split("\\n");
            if (dnsArr.length > 2) {
                return new BocloudResult<>(false, "DNS服务器地址最多支持2个IP");
            } else {
                for (String dns : dnsArr) {
                    dnsList.add(dns);
                }
            }
            dnsNames = JSON.toJSONString(dnsList);
        }

        // 检查输入准确性
        BocloudResult validate = validateSubnet(cidr, ipPools, gateway, dnsNames, null);
        if (validate.isFailed()) {
            return validate;
        }
        JSONObject param = JSONObject.parseObject(JSONObject.toJSONString(validate.getData()));
        model.setDnsNames(dnsNames);
        model.setCidr(cidr);
        model.setName(name);
        model.setGateway(param.getString("gateway"));
        model.setVpcUuid(vpc.getVpcId());
        model.setZone(zone);
        BocloudResult result = subnetDriver.create(vendor.getUuid(), vpc.getRegionId(), model);
        if (result.isSuccess()) {
            Subnet subnet = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Subnet.class);
            subnet.setRegionId(vpc.getRegionId());
            subnet.setIpPools(param.getString("ipPools"));
            subnet.setVpcUuid(vpc.getVpcId());
            subnet.setVpcId(vpc.getId());
            subnet.setZone(zone);
            subnet.preSave(context.getTarget(), context.getTarget(), vendor.getId(), null);
            subnetRepository.save(subnet);
        }
        return result;
    }

    private BocloudResult createJdCloudSubnet(CloudVendor vendor, Subnet subnetParam, RequestContext context)
        throws Exception {
        Long vpcId = subnetParam.getVpcId();
        SubnetModel model = new SubnetModel();
        String cidr = subnetParam.getCidr();
        String name = subnetParam.getName();
        Long routeTableId = subnetParam.getRouterTableId();
        Vpc vpc = vpcRepository.query(vpcId);
        if (null == vpc) {
            logger.error("get cloudVendor failure!");
            return new BocloudResult<>(false, "vpc不存在!");
        }
        RouteTable routeTable = routeTableRepository.query(routeTableId);
        if (null == routeTable) {
            return new BocloudResult<>(false, "路由表不存在!");
        }

        // 检查输入准确性
        BocloudResult validate = validateSubnet(cidr, null, null, null, null);
        if (validate.isFailed()) {
            return validate;
        }
        JSONObject param = JSONObject.parseObject(JSONObject.toJSONString(validate.getData()));
        model.setCidr(cidr);
        model.setName(name);
        model.setVpcUuid(vpc.getVpcId());
        model.setRouteTableId(routeTable.getUuid());
        BocloudResult result = subnetDriver.create(vendor.getUuid(), vpc.getRegionId(), model);
        if (result.isSuccess()) {
            Subnet subnet = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Subnet.class);
            subnet.setRegionId(vpc.getRegionId());
            subnet.setVpcId(vpc.getId());
            subnet.setRouterTableId(routeTableId);
            subnet.preSave(context.getTarget(), context.getTarget(), vendor.getId(), null);
            subnetRepository.save(subnet);
        }
        return result;
    }

    private BocloudResult createTianyiSubnet(CloudVendor vendor, Subnet subnetParam, RequestContext context)
        throws Exception {
        Long id = subnetParam.getId();
        SubnetModel model = new SubnetModel();
        String regionId = subnetParam.getRegionId();
        String cidr = subnetParam.getCidr();
        String ipPools = subnetParam.getIpPools();
        String dnsNames = subnetParam.getDnsNames();
        String gateway = subnetParam.getGateway();
        String zone = subnetParam.getZone();
        String name = subnetParam.getName();
        String primaryDns = "";
        String secondaryDns = "";
        Vpc vpc = vpcRepository.query(id);
        if (null == vpc) {
            logger.error("get cloudVendor failure!");
            return new BocloudResult<>(false, "vpc不存在!");
        }
        // 天翼云 dnsIP 最多可以指定两个IP
        if (null != dnsNames && dnsNames.length() > 0) {
            List<String> dnsList = new ArrayList<>();
            String[] dnsArr = dnsNames.split("\\n");
            if (dnsArr.length == 1) {
                primaryDns = dnsArr[0];
            } else if (dnsArr.length == 2) {
                primaryDns = dnsArr[0];
                secondaryDns = dnsArr[1];
            } else if (dnsArr.length > 2) {
                return new BocloudResult<>(false, "DNS服务器地址最多支持2个IP");
            } else {
                for (String dns : dnsArr) {
                    dnsList.add(dns);
                }
            }

            dnsNames = JSON.toJSONString(dnsList);
        }

        // 检查输入准确性
        BocloudResult validate = validateSubnet(cidr, ipPools, gateway, dnsNames, null);
        if (validate.isFailed()) {
            return validate;
        }
        JSONObject param = JSONObject.parseObject(JSONObject.toJSONString(validate.getData()));
        model.setRegionId(regionId);
        model.setCidr(cidr);
        model.setName(name);
        model.setGateway(param.getString("gateway"));
        model.setVpcUuid(vpc.getVpcId());
        model.setZone(zone);
        BocloudResult result = subnetDriver.create(vendor.getUuid(), vpc.getRegionId(), model);
        if (result.isSuccess()) {
            SubnetModel subnetModel = (SubnetModel)result.getData();
            model.setPrimaryDns(primaryDns);
            model.setSecondaryDns(secondaryDns);
            model.setDnsNames(dnsNames);
            model.setSubnetUuid(subnetModel.getSubnetUuid());
            BocloudResult modify = subnetDriver.modify(vendor.getUuid(), vpc.getRegionId(), model);
            if (modify.isSuccess()) {
                Subnet subnet = JSONObject.parseObject(JSONObject.toJSONString(modify.getData()), Subnet.class);
                subnet.setRegionId(vpc.getRegionId());
                subnet.setIpPools(param.getString("ipPools"));
                subnet.setVpcUuid(vpc.getVpcId());
                subnet.setZone(zone);
                subnet.preSave(context.getTarget(), context.getTarget(), vendor.getId(), null);
                subnet.setVpcId(subnetParam.getVpcId());
                subnetRepository.save(subnet);
            }
        }
        return result;
    }

    @Override
    public BocloudResult<String> modify(Subnet subnet, RequestContext context) {
        Assert.notNull(subnet, "参数格式错误");
        Long vendorId = subnet.getVendorId();
        Long id = subnet.getId();
        Long region = subnet.getRegion();
        String name = subnet.getName();
        Long networkId = subnet.getNetworkId();
        String subnetUuid = subnet.getSubnetUuid();
        String networkUuid = subnet.getNetworkUuid();
        String ipPools = subnet.getIpPools();
        String cidr = subnet.getCidr();
        String gateway = subnet.getGateway();
        String dnsNames = subnet.getDnsNames();
        String hostRoutes = subnet.getHostRoutes();
        boolean dhcpEnabled = subnet.getDhcpEnabled() == null ? false : subnet.getDhcpEnabled();
        BocloudResult result = null;
        try {
            Subnet subnetOld = subnetRepository.query(id);
            if (subnetOld == null) {
                return new BocloudResult<>(false, "修改失败,子网不存在");
            }
            CloudVendor cloudVendor = cloudVendorRepository.query(vendorId);
            if (null == cloudVendor) {
                logger.error("get cloudVendor failure!");
                return new BocloudResult<>(false, "修改失败!");
            }
            if (CloudProvider.HUAWEI.name().equals(cloudVendor.getType())
                || CloudProvider.MANAGEONE.name().equals(cloudVendor.getType())
                || CloudProvider.TENCENT.name().equals(cloudVendor.getType())
                || CloudProvider.TCE.name().equals(cloudVendor.getType())
                || CloudProvider.TIANYI.name().equals(cloudVendor.getType())) {
                return subnetModify(JSONObject.parseObject(JSON.toJSONString(subnet)), subnetOld, cloudVendor, context);
            }
            if (CloudProvider.JDCLOUD.name().equals(cloudVendor.getType())) {
                return jdCloudSubnetModify(subnet, subnetOld, cloudVendor, context.getTarget());
            }
            if (CloudProvider.ALIYUN.name().equals(cloudVendor.getType())) {
                return aliyunSubnetModify(subnet, subnetOld, cloudVendor, context.getTarget());
            }
            if (CloudProvider.AZURE.name().equals(cloudVendor.getType())) {
                return azureSubnetModify(JSONObject.parseObject(JSON.toJSONString(subnet)), subnetOld, cloudVendor,
                    context.getTarget());
            }
            if (CloudProvider.PQCLOUD.name().equals(cloudVendor.getType())
                || CloudProvider.AWS.name().equals(cloudVendor.getType())) {
                return pqcloudSubnetModify(JSONObject.parseObject(JSON.toJSONString(subnet)), subnetOld, cloudVendor,
                    context.getTarget());
            }
            Region reg = regionRepository.query(region);
            Network network = networkRepository.query(networkId);
            // 检查输入准确性
            BocloudResult validate = validateSubnet(cidr, ipPools, gateway, dnsNames, hostRoutes);
            if (validate.isFailed()) {
                return validate;
            }
            Map<String, Object> param = JSONObject.parseObject(JSONObject.toJSONString(validate.getData()));
            param.put("name", name);
            param.put("networkUuid", networkUuid);
            param.put("subnetUuid", subnetUuid);
            param.put("dhcpEnabled", dhcpEnabled);
            param.put("hostRoutes", hostRoutes);
            SubnetModel model = JSONObject.parseObject(JSONObject.toJSONString(param), SubnetModel.class);
            if (null == reg) {
                result = subnetDriver.modify(cloudVendor.getUuid(), subnetOld.getRegionId(), model);
            } else {
                result = subnetDriver.modify(cloudVendor.getUuid(), reg.getCode(), model);
            }
            if (null == result || result.isFailed()) {
                return new BocloudResult<>(false, "修改失败!");
            }
            SubnetModel subnetModel =
                JSONObject.parseObject(JSONObject.toJSONString(result.getData()), SubnetModel.class);
            BeanUtils.copyProperties(subnetModel, subnetOld);
            subnetOld.setIpPools(ipPools);
            subnetOld.setNetworkId(networkId);
            subnetOld.setNetworkUuid(networkUuid);
            subnetOld.setDnsNames(dnsNames);
            subnetOld.setHostRoutes(hostRoutes);
            subnetOld.setGateway(gateway);
            subnetRepository.update(subnetOld);
            if (CloudProvider.OPENSTACK.name().equals(cloudVendor.getType())
                || CloudProvider.FUSIONCLOUD.name().equals(cloudVendor.getType())) {
                // syncIpPool(subnetOld, false, vendorId, context.getTarget(), networkId);
            }
            // 同步端口
            threadQueue.execute(() -> {
                if (CloudProvider.OPENSTACK.name().equals(cloudVendor.getType())) {
                    try {
                        Thread.sleep(10000);
                        OpenstackTransportor toolOS = new OpenstackTransportor(subnetRepository, portRepository,
                            ipRepository, ipPoolRepository, portFixedIpRepository);
                        BocloudResult resultPort =
                            locationDriver.syncPortByNetworkUuid(cloudVendor.getUuid(), networkUuid);
                        if (resultPort.isSuccess()) {
                            Object data = resultPort.getData();
                            if (null != data) {
                                String content = JSONObject.toJSONString(data);
                                OSSyncModel modelObj = JSONObject.parseObject(content, OSSyncModel.class);
                                toolOS.syncPort4Network(modelObj.getPortModels(), vendorId, context.getTarget(),
                                    context.getTenant(), network);
                            }
                        }
                    } catch (Exception e) {
                        logger.info("同步端口失败", e);
                    }
                }
            });
            return new BocloudResult<>(true, "修改成功!");
        } catch (Exception e) {
            logger.error("create subnet failure:", e);
            return new BocloudResult<>(false, "修改失败 : " + e.getMessage());
        }
    }

    private BocloudResult<String> aliyunSubnetModify(Subnet subnetParam, Subnet subnetOld, CloudVendor cloudVendor,
        Long userId) {
        try {
            SubnetModel model = new SubnetModel();
            String name = subnetParam.getName();
            String remark = subnetParam.getRemark();
            model.setName(name);
            model.setRemark(remark);
            model.setVpcUuid(subnetOld.getVpcUuid());
            model.setSubnetUuid(subnetOld.getSubnetUuid());
            BocloudResult result = subnetDriver.modify(cloudVendor.getUuid(), subnetOld.getRegionId(), model);
            if (result.isSuccess()) {
                subnetOld.setGmtModify(new Date());
                subnetOld.setMenderId(userId);
                subnetOld.setName(name);
                subnetOld.setRemark(remark);
                subnetRepository.update(subnetOld);
                return new BocloudResult(true, "修改成功");
            } else {
                return new BocloudResult(false, result.getMessage());
            }
        } catch (Exception e) {
            logger.error("修改子网失败 ： " + e.getMessage());
            return new BocloudResult(false, "修改子网失败 ： " + e.getMessage());
        }
    }

    private BocloudResult<String> jdCloudSubnetModify(Subnet subnetParam, Subnet subnetOld, CloudVendor cloudVendor,
        Long userId) {
        try {
            SubnetModel model = new SubnetModel();
            String name = subnetParam.getName();
            String remark = subnetParam.getRemark();
            model.setName(name);
            model.setRemark(remark);
            model.setSubnetUuid(subnetOld.getSubnetUuid());
            BocloudResult result = subnetDriver.modify(cloudVendor.getUuid(), subnetOld.getRegionId(), model);
            if (result.isSuccess()) {
                subnetOld.setGmtModify(new Date());
                subnetOld.setMenderId(userId);
                subnetOld.setName(name);
                subnetOld.setRemark(remark);
                subnetRepository.update(subnetOld);
                return new BocloudResult(true, "修改成功");
            } else {
                return new BocloudResult(false, result.getMessage());
            }
        } catch (Exception e) {
            logger.error("修改子网失败 ： " + e.getMessage());
            return new BocloudResult(false, "修改子网失败 ： " + e.getMessage());
        }
    }

    private BocloudResult<String> subnetModify(JSONObject object, Subnet subnet, CloudVendor cloudVendor,
        RequestContext context) {
        try {
            String dns = object.getString("dnsNames");
            boolean dhcpEnabled = object.getBooleanValue("dhcpEnabled");
            String name = object.getString(Common.NAME);
            if (StringUtils.isEmpty(name)) {
                return new BocloudResult<>(false, "子网名称不合法!");
            }
            if (!StringUtils.isEmpty(dns)) {
                List<String> list = JSONObject.parseArray(dns, String.class);
                if (!ListTool.isEmpty(list)) {
                    for (String value : list) {
                        if (!IPAddress.ipv4Validate(value) && !IPAddress.ipv6Validate(value)) {
                            return new BocloudResult<>(false, "DNS不合法，请检查");
                        }
                    }
                }
            }
            SubnetModel model = new SubnetModel();
            model.setDnsNames(dns);
            model.setDhcpEnabled(dhcpEnabled);
            model.setSubnetUuid(subnet.getSubnetUuid());
            model.setName(name);
            model.setVpcUuid(subnet.getVpcUuid());
            model.setRegionId(subnet.getRegionId());
            BocloudResult result = null;
            if (CloudProvider.MANAGEONE.name().equals(cloudVendor.getType()) && null != context.getTenant()
                && 0L != context.getTenant()) {
                ManageOneAccount account = accountService.queryAccount(cloudVendor.getId(), context.getTenant());
                Assert.notNull(account, "认证失败！");
                result = subnetDriver.modify(cloudVendor.getUuid(), subnet.getRegionId(), model);
            } else {
                result = subnetDriver.modify(cloudVendor.getUuid(), subnet.getRegionId(), model);
            }
            if (result.isSuccess()) {
                subnet.setDnsNames(dns);
                subnet.setName(name);
                subnet.setDhcpEnabled(dhcpEnabled);
                subnet.setGmtModify(new Date());
                subnet.setMenderId(context.getTarget());
                subnetRepository.update(subnet);
                return new BocloudResult<>(true, "修改成功");
            } else {
                return new BocloudResult<>(false, result.getMessage());
            }
        } catch (Exception e) {
            logger.error("修改子网失败 ： " + e.getMessage());
            return new BocloudResult<>(false, "修改子网失败 ： " + e.getMessage());
        }
    }

    private BocloudResult<String> pqcloudSubnetModify(JSONObject object, Subnet subnet, CloudVendor cloudVendor,
        Long userId) {
        try {
            SubnetModel model = new SubnetModel();
            String name = object.getString("name");
            String remark = object.getString("remark");
            model.setName(name);
            model.setRemark(remark);
            model.setVpcUuid(subnet.getVpcUuid());
            model.setSubnetUuid(subnet.getSubnetUuid());
            BocloudResult result = subnetDriver.modify(cloudVendor.getUuid(), subnet.getRegionId(), model);
            if (result.isSuccess()) {
                subnet.setGmtModify(new Date());
                subnet.setMenderId(userId);
                subnet.setName(name);
                subnet.setRemark(remark);
                // 插入安全组id
                subnetRepository.update(subnet);
                return new BocloudResult<>(true, "修改成功");
            } else {
                return new BocloudResult<>(false, result.getMessage());
            }
        } catch (Exception e) {
            logger.error("修改子网失败 ： " + e.getMessage());
            return new BocloudResult<>(false, "修改子网失败 ： " + e.getMessage());
        }
    }

    private BocloudResult<String> azureSubnetModify(JSONObject object, Subnet subnet, CloudVendor cloudVendor,
        Long userId) {
        try {
            Long securityGroupId = object.getLong("securityGroupId");
            SecurityGroup securityGroup = securityGroupRepository.query(securityGroupId);

            SubnetModel model = new SubnetModel();
            model.setName(subnet.getName());
            model.setVpcUuid(subnet.getVpcUuid());
            if (null != securityGroup) {
                model.setSecurityGroupUuid(securityGroup.getGroupUuid());
            }
            BocloudResult result = subnetDriver.modify(cloudVendor.getUuid(), subnet.getRegionId(), model);
            if (result.isSuccess()) {
                subnet.setGmtModify(new Date());
                subnet.setMenderId(userId);
                // 插入安全组id
                if (null != securityGroup) {
                    subnet.setSecurityGroupId(securityGroup.getId());
                }
                subnetRepository.update(subnet);
                return new BocloudResult<>(true, "修改成功");
            } else {
                return new BocloudResult<>(false, result.getMessage());
            }
        } catch (Exception e) {
            logger.error("修改子网失败 ： " + e.getMessage());
            return new BocloudResult<>(false, "修改子网失败 ： " + e.getMessage());
        }
    }

    // public void syncIpPool(Subnet subnet, boolean isNew, Long vendorId, Long userId, Long networkId) throws Exception
    // {
    // if (isNew) {
    // IpPool pool = new IpPool(subnet.getGateway(), subnet.getCidr(), subnet.getIpPools(), subnet.getDnsNames(),
    // subnet.getId(), networkId, vendorId);
    // pool.setMenderId(userId);
    // pool.setCreatorId(userId);
    // pool.setVersion(IPAddress.getVersion(subnet.getGateway()));
    // ipPoolRepository.save(pool);
    // return;
    // }
    // IpPool pool = ipPoolRepository.queryBySubnet(subnet.getId(), vendorId);
    // if (null == pool) {
    // pool = new IpPool(subnet.getGateway(), subnet.getCidr(), subnet.getIpPools(), subnet.getDnsNames(),
    // subnet.getId(), networkId, vendorId);
    // pool.setMenderId(userId);
    // pool.setCreatorId(userId);
    // pool.setVersion(IPAddress.getVersion(subnet.getGateway()));
    // ipPoolRepository.save(pool);
    // return;
    // }
    // pool.setCidr(subnet.getCidr());
    // pool.setGateway(subnet.getGateway());
    // pool.setPools(subnet.getIpPools());
    // pool.setDnsNames(subnet.getDnsNames());
    // pool.setMenderId(userId);
    // ipPoolRepository.update(pool);
    // }

    private BocloudResult validateSubnet(String cidr) {
        if (StringUtils.isEmpty(cidr)) {
            return new BocloudResult<>(false, "网络地址不能为空！");
        }
        int index = cidr.indexOf("/");
        if (index < 0) {
            return new BocloudResult<>(false, "网络地址格式不正确，参考 address/prefix");
        }
        String address = cidr.substring(0, index);
        boolean result = IPAddress.ipv4Validate(address);
        String prefix = cidr.substring(index + 1);
        if (result) {
            result = Pattern.matches("^(\\d)|([1-2]\\d)|(3[0-2])$", prefix);
        } else {
            result = IPAddress.ipv6Validate(address);
            if (result) {
                result = Pattern.matches("^(\\d)|(\\d\\d)|(1[0-1]\\d)|(12[0-8])$", prefix);
            }
        }
        if (!result) {
            return new BocloudResult<>(false, "网络地址格式不正确，参考 address/prefix");
        }
        return new BocloudResult<>(true, "success");
    }

    private BocloudResult removeSubnet(SubnetModel model, CloudVendor vendor, Subnet subnet, RequestContext context) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String operate = vendor.getType().toLowerCase() + ".subnet";
                String content = "子网删除失败";
                BocloudResult result = new BocloudResult<>(false, content);
                try {
                    result = subnetDriver.remove(model, vendor.getUuid(), subnet.getRegionId());
                    if (result.isSuccess()) {
                        content = "删除成功！";
                        if (CloudProvider.QCLOUD.name().equalsIgnoreCase(vendor.getType())) {
                            subnetRepository.remove(subnet.getSubnetUuid(), vendor.getId(), subnet.getRegionId(),
                                context.getTarget());
                        } else {
                            subnetRepository.remove(subnet.getId(), context.getTarget());
                        }
                    } else {
                        content = result.getMessage();
                    }
                } catch (Exception e) {
                    logger.error("子网删除失败：" + e.getMessage());
                    result.setSuccess(false);
                    content = "子网删除失败：" + e.getMessage();
                }
                resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                    MapTools.simpleMap(Common.VENDORID, vendor.getId()), OperateResult.OperateCategory.ResourceEvent,
                    context));
            }
        }).start();
        return new BocloudResult<>(true, "删除任务已下发，正在执行...");
    }

    /**
     * 校验子网信息正确性
     *
     * @param cidr
     * @param ipPools
     * @param gateway
     * @param dns
     * @param hostRoutes
     * @return
     */
    private BocloudResult validateSubnet(String cidr, String ipPools, String gateway, String dns, String hostRoutes) {
        // 检查输入准确性
        if (StringUtils.isEmpty(cidr)) {
            return new BocloudResult<>(false, "子网掩码不能为空！");
        }
        int index = cidr.indexOf("/");
        if (index < 0) {
            return new BocloudResult<>(false, "网络地址格式不正确，参考 address/prefix");
        }
        // 判断是ipv4还是ipv6
        String address = cidr.substring(0, index);
        IPAddress ipAddress = new IPv4Address();
        boolean result = IPAddress.ipv4Validate(address);
        if (result) {
            result = Pattern.matches("^(\\d)|([1-2]\\d)|(3[0-2])$", cidr.substring(index + 1));
        } else {
            result = IPAddress.ipv6Validate(address);
            if (result) {
                result = Pattern.matches("^(\\d)|(\\d\\d)|(1[0-1]\\d)|(12[0-8])$", cidr.substring(index + 1));
            }
            ipAddress = new IPv6Address();
        }
        if (!result) {
            return new BocloudResult<>(false, "网络地址格式不正确，参考 address/prefix");
        }
        // 网关校验
        if (StringUtils.isEmpty(gateway)) {
            gateway = ipAddress.getDefaultGeteway(cidr);
        }
        if (StringUtils.isEmpty(ipPools)) {
            ipPools = ipAddress.getPools(gateway, cidr);
        } else {
            if (!ipAddress.isInRange(JSONObject.parseArray(ipPools, String.class), cidr)) {
                return new BocloudResult<>(false, "分配池超出范围或异常，请检查");
            }
        }
        if (ipAddress.isInPools(gateway, JSONObject.parseArray(ipPools, String.class))) {
            return new BocloudResult<>(false, "网关不允许包含在分配池内，请检查");
        }
        if (!StringUtils.isEmpty(dns)) {
            List<String> list = JSONObject.parseArray(dns, String.class);
            if (!ListTool.isEmpty(list)) {
                for (String value : list) {
                    if (!ipAddress.validate(value)) {
                        return new BocloudResult<>(false, "DNS不合法，请检查");
                    }
                }
            }
        }
        Map<String, Object> param = new HashMap<>(8);
        param.put("gateway", gateway);
        param.put("ipPools", ipPools);
        param.put("cidr", cidr);
        param.put("dnsNames", dns);
        return new BocloudResult<>(true, param, "success");
    }

    @Override
    public BocloudResult<String> remove(Long id, RequestContext context) {
        String path = Subnet.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Subnet subnet = subnetRepository.query(id);
            if (null == subnet) {
                logger.warn("subnet data not exist");
                return new BocloudResult<>(false, "数据不存在");
            }
            // 云供应商
            CloudVendor vendor = cloudVendorRepository.query(subnet.getVendorId());
            if (null == vendor) {
                logger.error("get cloud vendor failure");
                return new BocloudResult<>(false, "删除失败");
            }
            if (!CloudProvider.MANAGEONE.name().equals(vendor.getType())
                || !CloudProvider.JDCLOUD.name().equals(vendor.getType())) {
                List<Port> ports = portRepository.list(subnet.getVendorId(), subnet.getId());
                for (Port port : ports) {
                    if (StringUtils.isEmpty(port.getDeviceOwner()) || "network:dhcp".equals(port.getDeviceOwner())) {
                        continue;
                    }
                    return new BocloudResult<>(false, "该子网下存在正在使用的端口，无法删除");
                }
            }
            BocloudResult result = null;
            if (CloudProvider.HUAWEI.name().equals(vendor.getType())
                || CloudProvider.QCLOUD.name().equals(vendor.getType())
                || CloudProvider.TCE.name().equals(vendor.getType())
                || CloudProvider.PQCLOUD.name().equals(vendor.getType())
                || CloudProvider.TIANYI.name().equals(vendor.getType())) {
                SubnetModel model = new SubnetModel();
                model.setSubnetUuid(subnet.getSubnetUuid());
                model.setVpcUuid(subnet.getVpcUuid());
                model.setRegionId(subnet.getRegionId());
                return removeSubnet(model, vendor, subnet, context);
            } else if (CloudProvider.AZURE.name().equals(vendor.getType())) {
                SubnetModel model = new SubnetModel();
                model.setVpcUuid(subnet.getVpcUuid());
                model.setCidr(subnet.getCidr());
                model.setName(subnet.getName());
                result = subnetDriver.remove(model, vendor.getUuid(), subnet.getRegionId());
                if (result.isSuccess()) {
                    subnetRepository.remove(id, context.getTarget());
                }
            } else if (CloudProvider.MANAGEONE.name().equals(vendor.getType())) {
                SubnetModel model = JSON.parseObject(JSON.toJSONString(subnet), SubnetModel.class);
                if (null != context.getTenant() && 0L != context.getTenant()) {
                    ManageOneAccount account = accountService.queryAccount(vendor.getId(), context.getTenant());
                    Assert.notNull(account, "认证失败！");
                    result = subnetDriver.remove(model, vendor.getUuid(), account.getUsername(), account.getPassword(),
                        account.getProjectId(), account.getDomainName());
                } else {
                    result = subnetDriver.remove(model, vendor.getUuid(), subnet.getRegionId());
                }
            } else {
                result = subnetDriver.remove(subnet.getSubnetUuid(), vendor.getUuid(), subnet.getRegionId());
            }
            if (result.isFailed()) {
                return new BocloudResult<>(false, "删除失败:" + result.getMessage());
            }
            List<Port> portList = portRepository.listBySubnetId(id);
            for (Port port : portList) {
                List<PortFixedIp> fixedIps = portFixedIpRepository.listByPortId(port.getId());
                if (ListTool.isEmpty(fixedIps) || fixedIps.size() == 1) {
                    if (!StringUtils.isEmpty(port.getPortUuid())) {
                        portDriver.remove(port.getPortUuid(), vendor.getUuid(), null);
                    }
                    portRepository.remove(port.getId(), context.getTarget());
                    portFixedIpRepository.deleteByPortId(port.getId());
                } else {
                    portFixedIpRepository.delete(port.getId(), id);
                }
            }
            if (CloudProvider.AWS.name().equals(vendor.getType())
                || CloudProvider.ALIYUN.name().equals(vendor.getType())) {
                cidrBlockRepository.removeByVid(vendor.getId(), subnet.getRegionId(), context.getTarget(),
                    subnet.getSubnetUuid());
            }
            ipPoolRepository.removeBySubnetId(id, vendor.getId(), context.getTarget());
            ipRepository.deleteBySubnetId(id, vendor.getId());
            if (!CloudProvider.JDCLOUD.name().equals(vendor.getType())) {
                routerSubnetRepository.deleteBySubnet(id);
            }
            subnetRepository.remove(id, context.getTarget());
            if (CloudProvider.MANAGEONE.name().equals(vendor.getType())) {
                networkRepository.removeByNetworkUuid(subnet.getNetworkUuid(), context.getTarget());
            }
            return new BocloudResult<>(true, "删除成功");
        } catch (Exception e) {
            logger.error("remove subnet fail:", e);
            return new BocloudResult<>(false, "删除失败");
        }

    }

    @Override
    public BocloudResult<Subnet> detail(Long id) {
        try {
            Subnet subnet = subnetRepository.query(id);
            return new BocloudResult<>(true, subnet, "查询成功!");
        } catch (Exception e) {
            logger.error("query subnet detail failure:", e);
            return new BocloudResult<>(false, "查询详情失败!");
        }
    }

    @Override
    public BocloudResult<List<Subnet>> listByVendorId(Long vendorId, Long networkId, String tenantUuid) {
        try {
            List<Subnet> subnets = subnetRepository.listByVendorId(vendorId, networkId, tenantUuid);
            return new BocloudResult<>(true, subnets, "查询成功!");
        } catch (Exception e) {
            logger.error("query subnet detail failure:", e);
            return new BocloudResult<>(false, "查询详情失败!");
        }
    }

    @Override
    public BocloudResult<List<Subnet>> listAttachByRouter(Long vendorId, Long routerId) {
        try {
            List<Subnet> subnets = subnetRepository.listAttachByRouter(vendorId, routerId);
            return new BocloudResult<>(true, subnets, "查询成功!");
        } catch (Exception e) {
            logger.error("list subnet fail:", e);
            return new BocloudResult<>(false, "查询详情失败!");
        }
    }

    @Override
    public BocloudResult<List<Subnet>> listDetachByRouter(Long vendorId, Long routerId, Long networkId,
        String tenantUuid) {
        try {
            List<Subnet> subnets = subnetRepository.listDetachByRouter(vendorId, routerId, networkId, tenantUuid);
            Map<Long, Subnet> subnetMap = new HashMap<>(8);
            for (Subnet subnet : subnets) {
                subnetMap.put(subnet.getId(), subnet);
            }
            // 查询所有共享网络下的子网
            List<Subnet> attachSubnets = subnetRepository.listAttachByRouter(vendorId, routerId);
            Map<Long, Subnet> attachSubnetMap = new HashMap<>(8);
            for (Subnet subnet : attachSubnets) {
                attachSubnetMap.put(subnet.getId(), subnet);
            }
            List<Subnet> shareSubnets = subnetRepository.shareSubnets(vendorId, networkId);
            for (Subnet subnet : shareSubnets) {
                if (!attachSubnetMap.containsKey(subnet.getId())) {
                    subnetMap.put(subnet.getId(), subnet);
                }
            }
            // TODO 2020年1月17日14:59:30 电科云需求 路由连接子网时 过滤掉public 网络下的子网
            List<Network> externalNetwork = networkRepository.listExternalByVid(vendorId, null);
            if (null != externalNetwork && !externalNetwork.isEmpty()) {
                for (Network network : externalNetwork) {
                    List<Subnet> list = subnetRepository.list(vendorId, network.getId());
                    if (null != list && !list.isEmpty()) {
                        for (Subnet subnet : list) {
                            subnetMap.remove(subnet.getId());
                        }
                    }
                }
            }
            return new BocloudResult<>(true, new ArrayList<>(subnetMap.values()), "查询成功!");
        } catch (Exception e) {
            logger.error("list subnet fail:", e);
            return new BocloudResult<>(false, "查询详情失败!");
        }
    }

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

    @Override
    public BocloudResult<List<Subnet>> condition(String condition) {
        JSONObject object = JSONObject.parseObject(condition);

        String action = object.getString("condition");
        // 查询指定路由连接的子网
        if ("listattachbyrouter".equalsIgnoreCase(action)) {
            return this.listAttachByRouter(object.getLong(Common.VENDORID), object.getLong("routerId"));
        } else if ("listdetachbyrouter".equals(action)) {
            // 查询未连接该路由的子网
            return this.listDetachByRouter(object.getLong(Common.VENDORID), object.getLong("routerId"),
                object.getLong("networkId"), object.getString("tenantUuid"));
        } else if ("listbyvendor".equals(action)) {
            // 查询云平台下子网
            return this.listByVendorId(object.getLong(Common.VENDORID), object.getLong("networkId"),
                object.getString("tenantUuid"));
        } else {
            return ResultTools.formatErrResult();
        }
    }

    @Override
    public BocloudResult operations(Long id, SubnetParam subnetParam, RequestContext context) {
        if (null == subnetParam) {
            return new BocloudResult<>(false, "参数格式错误");
        }
        String action = subnetParam.getAction();
        if ("associateIpv6".equalsIgnoreCase(action)) {
            return this.associateIpv6(id, context, subnetParam.getIpv6Cidr());
        } else if ("disassociate".equalsIgnoreCase(action)) {
            return this.disassociate(id, context, subnetParam.getId());
        }
        return new BocloudResult(false, "无效操作！");
    }

    @Override
    public BocloudResult associateIpv6(Long id, RequestContext context, String ipv6CidrBlock) {
        try {
            Subnet subnet = subnetRepository.query(id);
            Assert.notNull(subnet, "subnet不存在");
            CloudVendor vendor = cloudVendorRepository.query(subnet.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            CloudProvider provider = CloudProvider.valueOf(vendor.getType());
            BocloudResult bocloudResult = null;
            BocloudResult detailResult = null;
            SubnetModel subnetModel = null;
            switch (provider) {
                case AWS:
                    bocloudResult = subnetDriver.associateIpv6CidrBlock(subnet.getSubnetUuid(), ipv6CidrBlock,
                        vendor.getUuid(), subnet.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    detailResult = subnetDriver.detail(subnet.getSubnetUuid(), vendor.getUuid(), subnet.getRegionId());
                    if (detailResult.isFailed()) {
                        return detailResult;
                    }
                    subnetModel = (SubnetModel)detailResult.getData();
                    for (CidrBlockModel cidrBlockModel : subnetModel.getCidrBlockModels()) {
                        if (bocloudResult.getData().toString().equals(cidrBlockModel.getUuid())) {
                            CidrBlock cidrBlock = new CidrBlock();
                            BeanUtils.copyProperties(cidrBlockModel, cidrBlock);
                            cidrBlock.setCreatorId(context.getTarget());
                            cidrBlock.setVendorId(vendor.getId());
                            cidrBlock.setRegionId(subnet.getRegionId());
                            cidrBlockRepository.save(cidrBlock);

                            subnet.setIpv6Cidr(cidrBlock.getCidrBlock());
                            subnetRepository.update(subnet);
                            break;
                        }
                    }
                    break;
                case HUAWEI:
                    subnetModel = new SubnetModel();
                    BeanUtils.copyProperties(subnet, subnetModel);
                    subnetModel.setIpV6Enable(true);
                    bocloudResult = subnetDriver.modify(vendor.getUuid(), subnet.getRegionId(), subnetModel);
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    detailResult = subnetDriver.detail(subnet.getSubnetUuid(), vendor.getUuid(), subnet.getRegionId());
                    if (detailResult.isFailed()) {
                        return detailResult;
                    }
                    subnetModel = (SubnetModel)detailResult.getData();

                    subnet.setIpv6Cidr(subnetModel.getIpv6Cidr());
                    subnetRepository.update(subnet);
                    break;
                case ALIYUN:
                    bocloudResult = subnetDriver.associateIpv6CidrBlock(subnet.getSubnetUuid(), ipv6CidrBlock,
                        vendor.getUuid(), subnet.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    detailResult = subnetDriver.detail(subnet.getSubnetUuid(), vendor.getUuid(), subnet.getRegionId());
                    if (detailResult.isFailed()) {
                        return detailResult;
                    }
                    subnetModel = (SubnetModel)detailResult.getData();
                    String ipv6Cidr = subnetModel.getIpv6Cidr();
                    if (!StringUtils.isEmpty(ipv6Cidr)) {
                        CidrBlock cidrBlock = new CidrBlock();
                        cidrBlock.setCidrBlock(ipv6Cidr);
                        cidrBlock.setType("IPV6");
                        cidrBlock.setMenderId(context.getTarget());
                        cidrBlock.setTargetId(subnet.getSubnetUuid());
                        cidrBlock.setCreatorId(context.getTarget());
                        cidrBlock.setGmtModify(new Date());
                        cidrBlock.setVendorId(vendor.getId());
                        cidrBlock.setRegionId(subnet.getRegionId());
                        cidrBlockRepository.save(cidrBlock);
                        subnet.setIpv6Cidr(ipv6Cidr);
                        subnetRepository.update(subnet);
                    }
                    break;
                default:
                    break;
            }
            return new BocloudResult(true, "SUBNET CIDR 保存成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult(false, e.getMessage());
        }

    }

    @Override
    public BocloudResult disassociate(Long id, RequestContext context, Long cidrId) {
        try {
            Subnet subnet = subnetRepository.query(id);
            Assert.notNull(subnet, "Subnet不存在");
            CloudVendor vendor = cloudVendorRepository.query(subnet.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            CloudProvider provider = CloudProvider.valueOf(vendor.getType());
            CidrBlock cidrBlock = null;
            BocloudResult bocloudResult = null;
            switch (provider) {
                case AWS:
                    cidrBlock = cidrBlockRepository.query(cidrId);
                    Assert.notNull(subnet, "CidrBlock不存在");
                    bocloudResult =
                        subnetDriver.disassociateCidrBlock(cidrBlock.getUuid(), vendor.getUuid(), subnet.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    subnet.setIpv6Cidr(null);
                    subnetRepository.update(subnet);
                    cidrBlockRepository.remove(cidrId, context.getTarget());
                    break;
                case HUAWEI:
                    break;
                case ALIYUN:
                    List<CidrBlock> cidrBlockList =
                        cidrBlockRepository.listByVid(vendor.getId(), subnet.getRegionId(), subnet.getSubnetUuid());
                    for (CidrBlock cidr : cidrBlockList) {
                        if ("IPV6".equalsIgnoreCase(cidr.getType())) {
                            cidrBlock = cidr;
                        }
                    }
                    Assert.notNull(subnet, "CidrBlock不存在");
                    bocloudResult = subnetDriver.disassociateCidrBlock(subnet.getSubnetUuid(), vendor.getUuid(),
                        subnet.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    subnet.setIpv6Cidr(null);
                    subnetRepository.update(subnet);
                    cidrBlockRepository.remove(cidrBlock.getId(), context.getTarget());
                    break;
                default:
                    break;
            }
            return new BocloudResult(true, "SUBNET CIDR 移除成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult updateRouteTable(Long id, Long routeTableId, RequestContext context) {
        try {
            Subnet subnet = subnetRepository.query(id);
            Assert.notNull(subnet, "Subnet不存在");
            CloudVendor vendor = cloudVendorRepository.query(subnet.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            RouteTable routeTable = routeTableRepository.query(routeTableId);
            Assert.notNull(routeTable, "路由表不存在！");

            BocloudResult result = routeTableDriver.associateSubnet(vendor.getUuid(), subnet.getRegionId(),
                routeTable.getUuid(), Collections.singletonList(subnet.getSubnetUuid()));
            if (result.isFailed()) {
                return new BocloudResult(false, "子网更换路由表失败" + result.getMessage());
            }
            subnet.setRouterTableId(routeTableId);
            subnetRepository.update(subnet);
            return new BocloudResult(true, "子网更换路由表成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult(false, e.getMessage());
        }
    }
}
