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.network.*;
import com.bocloud.cmp.driver.secuirty.VpcDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.*;
import com.bocloud.cmp.model.common.*;
import com.bocloud.cmp.provider.utils.IPAddress;
import com.bocloud.cmp.provider.utils.IPv4Address;
import com.bocloud.common.model.*;
import com.bocloud.common.model.RequestContext.Catalog;
import com.bocloud.common.utils.*;
import com.bocloud.ims.entity.common.Project;
import com.bocloud.ims.entity.common.Tenant;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.azure.ddos.DdosProtectionPlan;
import com.bocloud.ims.entity.resource.manageone.ManageOneAccount;
import com.bocloud.ims.interfaces.manageone.ManageOneAccountService;
import com.bocloud.ims.interfaces.resource.*;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.repository.resource.azure.ddos.DdosProtectionPlanRepository;
import com.bocloud.ims.service.internal.SmsProjectService;
import com.bocloud.ims.service.internal.SmsTenantService;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.nms.enums.OrderItemStatus;
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.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

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

/**
 * vpc service实现
 *
 * @author wangyu
 * @version 1.0
 * @since 2018年2月2日
 */
@Service("vpcService")
public class VpcServiceImpl implements VpcService {

    private static Logger logger = LoggerFactory.getLogger(VpcServiceImpl.class);
    @Autowired
    private VpcRepository vpcRepository;
    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private RegionRepository regionRepository;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private VpcDriver vpcDriver;
    @Autowired
    private NetworkService networkService;
    @Autowired
    private NetworkDriver networkDriver;
    @Autowired
    private SubnetService subnetService;
    @Autowired
    private TenantNetworkRepository tenantNetworkRepository;
    @Autowired
    private VendorProjectService vendorProjectService;
    @Autowired
    private NetworkRepository networkRepository;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;
    @Autowired
    private SecurityGroupRepository securityGroupRepository;
    @Autowired
    private SubnetRepository subnetRepository;
    @Autowired
    private SmsProjectService smsProjectService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private RouterService routerService;
    @Autowired
    private SubnetDriver subnetDriver;
    @Autowired
    private RouterSubnetRepository routerSubnetRepository;
    @Autowired
    private RouterRepository routerRepository;
    @Autowired
    private RouterDriver routerDriver;
    @Autowired
    private ManageOneAccountService accountService;
    @Autowired
    private ZoneRepository zoneRepository;
    @Autowired
    private SecurityGroupService securityGroupService;
    @Autowired
    private SecurityGroupRuleRepository securityGroupRuleRepository;
    @Autowired
    private SecurityGroupDriver securityGroupDriver;
    @Autowired
    private CidrBlockRepository cidrBlockRepository;
    @Autowired
    private LoadBalancerRepository loadBalancerRepository;
    @Autowired
    private InternetGatewayRepository gatewayRepository;
    @Autowired
    private RouteTableDriver routeTableDriver;
    @Autowired
    private RouteTableRepository routeTableRepository;
    @Autowired
    private RouteTableAssociationRepository routeTableAssociationRepository;
    @Autowired
    private RouteRepository routeRepository;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private ResourceGroupRepository resourceGroupRepository;
    @Autowired
    private DdosProtectionPlanRepository planRepository;
    @Autowired
    private SmsTenantService smsTenantService;
    @Autowired
    private InternetGatewayService internetGatewayService;
    @Autowired
    private InternetGatewayRepository internetGatewayRepository;
    @Autowired
    private InternetGatewayDriver internetGatewayDriver;
    @Autowired
    private LabelService labelService;
    @Autowired
    private OSTenantRepository osTenantRepository;

    @Override
    public BocloudResult<GridBean<Vpc>> list(Pager pager, RequestContext context) {
        List<Vpc> list = Lists.newArrayList();
        int total = 0;
        GridBean gridBean = null;
        try {
            List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
            Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
            Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
            sorter.put("gmtCreate", Common.ONE);
            Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
            Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);

            Boolean hasEip = false;
            Boolean hasIpv6 = false;
            Boolean notGateWay = false;
            String vendorType = null;
            String labelContent = null;
            for (Param param : params) {
                Map<String, Object> paramMap = param.getParam();
                if (paramMap.containsKey("vendorType")) {
                    vendorType = String.valueOf(paramMap.get("vendorType"));
                    paramMap.remove("vendorType");
                }
                if (paramMap.containsKey("hasEip")) {
                    hasEip = Boolean.valueOf(paramMap.get("hasEip").toString());
                    simple = false;
                    paramMap.remove("hasEip");
                }
                if (paramMap.containsKey("hasIpv6")) {
                    hasIpv6 = Boolean.valueOf(paramMap.get("hasIpv6").toString());
                    simple = false;
                    paramMap.remove("hasIpv6");
                }
                if (paramMap.containsKey("notGateWay")) {
                    notGateWay = Boolean.valueOf(paramMap.get("notGateWay").toString());
                    simple = false;
                    paramMap.remove("notGateWay");
                }
                if (paramMap.containsKey("labelContent")) {
                    labelContent = paramMap.get("labelContent").toString();
                    paramMap.remove("labelContent");
                }
            }
            // vpc列表特殊处理 只查询租户下的vpc
            if (context.getCatalog().equals(Catalog.Tenant) || context.getCatalog().equals(Catalog.User)) {
                params.add(new Param(MapTools.simpleMap("tenant_id", context.getTenant()), Sign.EQ));
                total = this.vpcRepository.count(params, vendorType, labelContent);
                list = this.vpcRepository.list(page, rows, params, sorter, vendorType, labelContent);
                gridBean = new GridBean<>(page, rows, total, list);
            } else {
                total = vpcRepository.countByLabel(params, labelContent);
                if (simple) {
                    List<SimpleBean> beans = vpcRepository.list(params, sorter, labelContent);
                    gridBean = new GridBean(1, 1, total, beans);
                } else {
                    list = vpcRepository.list(page, rows, params, sorter, hasEip, hasIpv6, notGateWay, labelContent);
                    gridBean = GridHelper.getBean(page, rows, total, list);
                }
                for (Vpc vpc : list) {
                    if (null != vpc.getResourceGroupId()) {
                        ResourceGroup resourceGroup = resourceGroupRepository.query(vpc.getResourceGroupId());
                        if (null != resourceGroup) {
                            vpc.setResourceGroupName(resourceGroup.getName());
                        }
                    }
                }
            }

            List<Long> tenantIds = new ArrayList<>();
            List<Long> projectIds = new ArrayList<>();
            for (Vpc vpc : list) {
                if (vpc.getTenantId() != null) {
                    tenantIds.add(vpc.getTenantId());
                }
                if (vpc.getProjectId() != null) {
                    projectIds.add(vpc.getProjectId());
                }
            }
            Map<Long, String> projectMap = smsProjectService.listProjectsByIds(projectIds).stream()
                    .collect(Collectors.toMap(Project::getId, Project::getName));
            Map<Long, String> tenantMap = smsTenantService.listTenantsByIds(tenantIds).stream()
                    .collect(Collectors.toMap(Tenant::getId, Tenant::getName));
            for (Vpc vpc : list) {
                if (vpc.getTenantId() != null) {
                    vpc.setTenantName(tenantMap.get(vpc.getTenantId()));
                }
                if (vpc.getProjectId() != null) {
                    vpc.setProjectName(projectMap.get(vpc.getProjectId()));
                }
            }
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list vpc failure:", e);
            return new BocloudResult<>(false, "查询失败", null, null);
        }
    }

    @Override
    public BocloudResult<String> create(Vpc vpc, RequestContext context) {
        try {
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "云平台不存在!");
            // azure vpc创建要进行名称重复性校验
            if (CloudProvider.AZURE.name().equals(vendor.getType())) {
                Vpc vpcByName = vpcRepository.getByName(vpc.getVendorId(), vpc.getName());
                if (null != vpcByName) {
                    return new BocloudResult<String>(false, "虚拟网络名称已存在");
                }
            }
            String resourceLabel = vpc.getResourceLabel();
            VpcModel model = new VpcModel();
            Region region = regionRepository.getByRegionId(vpc.getRegionId(), vendor.getId());
            String regionId = null;
            // 添加azure判断 start (azure没有region，直接跳过)
            if (!CloudProvider.AZURE.name().equals(vendor.getType())) {
                if (null == region) {
                    logger.error("Region does not exists");
                    return new BocloudResult<String>(false, "区域不存在");
                }
                regionId = region.getRegionId();
            } else if (CloudProvider.AZURE.name().equals(vendor.getType())) {
                regionId = vpc.getRegionId();
            }
            // 京东云 vpc按区域进行名称重复校验
            if (CloudProvider.JDCLOUD.name().equals(vendor.getType())) {
                Vpc byName = vpcRepository.getByName(vpc.getVendorId(), vpc.getName(), region.getRegionId());
                if (null != byName) {
                    return new BocloudResult<String>(false, "该云网络名称已存在");
                }
            }
            // 资源组校验
            if (CloudProvider.AZURE.name().equals(vendor.getType())) {
                ResourceGroup resourceGroup = resourceGroupRepository.query(vpc.getResourceGroupId());
                if (null == resourceGroup) {
                    return new BocloudResult<>(false, "资源组不存在");
                }
                vpc.setResourceGroupName(resourceGroup.getName());
                model.setResourceGroupName(resourceGroup.getName());
            }
            // 火山云 vpc按区域校验个数，最多可以创建10个
            if (CloudProvider.VOLCENGINE.name().equals(vendor.getType())) {
                List<Vpc> list = vpcRepository.list(vpc.getVendorId(), region.getRegionId());
                if (list.size() >= 10) {
                    return new BocloudResult<String>(false, "该云网络创建个数已达上限，最多可创建10个");
                }
            }
            final String finalRegionId = regionId;
            // 添加azure判断 end
            new Thread(() -> {
                BocloudResult result = null;
                String operate = vendor.getType().toLowerCase() + ".vpc";
                String content = "申请创建VPC失败";
                model.setRegionId(finalRegionId);
                try {
                    BeanUtils.copyProperties(vpc, model);
                    result = vpcDriver.create(model, vendor.getUuid(), vpc.getRegionId());
                    if (result.isSuccess()) {
                        VpcModel vpcModel =
                                JSONObject.parseObject(JSONObject.toJSONString(result.getData()), VpcModel.class);
                        BeanUtils.copyProperties(vpcModel, vpc);
                        vpc.setVendorId(vendor.getId());
                        vpc.setRegionId(finalRegionId);
                        vpc.setMenderId(context.getTarget());
                        vpc.setCreatorId(context.getTarget());
                        vpc.setTenantId(context.getTenant());
                        vpc.setProjectId(context.getProject());
                        vpc.setResourceLabel(resourceLabel);
                        vpcRepository.save(vpc);
                        content = "VPC创建成功";
                        BocloudResult bocloudResult = null;
                        switch (CloudProvider.valueOf(vendor.getType())) {
                            // 阿里云同步路由表
                            case ALIYUN:
                                for (CidrBlockModel cidrBlockModel : vpcModel.getCidrBlockModels()) {
                                    CidrBlock cidrBlock = new CidrBlock();
                                    BeanUtils.copyProperties(cidrBlockModel, cidrBlock);
                                    cidrBlock.setCreatorId(context.getTarget());
                                    cidrBlock.setGmtCreate(new Date());
                                    cidrBlock.setVendorId(vendor.getId());
                                    cidrBlock.setRegionId(finalRegionId);
                                    cidrBlockRepository.save(cidrBlock);
                                }
                                bocloudResult =
                                        routeTableDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(), finalRegionId);
                                if (bocloudResult.isFailed()) {
                                    content += "；路由表获取失败：" + bocloudResult.getMessage();
                                } else {
                                    List<RouteTableModel> routeTableModels = JSONObject.parseArray(
                                            JSONObject.toJSONString(bocloudResult.getData()), RouteTableModel.class);
                                    for (RouteTableModel routeTableModel : routeTableModels) {
                                        RouteTable routeTable = new RouteTable();
                                        BeanUtils.copyProperties(routeTableModel, routeTable);
                                        routeTable.setCreatorId(context.getTarget());
                                        routeTable.setVpcUuid(vpc.getVpcId());
                                        routeTable.setVpcId(vpc.getId());
                                        routeTable.setVendorId(vendor.getId());
                                        routeTable.setRegionId(finalRegionId);
                                        routeTableRepository.save(routeTable);
                                        List<RouteModel> routeModels = routeTableModel.getRouteModels();
                                        for (RouteModel routeModel : routeModels) {
                                            Route route = new Route();
                                            BeanUtils.copyProperties(routeModel, route);
                                            route.setRouteTableId(routeTable.getId());
                                            route.setCreatorId(context.getTarget());
                                            route.setVendorId(vendor.getId());
                                            route.setRegionId(finalRegionId);
                                            routeRepository.save(route);
                                        }
                                    }
                                }
                                break;
                            // AWS同步默认安全组
                            case AWS:
                                bocloudResult =
                                        securityGroupDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(), finalRegionId);
                                if (bocloudResult.isFailed()) {
                                    content += "；安全组获取失败：" + bocloudResult.getMessage();
                                } else {
                                    SecurityGroup group = new SecurityGroup();
                                    SecurityGroupModel groupModel = JSONObject.parseObject(
                                            JSONObject.toJSONString(bocloudResult.getData()), SecurityGroupModel.class);
                                    BeanUtils.copyProperties(groupModel, group);
                                    group.preSave(context.getTarget(), context.getTarget(), vendor.getId(),
                                            context.getTenant(), context.getProject());
                                    group.setTenantId(context.getTenant());
                                    group.setVpcUuid(vpc.getVpcId());
                                    group.setVpcId(vpc.getId());
                                    securityGroupRepository.save(group);
                                }
                                // AWS同步cidr
                                for (CidrBlockModel cidrBlockModel : vpcModel.getCidrBlockModels()) {
                                    CidrBlock cidrBlock = new CidrBlock();
                                    BeanUtils.copyProperties(cidrBlockModel, cidrBlock);
                                    cidrBlock.setCreatorId(context.getTarget());
                                    cidrBlock.setVendorId(vendor.getId());
                                    cidrBlock.setRegionId(vpc.getRegionId());
                                    cidrBlockRepository.save(cidrBlock);
                                }
                                // AWS同步路由表
                                bocloudResult =
                                        routeTableDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(), finalRegionId);
                                if (bocloudResult.isFailed()) {
                                    content += "；路由表获取失败：" + bocloudResult.getMessage();
                                } else {
                                    RouteTable routeTable = new RouteTable();
                                    RouteTableModel routeTableModel = JSONObject.parseObject(
                                            JSONObject.toJSONString(bocloudResult.getData()), RouteTableModel.class);
                                    BeanUtils.copyProperties(routeTableModel, routeTable);
                                    routeTable.setVpcId(vpc.getId());
                                    routeTable.setPropagatingVgws(JSONObject.toJSONString(routeTableModel.getPropagatingVgws()));
                                    routeTable.setCreatorId(context.getTarget());
                                    routeTable.setGmtCreate(new Date());
                                    routeTable.setVendorId(vendor.getId());
                                    routeTable.setRegionId(vpc.getRegionId());
                                    routeTableRepository.save(routeTable);
                                    // 同步路由关系
                                    List<RouteTableAssociationModel> associationModels = routeTableModel.getAssociations();
                                    for (RouteTableAssociationModel associationModel :
                                            associationModels) {
                                        RouteTableAssociation association = new RouteTableAssociation();
                                        BeanUtils.copyProperties(associationModel, association);
                                        association.setRouteTableId(routeTable.getId());
                                        association.setCreatorId(context.getTarget());
                                        association.setGmtCreate(new Date());
                                        association.setVendorId(vendor.getId());
                                        association.setRegionId(vpc.getRegionId());
                                        routeTableAssociationRepository.save(association);
                                    }
                                    // 同步路由
                                    List<RouteModel> routeModels = routeTableModel.getRouteModels();
                                    for (RouteModel routeModel :
                                            routeModels) {
                                        Route route = new Route();
                                        BeanUtils.copyProperties(routeModel, route);
                                        route.setRouteTableId(routeTable.getId());
                                        route.setRouteTableUuid(routeTable.getUuid());
                                        route.setCreatorId(context.getTarget());
                                        route.setGmtCreate(new Date());
                                        route.setVendorId(vendor.getId());
                                        route.setRegionId(vpc.getRegionId());
                                        routeRepository.save(route);
                                    }
                                }
                                break;
                            // 添加azure判断 插入子网
                            case AZURE:
                                List<SubnetModel> subnetModels = vpc.getSubnetModels();
                                for (SubnetModel subnetModel : subnetModels) {
                                    Subnet subnet = new Subnet();
                                    BeanUtils.copyProperties(subnetModel, subnet);
                                    subnet.setCreatorId(context.getTarget());
                                    subnet.setMenderId(context.getTarget());
                                    subnet.setVendorId(vendor.getId());
                                    subnet.setVpcId(vpc.getId());
                                    subnet.setVpcUuid(vpc.getVpcId());
                                    subnet.setNetworkId(vpc.getId());
                                    subnet.setNetworkUuid(vpc.getVpcId());
                                    subnet.setRegionId(vpc.getRegionId());
                                    subnetRepository.save(subnet);
                                }
                                break;
                            case JDCLOUD:
                            case VOLCENGINE:
                                bocloudResult =
                                        routeTableDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(), finalRegionId);
                                if (bocloudResult.isFailed()) {
                                    content += "；路由表获取失败：" + bocloudResult.getMessage();
                                } else {
                                    List<RouteTableModel> routeTableModels = JSONObject.parseArray(
                                            JSONObject.toJSONString(bocloudResult.getData()), RouteTableModel.class);
                                    for (RouteTableModel routeTableModel : routeTableModels) {
                                        RouteTable routeTable = new RouteTable();
                                        BeanUtils.copyProperties(routeTableModel, routeTable);
                                        routeTable.setCreatorId(context.getTarget());
                                        routeTable.setVpcId(vpc.getId());
                                        routeTable.setVendorId(vendor.getId());
                                        routeTable.setRegionId(finalRegionId);
                                        routeTableRepository.save(routeTable);
                                    }
                                }
                                bocloudResult =
                                        securityGroupDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(), finalRegionId);
                                if (bocloudResult.isFailed()) {
                                    content += "；安全组获取失败：" + bocloudResult.getMessage();
                                } else {
                                    SecurityGroup group = new SecurityGroup();
                                    List<SecurityGroupModel> groupModels = JSONObject.parseArray(
                                            JSONObject.toJSONString(bocloudResult.getData()), SecurityGroupModel.class);
                                    for (SecurityGroupModel groupModel : groupModels
                                    ) {
                                        BeanUtils.copyProperties(groupModel, group);
                                        group.preSave(context.getTarget(), context.getTarget(), vendor.getId(),
                                                context.getTenant(), context.getProject());
                                        group.setTenantId(context.getTenant());
                                        group.setVpcUuid(vpc.getVpcId());
                                        group.setVpcId(vpc.getId());
                                        securityGroupRepository.save(group);
                                    }
                                }
                                break;
                            default:
                                break;
                        }
                        // 发送给云平台统计队列对云平台重新统计
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put(Common.VENDORID, vendor.getId());
                        amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
                    } else {
                        content = result.getMessage();
                    }
                } catch (Exception 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<String>(true, "申请创建VPC任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult<String>(false, "创建失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<String> modify(Vpc vpc, RequestContext context) {
        String path = Vpc.class.getSimpleName() + "_" + vpc.getId();
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Vpc oldVpc = vpcRepository.query(vpc.getId());
            Assert.notNull(oldVpc, "VPC不存在!");
            CloudVendor cloudVendor = cloudVendorRepository.query(oldVpc.getVendorId());
            Assert.notNull(cloudVendor, "云平台不存在!");
            if (null != context.getTenant() && 0L != context.getTenant()) {
                CloudProvider provider = CloudProvider.valueOf(cloudVendor.getType());
                BocloudResult result = null;
                switch (provider) {
                    case OPENSTACK:
                    case EASYSTACK:
                        Network network = networkRepository.query(oldVpc.getNetworkId());
                        Assert.notNull(network, "网络不存在!");
                        NetworkModel networkModel = new NetworkModel();
                        networkModel.setNetworkUuid(network.getNetworkUuid());
                        networkModel.setName(vpc.getName());
                        networkModel.setAdminStateup(true);
                        networkModel.setShared(false);
                        result = networkDriver.modify(cloudVendor.getUuid(), null, networkModel);
                        Assert.isTrue(result.isSuccess(), result.getMessage());
                        network.setName(vpc.getName());
                        network.setMenderId(context.getTarget());
                        networkRepository.update(network);
                        break;
                    case TCE:
                    case TENCENT:
                    case ALIYUN:
                    case HUAWEI:
                    case HCSO:
                    case AWS:
                        VpcModel model = new VpcModel();
                        model.setVpcId(oldVpc.getVpcId());
                        model.setName(vpc.getName());
                        if (!StringUtils.isEmpty(vpc.getRemark())) {
                            model.setRemark(vpc.getRemark());
                        }
                        BocloudResult bocloudResult =
                                vpcDriver.update(model, cloudVendor.getUuid(), oldVpc.getRegionId());
                        if (bocloudResult.isFailed()) {
                            return bocloudResult;
                        }
                        break;
                    case MANAGEONE:
                        Router router = routerRepository.query(oldVpc.getRouterId());
                        Assert.notNull(router, "路由器不存在!");
                        RouterModel routerModel = new RouterModel();
                        routerModel.setRouterUuid(router.getRouterUuid());
                        routerModel.setName(vpc.getName());
                        result = routerDriver.modify(routerModel, cloudVendor.getUuid(), null);
                        Assert.isTrue(result.isSuccess(), result.getMessage());
                        router.setName(vpc.getName());
                        router.setMenderId(context.getTarget());
                        routerRepository.update(router);
                        break;
                    default:
                        return new BocloudResult<>(false, "暂不支持");
                }
                oldVpc.setName(vpc.getName());
                if (!StringUtils.isEmpty(vpc.getRemark())) {
                    oldVpc.setRemark(vpc.getRemark());
                }
                vpcRepository.update(oldVpc);
                return new BocloudResult<>(true, "编辑成功");
            }

            VpcModel model = new VpcModel();
            BeanUtils.copyProperties(vpc, model);
            model.setVpcId(oldVpc.getVpcId());
            taskExecutor.execute(() -> {
                String operate = cloudVendor.getType().toLowerCase() + ".vpc";
                String message = "VPC编辑失败";
                try {
                    BocloudResult bocloudResult = vpcDriver.update(model, cloudVendor.getUuid(), vpc.getRegionId());
                    if (bocloudResult.isFailed()) {
                        resourceEventPublisher.send(new OperateResult(false, bocloudResult.getMessage(), operate,
                                MapTools.simpleMap("vendorId", cloudVendor.getId()),
                                OperateResult.OperateCategory.ResourceEvent, context));
                        return;
                    }
                    VpcModel vpcModel =
                            JSONObject.parseObject(JSONObject.toJSONString(bocloudResult.getData()), VpcModel.class);
                    BeanUtils.copyProperties(vpcModel, oldVpc);
                    vpcRepository.update(oldVpc);
                    resourceEventPublisher.send(new OperateResult(bocloudResult.isSuccess(), "VPC编辑成功", operate,
                            MapTools.simpleMap("vendorId", cloudVendor.getId()),
                            OperateResult.OperateCategory.ResourceEvent, context));
                } catch (Exception e) {
                    logger.error("VPC modify fail:", e);
                    resourceEventPublisher.send(
                            new OperateResult(false, message, operate, MapTools.simpleMap("vendorId", cloudVendor.getId()),
                                    OperateResult.OperateCategory.ResourceEvent, context));
                }
            });
            return new BocloudResult(true, "编辑任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("Modify vpc fail:", e);
            return new BocloudResult<String>(false, "修改失败", null, null);
        }
    }

    @Override
    public BocloudResult<String> remove(Long id, RequestContext context) {
        String path = Vpc.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Vpc vpc = vpcRepository.query(id);
            Assert.notNull(vpc, "vpc专用网络不存在!");
            CloudVendor cloudVendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(cloudVendor, "平台验证失败");
            if (CloudProvider.ALIYUN.name().equals(cloudVendor.getType())
                    || CloudProvider.AWS.name().equals(cloudVendor.getType())
                    || CloudProvider.HUAWEI.name().equals(cloudVendor.getType())
                    || CloudProvider.HCSO.name().equals(cloudVendor.getType())
                    || CloudProvider.AZURE.name().equals(cloudVendor.getType())
                    || CloudProvider.JDCLOUD.name().equals(cloudVendor.getType())
                    || CloudProvider.VOLCENGINE.name().equals(cloudVendor.getType())) {
                // 如果VPC下有子网，则不让删除
                List<Subnet> subnetList = subnetRepository.listByVpcId(cloudVendor.getId(), vpc.getVpcId());
                if (null != subnetList && subnetList.size() > 0) {
                    return new BocloudResult<String>(false, "当前VPC下存在子网，请先删除子网！");
                }
            }
            if (CloudProvider.HUAWEI.name().equals(cloudVendor.getType())) {
                // 华为云 删除最后一个虚拟私有云时，请先删除安全组。
                List<SecurityGroup> groups = securityGroupRepository.listByVpcId(vpc.getId(), null);
                Iterator<SecurityGroup> iterator = groups.iterator();
                while (iterator.hasNext()) {
                    if ("Sys-default".equals(iterator.next().getName())) {
                        iterator.remove();
                    }
                }
                if (!ListTool.isEmpty(groups)) {
                    return new BocloudResult<String>(false, "删除最后一个VPC时，请先删除安全组。");
                }
            }
            if (CloudProvider.ALIYUN.name().equals(cloudVendor.getType())) {
                List<SecurityGroup> groups = securityGroupRepository.listByVpcId(vpc.getId(), null);
                if (!ListTool.isEmpty(groups)) {
                    return new BocloudResult<String>(false, "当前VPC下存在安全组，请先删除安全组");
                }
                List<LoadBalancer> lbs = loadBalancerRepository.getByVpc(vpc.getId(), cloudVendor.getId());
                if (!ListTool.isEmpty(lbs)) {
                    return new BocloudResult<String>(false, "当前VPC下存在SLB实例，请先删除SLB实例");
                }
                List<InternetGateway> gateways = gatewayRepository.getByVpc(vpc.getVpcId(), cloudVendor.getId());
                if (!ListTool.isEmpty(gateways)) {
                    return new BocloudResult<String>(false, "当前VPC下存在NAT网关，请先删除NAT网关");
                }
            }
            if (CloudProvider.QCLOUD.name().equals(cloudVendor.getType())
                    || CloudProvider.PQCLOUD.name().equals(cloudVendor.getType())) {
                // 如果VPC下有子网，则不让删除
                List<Subnet> subnetList = subnetRepository.listByVpcId(cloudVendor.getId(), vpc.getVpcId());
                if (null != subnetList && subnetList.size() > 0) {
                    return new BocloudResult<String>(false, "当前VPC下存在子网，请先删除子网！");
                }
            }
            BocloudResult result = vpcDriver.remove(vpc.getVpcId(), cloudVendor.getUuid(), vpc.getRegionId());
            if (result.isFailed()) {
                return result;
            }
            vpcRepository.delete(id, context.getTarget());
            //删除对应的路由表
            routeTableRepository.deleteByVpcUuid(id,context.getTarget());
            // 京东云删除vpc会删除该vpc下的安全组和路由表
            if (CloudProvider.JDCLOUD.name().equals(cloudVendor.getType()) ||
                    CloudProvider.AWS.name().equals(cloudVendor.getType())
                    || CloudProvider.VOLCENGINE.name().equals(cloudVendor.getType())) {
                securityGroupRepository.removeByVpcId(vpc.getId(), context.getTarget());
                routeTableRepository.removeByVpcId(vpc.getId(), context.getTarget());
            }
            cidrBlockRepository.removeByVid(cloudVendor.getId(), vpc.getRegionId(), context.getTarget(),
                    vpc.getVpcId());
            // 添加azure 判断 start ，删除vpc会同时删除其下的子网
            if (CloudProvider.AZURE.name().equals(cloudVendor.getType())) {
                List<Subnet> subnetList = subnetRepository.listByVpcId(cloudVendor.getId(), vpc.getVpcId());
                for (Subnet subnet : subnetList) {
                    subnetRepository.remove(subnet.getId(), context.getTarget());
                }
            }
            // 添加azure 判断 start
            // 发送给云平台统计队列对云平台重新统计
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(Common.VENDORID, cloudVendor.getId());
            amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
            return new BocloudResult<String>(true, "删除vpc成功");
        } catch (Exception e) {
            logger.error("remove vpc fail:", e);
            return new BocloudResult<String>(false, "删除vpc失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Vpc> detail(Long id) {
        try {
            Vpc vpc = vpcRepository.query(id);
            Assert.notNull(vpc, "vpc专用网络不存在!");
            CloudVendor cloudVendor = cloudVendorRepository.query(vpc.getVendorId());
            if (null != cloudVendor) {
                vpc.setVendorName(cloudVendor.getName());
                vpc.setVendorType(cloudVendor.getType());
            }
            // vpc标签
            List<JSONObject> parseArray = JSON.parseArray(vpc.getResourceLabel(), JSONObject.class);
            if (!ListTool.isEmpty(parseArray)) {
                BocloudResult existsValues = labelService.isExistsValues(parseArray);
                if (existsValues.isFailed()) {
                    return existsValues;
                }
                vpc.setResourceLabel(JSONObject.toJSONString(existsValues.getData()));
                vpcRepository.update(vpc);
            }
            if (null != vpc.getResourceGroupId()) {
                Optional.ofNullable(resourceGroupRepository.query(vpc.getResourceGroupId())).map(ResourceGroup::getName).ifPresent(vpc::setResourceGroupName);
            }
            return new BocloudResult<Vpc>(true, vpc, "查询成功");
        } catch (Exception e) {
            logger.error("Get error message：", e);
            return new BocloudResult<Vpc>(false, "查询失败: " + e.getMessage());
        }
    }

    @Override
    public BocloudResult<List<Vpc>> listByZone(String params, RequestContext context) {
        try {
            JSONObject object = JSONTools.isJSONObj(params);
            Long vendorId = object.getLong("vendorId");
            String region = object.getString("regionId");
            String zone = object.getString("zoneId");
            if (null == region || null == zone) {
                return new BocloudResult<List<Vpc>>(false, "参数格式错误");
            }
            List<Vpc> vpcs = vpcRepository.list(vendorId, region, null);
            if (null != vpcs && vpcs.size() > 0) {
                Map<String, String> sorter = Maps.newHashMap();
                sorter.put("gmtCreate", Common.ONE);
                List<Param> switchParams = Lists.newArrayList();
                for (Vpc vpc : vpcs) {
                    // 查询vpc下的安全组
                    List<SecurityGroup> securityGroups = securityGroupRepository.listByVpcId(vpc.getId(), null);
                    vpc.setSecurityGroups(securityGroups);
                    // 查询vpc下的交换机
                    if (null != zone && !"".equals(zone)) {
                        switchParams.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
                        switchParams.add(new Param(MapTools.simpleMap("zone", zone), Sign.EQ));
                        switchParams.add(new Param(MapTools.simpleMap("vpcUuid", vpc.getVpcId()), Sign.EQ));
                        vpc.setSubnets(subnetRepository.list(1, Integer.MAX_VALUE, switchParams, sorter));
                    }
                    switchParams.clear();
                }
            }
            return new BocloudResult<List<Vpc>>(true, vpcs, "查询成功");
        } catch (Exception e) {
            logger.error("Get error message：", e);
            return new BocloudResult<List<Vpc>>(false, "查询失败");
        }
    }

    @Override
    public BocloudResult<String> batchRemove(List<Long> idArray, RequestContext context) {
        try {
            // 获取资源ID
            if (ListTool.isEmpty(idArray)) {
                return new BocloudResult<String>(false, "请选择需要删除的VPC！");
            }
            Vpc vpc = vpcRepository.query(idArray.get(0));
            Assert.notNull(vpc, "vpc专用网络不存在!");
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "平台信息异常!");
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String operate = vendor.getType().toLowerCase() + ".vpc";
                    try {
                        List<BocloudResult<String>> succList = Lists.newArrayList();
                        List<BocloudResult<String>> failList = Lists.newArrayList();
                        for (Long id : idArray) {
                            BocloudResult<String> bocloudResult = remove(id, context);
                            if (bocloudResult.isSuccess()) {
                                succList.add(bocloudResult);
                            } else {
                                failList.add(bocloudResult);
                            }
                        }
                        // 删除成功的数量
                        int success = succList.size();
                        // 删除失败的数量
                        int fail = failList.size();
                        String content = null;
                        if (fail == idArray.size()) {
                            content = "VPC批量删除失败，详情如下：\n";
                            for (BocloudResult<String> bocloudResult : failList) {
                                content += bocloudResult.getMessage() + "\n";
                            }
                        } else if (success == idArray.size()) {
                            content = "VPC批量删除成功【" + success + "】个";
                        } else {
                            content = "VPC批量删除成功【" + success + "】个,失败【" + fail + "】个，失败详情如下：\n";
                            for (int i = 0; i < failList.size(); i++) {
                                content += "【" + i + 1 + "】" + failList.get(i).getMessage() + "\n";
                            }
                        }
                        resourceEventPublisher.send(new OperateResult(fail == idArray.size() ? false : true, content,
                                operate, MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                                OperateResult.OperateCategory.ResourceEvent, context));
                    } catch (Exception e) {
                        logger.error("VPC批量删除异常：" + e.getMessage());
                        resourceEventPublisher.send(new OperateResult(false, "VPC批量删除异常：" + e.getMessage(), operate,
                                MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                                OperateResult.OperateCategory.ResourceEvent, context));
                    }
                }
            }).start();
            return new BocloudResult<String>(true, "删除任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("delete error ：", e);
            return new BocloudResult<String>(false, "批量删除失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult apply(ApplicationParam application) {
        List<OrderItem> items = null;
        try {
            RequestContext context = application.getContext();
            ServiceOrder order = application.getOrder();
            Assert.notNull(order, "订单为空！");
            items = order.getItems();
            Assert.notEmpty(items, "子订单为空！");
            // 位置
            LocationModel location = application.getLocation();
            Long vendorId = location.getVendorId();
            CloudVendor vendor = cloudVendorRepository.query(vendorId);
            Assert.notNull(vendor, "云平台不存在！");

            // 订购信息
            EmptionModel emption = application.getEmption();
            // 使用时长信息
            DurationModel duration = emption.getDuration();
            // 使用时长单位Hour/Month
            DurationModel.Mode mode = duration.getMode();
            // 时长
            Integer month = duration.getAmount();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            if (DurationModel.Mode.Hour == mode) {
                calendar.setTime(DateTools.stringToDateTime("2099-12-31 00:00:00"));
            } else {
                calendar.add(Calendar.MONTH, month);
            }

            // 配置信息(创建网络相关的参数在这里)
            JSONObject configs = application.getConfigs();
            String resourceLabel = configs.getString("resourceLabel");
            CloudProvider provider = CloudProvider.valueOf(vendor.getType());
            // 申请个数
            Integer count = null == emption.getCount() ? 1 : emption.getCount();
            for (int i = 0; i < count; i++) {
                OrderItem item = items.get(0);
                // 网关校验
                IPAddress ipAddress = new IPv4Address();
                Vpc vpc = new Vpc();
                vpc.setResourceLabel(resourceLabel);
                vpc.setVendorId(vendorId);
                vpc.setUuid(item.getSn());
                vpc.setRegionId(location.getRegion());
                vpc.setExpiredTime(calendar.getTime());
                vpc.setPoolGroupId(location.getPoolGroupId());
                // 自服务需要用到
                vpc.setCreatorId(location.getCreatorId() == null ? 0 : location.getCreatorId());
                vpc.setOwnerId(location.getOwnerId() == null ? 0 : location.getOwnerId());
                vpc.setMenderId(location.getMenderId() == null ? 0 : location.getMenderId());
                vpc.setCatalog(context.getCatalog());
                vpc.setTenantId(context.getTenant() == null ? 0 : context.getTenant());
                vpc.setBusinessId(location.getBusinessId() == null ? 0 : location.getBusinessId());
                vpc.setProjectId(location.getProjectId() == null ? 0 : location.getProjectId());
                vpc.setPoolGroupId(location.getPoolGroupId());

                String name = configs.getString("name") + "_" + IDFactory.instance().uuid();
                JSONObject data = null;
                switch (provider) {
                    case OPENSTACK:
                    case EASYSTACK:
                        NetworkModel networkModel = new NetworkModel();
                        networkModel.setName(name);
                        networkModel.setPhyNetwork(null);
                        networkModel.setSegmentationId(null);
                        networkModel.setIsTenant(true);
                        networkModel.setAdminStateup(true);
                        networkModel.setShared(false);
                        networkModel.setIsRouterExternal(false);
                        OSTenant osTenant = osTenantRepository.getByTenantId(context.getTenant(), vendor.getId());
                        Assert.notNull(osTenant, "租户云平台认证信息不存在");
                        BocloudResult result =
                                networkDriver.create(vendor.getUuid(), osTenant.getName(), null, networkModel);
                        Assert.isTrue(result.isSuccess(), result.getMessage());
                        Network network =
                                JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Network.class);
                        network.preSave(context.getTarget(), context.getTarget(), vendorId, null);
                        network.setCreatorId(location.getCreatorId() == null ? 0 : location.getCreatorId());
                        network.setOwnerId(location.getOwnerId() == null ? 0 : location.getOwnerId());
                        network.setMenderId(location.getMenderId() == null ? 0 : location.getMenderId());
                        network.setCatalog(context.getCatalog());
                        network.setTenantId(context.getTenant() == null ? 0 : context.getTenant());
                        network.setBusinessId(location.getBusinessId() == null ? 0 : location.getBusinessId());
                        network.setProjectId(location.getProjectId() == null ? 0 : location.getProjectId());
                        networkRepository.save(network);
                        TenantNetwork tenantNetwork =
                                new TenantNetwork(network.getId(), vendorId, context.getTenant(), context.getProject());
                        tenantNetworkRepository.save(tenantNetwork);
                        vpc.setName(network.getName());
                        vpc.setNetworkId(network.getId());
                        // 创建子网
                        if (!StringUtils.isEmpty(configs.getString("ipAddress"))) {
                            vpc.setCidr(configs.getString("ipAddress") + "/" + configs.getLong("prefixLength"));
                            JSONObject subnetParams = new JSONObject();
                            subnetParams.put("name", "subnet_" + IDFactory.instance().timestamp());
                            subnetParams.put("networkId", network.getId());
                            subnetParams.put("vendorId", network.getVendorId());
                            subnetParams.put("ipVersion", "V4");
                            String opCidr = configs.getString("ipAddress") + "/" + configs.getLong("prefixLength");
                            subnetParams.put("cidr", opCidr);
                            subnetParams.put("dhcpEnabled", true);
                            subnetParams.put("networkUuid", network.getNetworkUuid());
                            // 网关校验
                            String opGateway = ipAddress.getDefaultGeteway(opCidr);
                            subnetParams.put("gateway", opGateway);
                            result = subnetService
                                    .create(JSONObject.parseObject(subnetParams.toJSONString(), Subnet.class), context);
                            if (result.isFailed()) {
                                networkService.remove(network.getId(), context);
                                return new BocloudResult<>(false, items, "VPC申请失败：" + result.getMessage());
                            } else {
                                vpcRepository.save(vpc);
                                Subnet opSubnet = (Subnet) result.getData();
                                opSubnet.setVpcId(vpc.getId());
                                subnetRepository.update(opSubnet);
                            }
                        } else {
                            vpcRepository.save(vpc);
                        }
                        data = JSONObject.parseObject(JSONObject.toJSONString(network));
                        data.put("vpcId", vpc.getId());
                        break;
                    case FUSIONCLOUD:
                        // 如果与MANAGEONE逻辑一直，则可以去掉break;
                        break;
                    case MANAGEONE:
                        try {
                            Router router = new Router();
                            router.setVendorId(vendorId);
                            router.setName(name);
                            router.setExpiredTime(vpc.getExpiredTime());
                            BocloudResult createRouter = routerService.create(router, context);
                            if (createRouter.isFailed()) {
                                createRouter.setData(items);
                                return createRouter;
                            }
                            router = (Router) createRouter.getData();
                            // 赋值给vpc
                            BeanUtils.copyProperties(router, vpc);
                            vpc.setRouterId(router.getId());
                            vpc.setVpcId(router.getRouterUuid());
                            vpc.setRegionId(location.getRegion());
                            vpc.setCidr(configs.getString("ipAddress") + "/" + configs.getLong("prefixLength"));
                            vpc.setId(null);
                            // 创建子网
                            Long routerId = router.getId();
                            String manageOneCidr =
                                    configs.getString("ipAddress") + "/" + configs.getLong("prefixLength");
                            SubnetModel model = new SubnetModel();
                            String moGateway = ipAddress.getDefaultGeteway(manageOneCidr);
                            model.setGateway(moGateway);
                            model.setCidr(manageOneCidr);
                            model.setRouterUuid(router.getRouterUuid());
                            model.setDhcpEnabled(true);
                            model.setName(configs.getString("subnetName"));
                            result = subnetDriver.create(vendor.getUuid(), vpc.getRegionId(), model);
                            if (result.isSuccess()) {
                                Subnet manageOneSubnet =
                                        JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Subnet.class);
                                // 为了数据完整性 保存网络 and 路由关系表数据
                                Network manageOneNetwork = new Network();
                                manageOneNetwork.setNetworkUuid(manageOneSubnet.getNetworkUuid());
                                manageOneNetwork.setVendorId(vendor.getId());
                                manageOneNetwork.setCreatorId(context.getTarget());
                                manageOneNetwork.setMenderId(context.getTarget());
                                networkRepository.save(manageOneNetwork);
                                vpc.setNetworkId(manageOneNetwork.getId());
                                vpcRepository.save(vpc);
                                manageOneSubnet.setRegionId(model.getRegionId());
                                manageOneSubnet.setZone(model.getZone());
                                manageOneSubnet.preSave(context.getTarget(), context.getTarget(), vendor.getId(), null);
                                manageOneSubnet.setNetworkId(manageOneNetwork.getId());
                                manageOneSubnet.setRouterId(routerId);
                                manageOneSubnet.setVpcUuid(router.getRouterUuid());
                                manageOneSubnet.setVpcId(vpc.getId());
                                subnetRepository.save(manageOneSubnet);
                                // 保存关系表数据
                                RouterSubnet routerSubnet =
                                        new RouterSubnet(router.getId(), manageOneSubnet.getId(), vendor.getId());
                                routerSubnetRepository.save(routerSubnet);
                            } else {
                                routerService.remove(router.getId(), context);
                                return new BocloudResult<>(false, items, "VPC子网创建失败：" + result.getMessage());
                            }
                        } catch (Exception e) {
                            logger.error("子网创建失败：" + e.getMessage());
                            return new BocloudResult<>(false, items, "VPC子网创建失败:" + e.getMessage());
                        }
                        break;
                    case AZURE:
                        try {
                            VpcModel model = new VpcModel();
                            Region region = regionRepository.getByRegionId(location.getRegion(), vendor.getId());
                            if (null == region) {
                                return new BocloudResult<>(false, items, "区域信息异常！");
                            }
                            String azureResourceGroupName = configs.getString("azureResourceGroupName");
                            model.setAzureResourceGroupName(azureResourceGroupName);
                            model.setRegionId(location.getRegion());
                            model.setName(configs.getString("name"));
                            model.setCidr(configs.getString("cidr"));
                            List<SubnetModel> subnets =
                                    JSONArray.parseArray(configs.getString("subnetModels"), SubnetModel.class);
                            model.setSubnetModels(subnets);
                            result = vpcDriver.create(model, vendor.getUuid(), model.getRegionId());
                            if (result.isSuccess()) {
                                VpcModel vpcModel =
                                        JSONObject.parseObject(JSONObject.toJSONString(result.getData()), VpcModel.class);
                                BeanUtils.copyProperties(vpcModel, vpc);
                                vpc.setRegionId(location.getRegion());
                                vpcRepository.save(vpc);
                                List<SubnetModel> subnetModels = vpc.getSubnetModels();
                                for (SubnetModel subnetModel : subnetModels) {
                                    Subnet subnet = new Subnet();
                                    BeanUtils.copyProperties(subnetModel, subnet);
                                    subnet.setVendorId(vendor.getId());
                                    subnet.setCreatorId(context.getTarget());
                                    subnet.setMenderId(context.getTarget());
                                    subnet.setVpcId(vpc.getId());
                                    subnet.setVpcUuid(vpc.getVpcId());
                                    subnet.setNetworkId(vpc.getId());
                                    subnet.setNetworkUuid(vpc.getVpcId());
                                    subnet.setRegionId(vpc.getRegionId());
                                    subnetRepository.save(subnet);
                                }
                                // 发送给云平台统计队列对云平台重新统计
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put(Common.VENDORID, vendor.getId());
                                amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
                            } else {
                                logger.error("azure VPC 创建失败：" + result.getMessage());
                                return new BocloudResult<>(false, items, "azure VPC 创建失败:" + result.getMessage());
                            }
                        } catch (Exception e) {
                            logger.error("azure vpc error message:", e);
                            return new BocloudResult<>(false, items, "azure vpc 创建失败");
                        }
                        break;
                    case AWS:
                        try {
                            VpcModel model = new VpcModel();
                            Region region = regionRepository.getByRegionId(location.getRegion(), vendor.getId());
                            if (null == region) {
                                return new BocloudResult<>(false, items, "区域信息异常！");
                            }
                            String publicCidr = configs.getString("cidr");
                            Boolean providedIpv6Cidr = configs.getBoolean("providedIpv6Cidr");
                            model.setRegionId(location.getRegion());
                            model.setName(name);
                            model.setCidr(publicCidr);
                            model.setProvidedIpv6Cidr(providedIpv6Cidr);
                            logger.info("执行aws vpc 订购.....");
                            result = vpcDriver.create(model, vendor.getUuid(), model.getRegionId());
                            if (result.isSuccess()) {
                                logger.info("aws vpc 创建成功！");
                                VpcModel vpcModel =
                                        JSONObject.parseObject(JSONObject.toJSONString(result.getData()), VpcModel.class);
                                BeanUtils.copyProperties(vpcModel, vpc);
                                vpc.setRegionId(location.getRegion());
                                // 自服务申请
                                vpc.setPoolGroupId(location.getPoolGroupId());
                                vpc.setCreatorId(location.getCreatorId() == null ? 0 : location.getCreatorId());
                                vpc.setOwnerId(location.getOwnerId() == null ? 0 : location.getOwnerId());
                                vpc.setMenderId(location.getMenderId() == null ? 0 : location.getMenderId());
                                vpc.setCatalog(context.getCatalog());
                                vpc.setTenantId(context.getTenant() == null ? 0 : context.getTenant());
                                vpc.setBusinessId(location.getBusinessId() == null ? 0 : location.getBusinessId());
                                vpc.setProjectId(location.getProjectId() == null ? 0 : location.getProjectId());
                                vpcRepository.save(vpc);
                                logger.info("执行aws 互联网网关 创建.....");
                                InternetGateway internetGateway = new InternetGateway();
                                internetGateway.setName("igw-" + vpc.getName());
                                internetGateway.setRegionId(vpc.getRegionId());
                                internetGateway.setVendorId(vpc.getVendorId());
                                result = internetGatewayService.create(internetGateway, context);
                                if (result.isFailed()) {
                                    logger.info("互联网网关创建失败，执行删除vpc");
                                    vpcDriver.remove(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                                    vpcRepository.delete(vpc.getId());
                                    logger.error("互联网网关创建失败失败：" + result.getMessage());
                                    return new BocloudResult<>(false, items, "互联网网关创建失败失败:" + result.getMessage());
                                } else {
                                    logger.info("aws 互联网网关 创建成功！");
                                    internetGateway = (InternetGateway)result.getData();
                                    internetGateway.setTenantId(context.getTenant() == null ? 0 : context.getTenant());
                                    internetGateway.setProjectId(location.getProjectId() == null ? 0 : location.getProjectId());
                                    internetGatewayRepository.update(internetGateway);
                                    logger.info("执行 aws 互联网网关挂载vpc......");
                                    InternetGatewayParam internetGatewayParam = new InternetGatewayParam();
                                    internetGatewayParam.setId(internetGateway.getId());
                                    internetGatewayParam.setVpcId(vpc.getVpcId());
                                    result = internetGatewayService.attach(internetGatewayParam, context);
                                    if (result.isFailed()) {
                                        logger.info("互联网网关挂载失败，执行删除vpc，删除互联网网关！");
                                        vpcDriver.remove(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                                        vpcRepository.delete(vpc.getId());
                                        internetGatewayService.remove(internetGateway.getId(), context);
                                        logger.error("互联网网关创建失败失败：" + result.getMessage());
                                        return new BocloudResult<>(false, items, "互联网网关创建失败失败:" + result.getMessage());
                                    }
                                    logger.info("aws 互联网网关挂载vpc 成功！");
                                }
                                result = securityGroupDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(),
                                        location.getRegion());
                                SecurityGroup group = new SecurityGroup();
                                if (result.isFailed()) {
                                    logger.error("安全组获取失败：" + result.getMessage());
                                    return new BocloudResult<>(false, items, "安全组获取失败:" + result.getMessage());
                                } else {
                                    SecurityGroupModel groupModel = JSONObject.parseObject(
                                            JSONObject.toJSONString(result.getData()), SecurityGroupModel.class);
                                    BeanUtils.copyProperties(groupModel, group);
                                    group.preSave(context.getTarget(), context.getTarget(), vendor.getId(),
                                            context.getTenant(), context.getProject());
                                    group.setTenantId(context.getTenant() == null ? 0 : context.getTenant());
                                    group.setProjectId(location.getProjectId() == null ? 0 : location.getProjectId());
                                    group.setVpcUuid(vpc.getVpcId());
                                    group.setVpcId(vpc.getId());
                                    group.setTenantIds(context.getTenant() == null ? null : context.getTenant().toString());
                                    securityGroupRepository.save(group);
                                }
                                // AWS同步cidr
                                for (CidrBlockModel cidrBlockModel : vpcModel.getCidrBlockModels()) {
                                    CidrBlock cidrBlock = new CidrBlock();
                                    BeanUtils.copyProperties(cidrBlockModel, cidrBlock);
                                    cidrBlock.setCreatorId(context.getTarget());
                                    cidrBlock.setVendorId(vendor.getId());
                                    cidrBlock.setRegionId(vpc.getRegionId());
                                    cidrBlockRepository.save(cidrBlock);
                                }

                                // AWS同步路由表
                                result = routeTableDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(), location.getRegion());
                                if (result.isFailed()) {
                                    logger.error("路由表获取失败：" + result.getMessage());
                                    return new BocloudResult<>(false, items, "路由表获取失败:" + result.getMessage());
                                } else {
                                    RouteTable routeTable = new RouteTable();
                                    RouteTableModel routeTableModel = JSONObject.parseObject(
                                            JSONObject.toJSONString(result.getData()), RouteTableModel.class);
                                    BeanUtils.copyProperties(routeTableModel, routeTable);
                                    routeTable.setVpcId(vpc.getId());
                                    routeTable.setPropagatingVgws(JSONObject.toJSONString(routeTableModel.getPropagatingVgws()));
                                    routeTable.setCreatorId(context.getTarget());
                                    routeTable.setGmtCreate(new Date());
                                    routeTable.setVendorId(vendor.getId());
                                    routeTable.setRegionId(vpc.getRegionId());
                                    routeTableRepository.save(routeTable);
                                    // 同步路由关系
                                    List<RouteTableAssociationModel> associationModels = routeTableModel.getAssociations();
                                    for (RouteTableAssociationModel associationModel :
                                            associationModels) {
                                        RouteTableAssociation association = new RouteTableAssociation();
                                        BeanUtils.copyProperties(associationModel, association);
                                        association.setRouteTableId(routeTable.getId());
                                        association.setCreatorId(context.getTarget());
                                        association.setGmtCreate(new Date());
                                        association.setVendorId(vendor.getId());
                                        association.setRegionId(vpc.getRegionId());
                                        routeTableAssociationRepository.save(association);
                                    }
                                    // 同步路由
                                    List<RouteModel> routeModels = routeTableModel.getRouteModels();
                                    for (RouteModel routeModel :
                                            routeModels) {
                                        Route route = new Route();
                                        BeanUtils.copyProperties(routeModel, route);
                                        route.setRouteTableId(routeTable.getId());
                                        route.setRouteTableUuid(routeTable.getUuid());
                                        route.setCreatorId(context.getTarget());
                                        route.setGmtCreate(new Date());
                                        route.setVendorId(vendor.getId());
                                        route.setRegionId(vpc.getRegionId());
                                        routeRepository.save(route);
                                    }
                                }

                                // 发送给云平台统计队列对云平台重新统计
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put(Common.VENDORID, vendor.getId());
                                amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
                            } else {
                                logger.error("VPC创建失败：" + result.getMessage());
                                return new BocloudResult<>(false, items, "VPC创建失败:" + result.getMessage());
                            }
                        } catch (Exception e) {
                            logger.error("Get error message:", e);
                            return new BocloudResult<>(false, items, "创建失败 : " + e.getMessage());
                        }
                        break;

                    case ALIYUN:
                    case HUAWEI:
                    case HCSO:
                    case TENCENT:
                    case TCE:
                        try {
                            VpcModel model = new VpcModel();
                            Region region = regionRepository.getByRegionId(location.getRegion(), vendor.getId());
                            if (null == region) {
                                return new BocloudResult<>(false, items, "区域信息异常！");
                            }
                            String publicCidr = configs.getString("cidr");
                            model.setRegionId(location.getRegion());
                            model.setName(name);
                            model.setCidr(publicCidr);

                            result = vpcDriver.create(model, vendor.getUuid(), model.getRegionId());
                            if (result.isSuccess()) {
                                VpcModel vpcModel =
                                        JSONObject.parseObject(JSONObject.toJSONString(result.getData()), VpcModel.class);
                                BeanUtils.copyProperties(vpcModel, vpc);
                                vpc.setRegionId(location.getRegion());
                                // 自服务申请
                                vpc.setPoolGroupId(location.getPoolGroupId());
                                vpc.setCreatorId(location.getCreatorId() == null ? 0 : location.getCreatorId());
                                vpc.setOwnerId(location.getOwnerId() == null ? 0 : location.getOwnerId());
                                vpc.setMenderId(location.getMenderId() == null ? 0 : location.getMenderId());
                                vpc.setCatalog(context.getCatalog());
                                vpc.setTenantId(context.getTenant() == null ? 0 : context.getTenant());
                                vpc.setBusinessId(location.getBusinessId() == null ? 0 : location.getBusinessId());
                                vpc.setProjectId(location.getProjectId() == null ? 0 : location.getProjectId());
                                vpcRepository.save(vpc);

                                if("ALIYUN".equals(provider.name())){
                                    logger.info("aliyun vpc sync routeTable start");
                                    for (CidrBlockModel cidrBlockModel : vpcModel.getCidrBlockModels()) {
                                        CidrBlock cidrBlock = new CidrBlock();
                                        BeanUtils.copyProperties(cidrBlockModel, cidrBlock);
                                        cidrBlock.setCreatorId(context.getTarget());
                                        cidrBlock.setGmtCreate(new Date());
                                        cidrBlock.setVendorId(vendor.getId());
                                        cidrBlock.setRegionId(location.getRegion());
                                        cidrBlockRepository.save(cidrBlock);
                                    }
                                    BocloudResult bocloudResult =
                                            routeTableDriver.getByVpc(vpc.getVpcId(), vendor.getUuid(), location.getRegion());
                                    if (bocloudResult.isFailed()) {
                                        logger.error("路由表获取失败：" + bocloudResult.getMessage());
                                        return new BocloudResult<>(false,"路由表获取失败："+bocloudResult.getMessage());
                                    } else {
                                        List<RouteTableModel> routeTableModels = JSONObject.parseArray(
                                                JSONObject.toJSONString(bocloudResult.getData()), RouteTableModel.class);
                                        for (RouteTableModel routeTableModel : routeTableModels) {
                                            RouteTable routeTable = new RouteTable();
                                            BeanUtils.copyProperties(routeTableModel, routeTable);
                                            routeTable.setCreatorId(context.getTarget());
                                            routeTable.setVpcUuid(vpc.getVpcId());
                                            routeTable.setVpcId(vpc.getId());
                                            routeTable.setVendorId(vendor.getId());
                                            routeTable.setRegionId(location.getRegion());
                                            routeTableRepository.save(routeTable);
                                            List<RouteModel> routeModels = routeTableModel.getRouteModels();
                                            for (RouteModel routeModel : routeModels) {
                                                Route route = new Route();
                                                BeanUtils.copyProperties(routeModel, route);
                                                route.setRouteTableId(routeTable.getId());
                                                route.setCreatorId(context.getTarget());
                                                route.setVendorId(vendor.getId());
                                                route.setRegionId(location.getRegion());
                                                routeRepository.save(route);
                                            }
                                        }
                                    }
                                    logger.info("aliyun vpc sync routeTable end");
                                }

                                // 发送给云平台统计队列对云平台重新统计
                                JSONObject jsonObject = new JSONObject();
                                jsonObject.put(Common.VENDORID, vendor.getId());
                                amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
                            } else {
                                logger.error("VPC创建失败：" + result.getMessage());
                                return new BocloudResult<>(false, items, result.getMessage());
                            }
                        } catch (Exception e) {
                            logger.error("Get error message:", e);
                            return new BocloudResult<>(false, items, "创建失败 : " + e.getMessage());
                        }
                        break;
                    default:
                        return new BocloudResult<>(false, items, "暂不支持");
                }
                // 通知订单
                List<ResourceModel> resources = new ArrayList<>();
                resources.add(new ResourceModel(vpc.getName(), vpc.getVpcId(),
                        item.getServiceCode(), vpc.getVpcId(), item.getSn()));
                OrderMessage message = new OrderMessage(item.getSn(), OrderMessage.Operation.Application,
                        OrderItemStatus.OpenedSuccess, null, "vpc申请创建成功", vpc.getGmtCreate(), calendar.getTime(), resources,
                        ResourceCategory.Vpc.name(), context);
                message.setCategory(ResourceCategory.Vpc.name());
                amqpTemplate.convertAndSend("resource.result.queue", message);
                if (!StringUtils.isEmpty(application.getCallback())) {
                    BocloudResult result = new BocloudResult<>(true, data, "云网络创建成功");
                    amqpTemplate.convertAndSend(application.getCallback(), JSONObject.toJSON(result));
                }
                items.remove(item);
            }
            return new BocloudResult<>(true, "VPC申请成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult<>(false, items, e.getMessage());
        }
    }

    @Override
    public BocloudResult extension(ExtensionParam param) {
        try {
            Vpc vpc = vpcRepository.getByUuid(param.getInstance());
            Assert.notNull(vpc, "VPC不存在");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(vpc.getExpiredTime());
            calendar.add(Calendar.MONTH, param.getExtension());
            vpc.setExpiredTime(calendar.getTime());
            vpcRepository.update(vpc);

            OrderMessage message = new OrderMessage();
            message.setSn(param.getInstance());
            message.setOperation(OrderMessage.Operation.Extension);
            message.setStatus(OrderItemStatus.ExtensionSuccess);
            message.setExtension(param.getExtension());
            message.setExpiredTime(calendar.getTime());
            message.setCategory(ResourceCategory.Vpc.name());
            message.setMessage("VPC延期成功");
            amqpTemplate.convertAndSend("resource.result.queue", message);
            return new BocloudResult<>(true, "VPC延期成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult cancelation(CancelationParam param) {
        try {
            Vpc vpc = vpcRepository.getByUuid(param.getInstance());
            Assert.notNull(vpc, "VPC不存在");
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            RequestContext context = param.getContext();
            CloudProvider provider = CloudProvider.valueOf(vendor.getType());
            List<QuotaBean> quotas = new ArrayList<>();
            switch (provider) {
                case OPENSTACK:
                case EASYSTACK:
                    Network network = networkRepository.query(vpc.getNetworkId());
                    Assert.notNull(network, "VPC关联网络不存在");
                    Boolean shared = network.getShared();
                    if (null != shared && !shared) {
                        List<Subnet> subnets = subnetRepository.listByNetwork(network.getId());
                        for (Subnet subnet : subnets) {
                            BocloudResult result = subnetService.remove(subnet.getId(), context);
                            Assert.isTrue(result.isSuccess(), result.getMessage());
                        }
                        // 删除网络
                        BocloudResult result = networkService.remove(network.getId(), context);
                        Assert.isTrue(result.isSuccess(), result.getMessage());
                    }
                    vpcRepository.delete(vpc.getId());
                    break;
                case MANAGEONE:
                    Long routerId = vpc.getRouterId();
                    List<Subnet> manageOneSubnets = subnetRepository.listByRouterId(routerId);
                    for (Subnet subnet : manageOneSubnets) {
                        BocloudResult manageOneResult = subnetService.remove(subnet.getId(), context);
                        Assert.isTrue(manageOneResult.isSuccess(), manageOneResult.getMessage());
                    }
                    BocloudResult manageOneResult = routerService.remove(routerId, context);
                    if (manageOneResult.isFailed()) {
                        return manageOneResult;
                    }
                    networkRepository.remove(vpc.getNetworkId(), context.getTarget());
                    vpcRepository.delete(vpc.getId());
                    break;
                case FUSIONCLOUD:
                    break;
                case AZURE:
                case TCE:
                case ALIYUN:
                case HUAWEI:
                case HCSO:
                case TENCENT:
                case AWS:
                    List<Subnet> tencentSubnets = subnetRepository.listByVpcId(vendor.getId(), vpc.getVpcId());
                    for (Subnet subnet : tencentSubnets) {
                        SubnetModel model = new SubnetModel();
                        model.setSubnetUuid(subnet.getSubnetUuid());
                        model.setVpcUuid(subnet.getVpcUuid());
                        model.setName(subnet.getName());
                        model.setCidr(subnet.getCidr());
                        BocloudResult tceResult = subnetDriver.remove(model, vendor.getUuid(), subnet.getRegionId());
                        Assert.isTrue(tceResult.isSuccess(), tceResult.getMessage());
                        subnetRepository.remove(subnet.getId());
                    }
                    if (CloudProvider.AWS.name().equalsIgnoreCase(vendor.getType())) {
                        InternetGateway internetGateway = internetGatewayRepository.getByVpcId(vpc.getVpcId(), vendor.getId(), vpc.getRegionId());
                        if (internetGateway != null) {
                            BocloudResult result = internetGatewayDriver.detach(vendor.getUuid(), internetGateway.getInternetGatewayUuid(),
                                    vpc.getVpcId(), vpc.getRegionId());
                            Assert.isTrue(result.isSuccess(), result.getMessage());
                            result = internetGatewayService.remove(internetGateway.getId(), context);
                            Assert.isTrue(result.isSuccess(), result.getMessage());
                        }
                    }
                    if (CloudProvider.ALIYUN.name().equalsIgnoreCase(vendor.getType())) {
                        List<SecurityGroup> securityGroups =
                                securityGroupRepository.listByVpcId(vpc.getId(), null, null);
                        if (!ListTool.isEmpty(securityGroups)) {
                            for (SecurityGroup securityGroup : securityGroups) {
                                BocloudResult remove = securityGroupDriver.remove(securityGroup.getGroupUuid(),
                                        vendor.getUuid(), securityGroup.getRegionId());
                                if (remove.isFailed()) {
                                    return remove;
                                }
                                securityGroupRuleRepository.removeBySgId(securityGroup.getId(), context.getTarget());
                                securityGroupRepository.remove(securityGroup.getId(), context.getTarget());
                            }
                        }
                    }
                    BocloudResult tencentResult = this.remove(vpc.getId(), context);
                    if (tencentResult.isFailed()) {
                        return tencentResult;
                    }
                    break;
                default:
                    break;
            }
            quotas.add(new QuotaBean(vendor.getType().toLowerCase() + ".standard.vpc", 1));
            OrderMessage orderMessage =
                    new OrderMessage(vpc.getUuid(), OrderMessage.Operation.Cancelation, OrderItemStatus.UnsubscribeSuccess,
                            null, "VPC退订成功", null, null, new ArrayList<>(), ResourceCategory.Vpc.name(), context);
            orderMessage.setCategory(ResourceCategory.Vpc.name());
            orderMessage.setQuotas(quotas);
            amqpTemplate.convertAndSend("resource.result.queue", orderMessage);
            return new BocloudResult<>(true, "VPC退订成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult associate(Long id, RequestContext context, String cidr) {
        try {
            Vpc vpc = vpcRepository.query(id);
            Assert.notNull(vpc, "VPC不存在");
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            CloudProvider provider = CloudProvider.valueOf(vendor.getType());
            BocloudResult bocloudResult = null;
            switch (provider) {
                case AWS:
                    bocloudResult =
                            vpcDriver.associateCidrBlock(vpc.getVpcId(), cidr, vendor.getUuid(), vpc.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    BocloudResult detailResult = vpcDriver.detail(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                    if (detailResult.isFailed()) {
                        return detailResult;
                    }
                    VpcModel vpcModel = (VpcModel) detailResult.getData();
                    for (CidrBlockModel cidrBlockModel : vpcModel.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(vpc.getRegionId());
                            cidrBlockRepository.save(cidrBlock);

                            JSONArray cidrs = JSONObject.parseArray(vpc.getCidr());
                            cidrs.add(cidr);
                            vpc.setCidr(JSONObject.toJSONString(cidrs));
                            vpcRepository.update(vpc);

                            List<RouteTable> routeTables = routeTableRepository.list(vendor.getId(), vpc.getVpcId());
                            if (!ListTool.isEmpty(routeTables)) {
                                for (RouteTable routeTable : routeTables) {
                                    Route route = new Route();
                                    route.setRouteTableId(routeTable.getId());
                                    route.setRouteTableUuid(routeTable.getUuid());
                                    route.setDestinationType("IPV4");
                                    route.setDestination(cidr);
                                    route.setTargetType("INTERNET_GATEWAY");
                                    route.setTargetUuid("local");
                                    route.setOrigin("CreateRoute");
                                    route.setState("active");
                                    route.setVendorId(vendor.getId());
                                    route.setCreatorId(context.getTarget());
                                    route.setRegionId(vpc.getRegionId());
                                    routeRepository.save(route);
                                }
                            }
                            break;
                        }
                    }
                    break;
                case HUAWEI:
                case HCSO:
                    break;
                case ALIYUN:
                    bocloudResult =
                            vpcDriver.associateCidrBlock(vpc.getVpcId(), cidr, vendor.getUuid(), vpc.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    CidrBlock cidrBlock = new CidrBlock();
                    cidrBlock.setCidrBlock(cidr);
                    cidrBlock.setTargetId(vpc.getVpcId());
                    cidrBlock.setType("Secondary");
                    cidrBlock.setCreatorId(context.getTarget());
                    cidrBlock.setVendorId(vendor.getId());
                    cidrBlock.setRegionId(vpc.getRegionId());
                    cidrBlockRepository.save(cidrBlock);
                    JSONArray cidrs = JSONObject.parseArray(vpc.getCidr());
                    cidrs.add(cidr);
                    vpc.setCidr(JSON.toJSONString(cidrs));
                    vpcRepository.update(vpc);
                    break;
                default:
                    break;
            }
            return new BocloudResult<>(true, "VPC-IPv4 CIDR 保存成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult associateIpv6(Long id, RequestContext context) {
        try {
            Vpc vpc = vpcRepository.query(id);
            Assert.notNull(vpc, "VPC不存在");
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            CloudProvider provider = CloudProvider.valueOf(vendor.getType());
            BocloudResult bocloudResult = null;
            BocloudResult detailResult = null;
            VpcModel vpcModel = null;
            switch (provider) {
                case AWS:
                    bocloudResult =
                            vpcDriver.associateIpv6CidrBlock(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    detailResult = vpcDriver.detail(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                    if (detailResult.isFailed()) {
                        return detailResult;
                    }
                    vpcModel = (VpcModel) detailResult.getData();
                    for (CidrBlockModel cidrBlockModel : vpcModel.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(vpc.getRegionId());
                            cidrBlockRepository.save(cidrBlock);

                            vpc.setIpv6Cidr(cidrBlock.getCidrBlock());
                            vpcRepository.update(vpc);

                            List<RouteTable> routeTables = routeTableRepository.list(vendor.getId(), vpc.getVpcId());
                            if (!ListTool.isEmpty(routeTables)) {
                                for (RouteTable routeTable : routeTables) {
                                    Route route = new Route();
                                    route.setRouteTableId(routeTable.getId());
                                    route.setRouteTableUuid(routeTable.getUuid());
                                    route.setDestinationType("IPV6");
                                    route.setDestination(cidrBlock.getCidrBlock());
                                    route.setTargetType("INTERNET_GATEWAY");
                                    route.setTargetUuid("local");
                                    route.setOrigin("CreateRoute");
                                    route.setState("active");
                                    route.setVendorId(vendor.getId());
                                    route.setCreatorId(context.getTarget());
                                    route.setRegionId(vpc.getRegionId());
                                    routeRepository.save(route);
                                }
                            }
                            break;
                        }
                    }
                    break;
                case HUAWEI:
                case HCSO:
                    break;
                case ALIYUN:
                    bocloudResult =
                            vpcDriver.associateIpv6CidrBlock(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    detailResult = vpcDriver.detail(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                    if (detailResult.isFailed()) {
                        return detailResult;
                    }
                    vpcModel = (VpcModel) detailResult.getData();
                    for (CidrBlockModel cidrBlockModel : vpcModel.getCidrBlockModels()) {
                        if ("IPV6".equalsIgnoreCase(cidrBlockModel.getType())) {
                            CidrBlock cidrBlock = new CidrBlock();
                            BeanUtils.copyProperties(cidrBlockModel, cidrBlock);
                            cidrBlock.setCreatorId(context.getTarget());
                            cidrBlock.setVendorId(vendor.getId());
                            cidrBlock.setRegionId(vpc.getRegionId());
                            cidrBlockRepository.save(cidrBlock);
                            vpc.setIpv6Cidr(vpc.getIpv6Cidr());
                            vpcRepository.update(vpc);
                            break;
                        }
                    }
                    break;
                default:
                    break;
            }
            return new BocloudResult<>(true, "VPC-IPv6 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 {
            Vpc vpc = vpcRepository.query(id);
            Assert.notNull(vpc, "VPC不存在");
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            CloudProvider provider = CloudProvider.valueOf(vendor.getType());
            CidrBlock cidrBlock;
            BocloudResult bocloudResult = null;
            switch (provider) {
                case AWS:
                    cidrBlock = cidrBlockRepository.query(cidrId);
                    Assert.notNull(vpc, "CidrBlock不存在");
                    bocloudResult =
                            vpcDriver.disassociateCidrBlock(cidrBlock.getUuid(), vendor.getUuid(), vpc.getRegionId());
                    if (bocloudResult.isFailed()) {
                        return bocloudResult;
                    }
                    if ("IPV4".equals(cidrBlock.getType())) {
                        JSONArray cidrs = JSONObject.parseArray(vpc.getCidr());
                        cidrs.remove(cidrBlock.getCidrBlock());
                        vpc.setCidr(JSONObject.toJSONString(cidrs));
                    } else {
                        vpc.setIpv6Cidr(null);
                    }
                    vpcRepository.update(vpc);
                    cidrBlockRepository.remove(cidrId, context.getTarget());
                    routeRepository.removeByDestination(vendor.getId(), cidrBlock.getCidrBlock(), context.getTarget());
                    break;
                case HUAWEI:
                case HCSO:
                    break;
                case ALIYUN:
                    cidrBlock = cidrBlockRepository.query(cidrId);
                    Assert.notNull(vpc, "CidrBlock不存在");
                    if ("Primary".equalsIgnoreCase(cidrBlock.getType())) {
                        return new BocloudResult<>(false, "主网段不允许删除");
                    }
                    if ("Secondary".equalsIgnoreCase(cidrBlock.getType())) {
                        bocloudResult = vpcDriver.disassociateVpcCidrBlock(vpc.getVpcId(), cidrBlock.getCidrBlock(),
                                vendor.getUuid(), vpc.getRegionId());
                        if (bocloudResult.isFailed()) {
                            return bocloudResult;
                        }
                        JSONArray cidrs = JSONObject.parseArray(vpc.getCidr());
                        cidrs.remove(cidrBlock.getCidrBlock());
                        vpc.setCidr(JSON.toJSONString(cidrs));
                        vpcRepository.update(vpc);
                        cidrBlockRepository.remove(cidrId, context.getTarget());
                    }
                    if ("IPV6".equalsIgnoreCase(cidrBlock.getType())) {
                        bocloudResult =
                                vpcDriver.disassociateCidrBlock(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
                        if (bocloudResult.isFailed()) {
                            return bocloudResult;
                        }
                        vpc.setIpv6Cidr(null);
                        vpcRepository.update(vpc);
                        cidrBlockRepository.remove(cidrId, context.getTarget());
                    }
                    break;
                default:
                    break;
            }
            return new BocloudResult<>(true, "VPC CIDR 移除成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult operations(Long id, VpcOperationParam vpcOperationParam, RequestContext context) {
        if (null == vpcOperationParam || StringUtils.isEmpty(vpcOperationParam.getAction())) {
            return new BocloudResult<>(false, "参数格式错误");
        }
        String action = vpcOperationParam.getAction();
        if ("associate".equalsIgnoreCase(action)) {
            return this.associate(id, context, vpcOperationParam.getCidr());
        } else if ("associateIpv6".equalsIgnoreCase(action)) {
            return this.associateIpv6(id, context);
        } else if ("disassociate".equalsIgnoreCase(action)) {
            return this.disassociate(id, context, vpcOperationParam.getId());
        } else if ("addAddressSpace".equalsIgnoreCase(action)) {
            return this.addAddressSpace(vpcOperationParam, context);
        } else if ("removeAddressSpace".equalsIgnoreCase(action)) {
            return this.removeAddressSpace(vpcOperationParam, context);
        }
        return new BocloudResult<>(false, "无效操作！");
    }

    @Override
    public BocloudResult<GridBean<CidrBlock>> cidrs(Pager pager, RequestContext context) {
        try {
            List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
            Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
            sorter.put("gmtCreate", Common.ONE);
            Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
            Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);
            sorter.put("gmtCreate", Common.ZERO);
            int total = cidrBlockRepository.count(params);
            List<CidrBlock> list = cidrBlockRepository.list(page, rows, params, sorter);
            GridBean gridBean = GridHelper.getBean(page, rows, total, list);
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list cidr failure:", e);
            return new BocloudResult<>(false, "查询失败", null, null);
        }
    }

    @Override
    public BocloudResult<List<Vpc>> condition(String condition, RequestContext context) {
        condition = Optional.ofNullable(condition).orElse("");
        JSONObject object = JSONObject.parseObject(condition);
        String action = object.getString("condition");
        if ("zone".equalsIgnoreCase(action)) {
            return this.listByZone(condition, context);
        } else if ("listByVendorAndRegion".equalsIgnoreCase(action)) {
            Long vendorId = object.getLong("vendorId");
            String regionId = object.getString("regionId");
            List<Vpc> list = vpcRepository.list(vendorId, regionId);
            return new BocloudResult<>(true, list, "查询网络列表成功");
        }
        return ResultTools.formatErrResult();
    }

    @Override
    public BocloudResult withDdos(Long id, Long planId, RequestContext context) {
        String path = DdosProtectionPlan.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Vpc vpc = vpcRepository.query(id);
            Assert.notNull(vpc, "数据不存在");
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            DdosProtectionPlan plan = planRepository.query(planId);
            Assert.notNull(plan, "DDOS防护计划不存在！");
            BocloudResult result =
                    vpcDriver.withDdos(vpc.getVpcId(), plan.getDdosUuid(), vendor.getUuid(), vpc.getRegionId());
            Assert.isTrue(result.isSuccess(), result.getMessage());
            vpc.setDdosPlanEnabled(true);
            vpc.setDdosPlanId(planId);
            vpc.setDdosPlanUuid(plan.getDdosUuid());
            vpc.setMenderId(context.getTarget());
            boolean flag = vpcRepository.update(vpc);
            return flag ? new BocloudResult(true, "更新成功") : new BocloudResult(false, "更新失败");
        } catch (Exception e) {
            logger.error("Get error message：{}", e);
            return new BocloudResult(false, "更新失败：" + e.getMessage());
        }
    }

    @Override
    public BocloudResult withoutDdos(Long id, RequestContext context) {
        String path = DdosProtectionPlan.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Vpc vpc = vpcRepository.query(id);
            Assert.notNull(vpc, "数据不存在");
            CloudVendor vendor = cloudVendorRepository.query(vpc.getVendorId());
            Assert.notNull(vendor, "云平台不存在！");
            BocloudResult result = vpcDriver.withoutDdos(vpc.getVpcId(), vendor.getUuid(), vpc.getRegionId());
            Assert.isTrue(result.isSuccess(), result.getMessage());
            vpc.setDdosPlanEnabled(false);
            vpc.setDdosPlanId(null);
            vpc.setDdosPlanUuid(null);
            vpc.setMenderId(context.getTarget());
            boolean flag = vpcRepository.update(vpc);
            return flag ? new BocloudResult(true, "更新成功") : new BocloudResult(false, "更新失败");
        } catch (Exception e) {
            logger.error("Get error message：{}", e);
            return new BocloudResult(false, "更新失败：" + e.getMessage());
        }
    }

    public BocloudResult addAddressSpace(VpcOperationParam vpcOperationParam, RequestContext context) {
        try {
            String cidr = vpcOperationParam.getCidr();
            Vpc entity = vpcRepository.query(vpcOperationParam.getId());
            Assert.notNull(entity, "vpc不存在");
            CloudVendor vendor = cloudVendorRepository.query(entity.getVendorId());
            Assert.notNull(vendor, "平台验证失败");
            VpcModel model = new VpcModel();
            model.setVpcId(entity.getVpcId());
            model.setCidr(cidr);
            BocloudResult result = vpcDriver.addAddressSpace(model, vendor.getUuid(), entity.getRegionId());
            if (result.isFailed()) {
                return result;
            }
            VpcModel newModel = JSONObject
                    .parseObject(JSONObject.toJSONString(result.getData()), VpcModel.class);
            entity.setCidr(newModel.getCidr());
            entity.setGmtModify(new Date());
            entity.setMenderId(context.getTarget());
            vpcRepository.update(entity);
            return new BocloudResult(true, "更新成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e);
            return new BocloudResult(false, "更新失败：" + e.getMessage());
        }
    }

    public BocloudResult removeAddressSpace(VpcOperationParam vpcOperationParam, RequestContext context) {
        try {
            String cidr = vpcOperationParam.getCidr();
            Vpc entity = vpcRepository.query(vpcOperationParam.getId());
            Assert.notNull(entity, "vpc不存在");
            CloudVendor vendor = cloudVendorRepository.query(entity.getVendorId());
            Assert.notNull(vendor, "平台验证失败");
            VpcModel model = new VpcModel();
            model.setVpcId(entity.getVpcId());
            model.setCidr(cidr);
            BocloudResult result = vpcDriver.removeAddressSpace(model, vendor.getUuid(), entity.getRegionId());
            if (result.isFailed()) {
                return result;
            }
            VpcModel newModel = JSONObject
                    .parseObject(JSONObject.toJSONString(result.getData()), VpcModel.class);
            entity.setCidr(newModel.getCidr());
            entity.setGmtModify(new Date());
            entity.setMenderId(context.getTarget());
            vpcRepository.update(entity);
            return new BocloudResult(true, "更新成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e);
            return new BocloudResult(false, "更新失败：" + e.getMessage());
        }
    }

}