package com.bocloud.ims.service.resource.azure.slb;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.azure.slb.LoadBalanceDriver;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.NotifyMessage;
import com.bocloud.cmp.model.azure.slb.InboundNatPoolModel;
import com.bocloud.cmp.model.azure.slb.SlbModel;
import com.bocloud.cmp.model.common.*;
import com.bocloud.cmp.params.azure.UserAssignParams;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.DateTools;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.common.enums.azure.AzureIpRelationType;
import com.bocloud.ims.common.enums.azure.AzureTaskStatus;
import com.bocloud.ims.entity.common.Project;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.azure.network.PublicIPAddress;
import com.bocloud.ims.entity.resource.azure.network.ResourcePublicIPAddressRelation;
import com.bocloud.ims.entity.resource.azure.slb.BackEnd;
import com.bocloud.ims.entity.resource.azure.slb.FrontEnd;
import com.bocloud.ims.entity.resource.azure.slb.InboundNatPool;
import com.bocloud.ims.entity.resource.azure.slb.Slb;
import com.bocloud.ims.interfaces.resource.azure.slb.SlbService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.repository.resource.azure.network.PublicIPAddressRepository;
import com.bocloud.ims.repository.resource.azure.network.ResourcePublicIPAddressRelationRepository;
import com.bocloud.ims.repository.resource.azure.slb.*;
import com.bocloud.ims.service.internal.SmsProjectService;
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.Maps;
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 org.springframework.util.ObjectUtils;

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

@Service("slbService")
public class SlbServiceImpl implements SlbService {

    private static Logger logger = LoggerFactory.getLogger(SlbServiceImpl.class);

    private static OperateResult.OperateCategory operateCategory = OperateResult.OperateCategory.ResourceEvent;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private SlbRepository slbRepository;
    @Autowired
    private ResourceGroupRepository resourceGroupRepository;
    @Autowired
    private LoadBalanceDriver loadBalanceDriver;
    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private ResourceEventPublisher resourceEventPublisher;
    @Autowired
    private PublicIPAddressRepository publicIPAddressRepository;
    @Autowired
    private InboundNatPoolRepository inboundNatPoolRepository;
    @Autowired
    private FrontEndRepository frontEndRepository;
    @Autowired
    private SmsProjectService smsProjectService;
    @Autowired
    private ResourcePublicIPAddressRelationRepository resourcePublicIPAddressRelationRepository;
    @Autowired
    private BackEndRepository backEndRepository;
    @Autowired
    private InboundNatRuleRepository inboundNatRuleRepository;
    @Autowired
    private ProbeRepository probeRepository;
    @Autowired
    private LbRuleRepository lbRuleRepository;
    @Autowired
    private ObjectRelationRepository objectRelationRepository;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private VpcRepository vpcRepository;
    @Autowired
    private SubnetRepository subnetRepository;

    @Override
    public BocloudResult<GridBean<Slb>> list(Pager pager, RequestContext context) {
        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);
        Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
        Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
        Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);
        try {
            List<Slb> list;
            int total;
            GridBean<Slb> gridBean;

            Long tenantId = context.getTenant();
            Long projectId = context.getProject();
            // 为租户下的用户
            if (null != tenantId && 0L != tenantId) {
                List<Project> projects = smsProjectService.projectsByCondition(context.getTarget(),
                        context.getCatalog());
                List<Long> projectIds = new ArrayList<>();
                // 此时查询的是全部用户全部项目的信息
                if (null != projectId && 0L != projectId) {
                    projectIds.add(projectId);
                } else if (!ListTool.isEmpty(projects)) {
                    projects.forEach(project -> projectIds.add(project.getId()));
                } else {
                    projectIds.add(-1L);
                }
                total = this.slbRepository.count(params, null, projectIds, null);
                list = this.slbRepository.list(page, rows, params, sorter, null, projectIds, null);
            } else {
                list = slbRepository.list(page, rows, params, sorter);
                total = slbRepository.count(params);
            }
            gridBean = new GridBean<>(page, rows, total, list);
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list slb failure:", e);
            return new BocloudResult<>(false, "查询失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> create(Slb entityParams, RequestContext context) {
        try {
            CloudVendor vendor = cloudVendorRepository.query(entityParams.getVendorId());
            Assert.notNull(vendor, "平台验证失败");
            if (null != slbRepository.getByName(entityParams.getVendorId(), entityParams.getResourceGroupId(), entityParams.getName())) {
                return new BocloudResult<>(false, "名称已存在");
            }
            ResourceGroup resourceGroup = resourceGroupRepository.query(entityParams.getResourceGroupId());
            Assert.notNull(resourceGroup, "资源组不能为空");

            List<InboundNatPoolModel> inboundNatPoolModels = new ArrayList<>();
            entityParams.getInboundNatPools().forEach(pool -> {
                InboundNatPoolModel natPoolModel = new InboundNatPoolModel();
                BeanUtils.copyProperties(pool, natPoolModel);
                inboundNatPoolModels.add(natPoolModel);
            });

            SlbModel model = new SlbModel();
            BeanUtils.copyProperties(entityParams, model);
            model.setResourceGroupName(resourceGroup.getName());
            model.setInboundNatPoolModels(inboundNatPoolModels);
            //判断是内部还是外部
            if (entityParams.getSlbType().equalsIgnoreCase("INTERNAL")) {
                Vpc vpc = vpcRepository.query(entityParams.getVpcId());
                Assert.notNull(vpc, "vpc验证失败");
                Subnet subnet = subnetRepository.query(entityParams.getSubnetId());
                Assert.notNull(subnet, "子网验证失败");
                model.setVpcUuid(vpc.getVpcId());
                model.setSubnetName(subnet.getName());
                model.setSubnetUuid(subnet.getSubnetUuid());
            } else if (entityParams.getSlbType().equalsIgnoreCase("EXTERNAL")) {
                // 公共ipuuid
                List<String> publicIPAddressUuids = new ArrayList<>();
                List<Long> publicIPAddressIds = new ArrayList<>();
                for (Long ipId : entityParams.getPublicIPAddressIds()) {
                    PublicIPAddress publicIPAddress = publicIPAddressRepository.query(ipId);
                    publicIPAddressIds.add(publicIPAddress.getId());
                    publicIPAddressUuids.add(publicIPAddress.getUuid());
                }
                model.setPublicIPAddressUuids(publicIPAddressUuids);
            }
            //增加状态
            entityParams.setCreatorId(context.getTarget());
            entityParams.setResourceGroupId(resourceGroup.getId());
            entityParams.setTenantId(context.getTenant());
            entityParams.setProjectId(context.getProject());
            if (context.getCatalog() == RequestContext.Catalog.User) {
                entityParams.setUserId(context.getTarget());
            }
            entityParams.setStatus(AzureTaskStatus.BUILDING.name());
            slbRepository.save(entityParams);

            taskExecutor.execute(() -> {
                String operate = vendor.getType().toLowerCase() + ".slb";
                String message = "创建负载均衡器失败";
                BocloudResult result = loadBalanceDriver.create(vendor.getUuid(), entityParams.getRegionId(), model);
                try {
                    if (result.isSuccess()) {
                        message = "尊敬的客户，您好！您的负载均衡器【" + entityParams.getName() + "】于" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "创建成功，请登录控制台查看及管理。";
                        SlbModel newModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                                SlbModel.class);
                        BeanUtils.copyProperties(newModel, entityParams);
                        entityParams.setStatus(AzureTaskStatus.AVAILABLE.name());
                        slbRepository.update(entityParams);

                        newModel.getInboundNatPoolModels().forEach(natPoolModel -> {
                            InboundNatPool natPool = new InboundNatPool();
                            BeanUtils.copyProperties(natPoolModel, natPool);
                            natPool.setSlbId(entityParams.getId());
                            natPool.setVendorId(entityParams.getVendorId());
                            natPool.setCreatorId(context.getTarget());
                            inboundNatPoolRepository.save(natPool);
                        });

                        newModel.getFrontEndModels().forEach(frontEndModel -> {
                            FrontEnd frontEnd = new FrontEnd();
                            BeanUtils.copyProperties(frontEndModel, frontEnd);
                            frontEnd.setSlbId(entityParams.getId());
                            frontEnd.setVendorId(entityParams.getVendorId());
                            if (frontEnd.getFrontEndType().equalsIgnoreCase("INTERNAL")) {
                                Subnet subnet = subnetRepository.query(frontEndModel.getSubnetUuid(), entityParams.getVendorId());
                                if (null != subnet) {
                                    frontEnd.setSubnetId(subnet.getId());
                                }
                                frontEndRepository.save(frontEnd);
                            } else if (frontEnd.getFrontEndType().equalsIgnoreCase("EXTERNAL")) {
                                PublicIPAddress publicIPAddress = publicIPAddressRepository.getByUuid(entityParams.getVendorId(), frontEndModel.getPublicIpUuid());
                                Optional.ofNullable(publicIPAddress).ifPresent(ipAddress -> frontEnd.setPublicIpId(ipAddress.getId()));
                                frontEndRepository.save(frontEnd);
                                if (!ObjectUtils.isEmpty(publicIPAddress)) {
                                    //弹性IP重置状态
                                    publicIPAddress.setStatus(AzureTaskStatus.IN_USE.name());
                                    publicIPAddressRepository.update(publicIPAddress);
                                    //弹性IP增加绑定关系
                                    ResourcePublicIPAddressRelation relation = new ResourcePublicIPAddressRelation();
                                    relation.setIpId(publicIPAddress.getId());
                                    relation.setResourceId(frontEnd.getId());
                                    relation.setResourceType(AzureIpRelationType.FRONTEND.name());
                                    resourcePublicIPAddressRelationRepository.save(relation);
                                }
                            }
                        });
                    } else {
                        logger.error("创建负载均衡器失败：" + result.getMessage());
                        message = "尊敬的客户，您好！您的负载均衡器【" + entityParams.getName() + "】于" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "创建失败，失败信息：" + result.getMessage();
                        slbRepository.remove(entityParams.getId(), context.getTarget());
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate,
                            MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                    //站内信推送
                    NotifyMessage notifyMessage = new NotifyMessage(context, "负载均衡器:", message, null,
                            true, false);
                    amqpTemplate.convertAndSend("event.notice.queue", notifyMessage);
                } catch (Exception e) {
                    logger.error("create slb fail:", e);
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate,
                            MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                }
            });
            return new BocloudResult<>(true, "任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("create slb error:", e);
            return new BocloudResult<>(false, "创建负载均衡失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> remove(Long id, RequestContext context) {
        String path = BackEnd.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Slb entity = slbRepository.query(id);
            Assert.notNull(entity, "数据不存在");
            CloudVendor vendor = cloudVendorRepository.query(entity.getVendorId());
            Assert.notNull(vendor, "平台验证失败");
            entity.setStatus(AzureTaskStatus.DELETING.name());
            slbRepository.update(entity);

            taskExecutor.execute(() -> {
                String operate = vendor.getType().toLowerCase() + ".slb";
                String message = "删除负载均衡器失败";
                BocloudResult result = loadBalanceDriver.remove(vendor.getUuid(), entity.getRegionId(),
                        entity.getUuid());
                try {
                    if (result.isSuccess()) {
                        message = "删除负载均衡器成功";
                        slbRepository.remove(id, context.getTarget());
                        List<FrontEnd> frontEnds = frontEndRepository.listSlbId(id);
                        for (FrontEnd frontEnd : frontEnds) {
                            List<ResourcePublicIPAddressRelation> addressRelations = resourcePublicIPAddressRelationRepository.listByResourceId(frontEnd.getId(), AzureIpRelationType.FRONTEND.name());
                            for (ResourcePublicIPAddressRelation relation : addressRelations) {
                                PublicIPAddress publicIPAddress = publicIPAddressRepository.query(relation.getIpId());
                                if (!ObjectUtils.isEmpty(publicIPAddress)) {
                                    //重置状态
                                    publicIPAddress.setStatus(AzureTaskStatus.AVAILABLE.name());
                                    publicIPAddressRepository.update(publicIPAddress);
                                }
                            }
                            resourcePublicIPAddressRelationRepository.removeByResourceId(frontEnd.getId(), AzureIpRelationType.FRONTEND.name());
                        }
                        backEndRepository.removeSlbId(entity.getId(), context.getTarget());
                        frontEndRepository.removeSlbId(entity.getId(), context.getTarget());
                        inboundNatPoolRepository.removeSlbId(entity.getId(), context.getTarget());
                        inboundNatRuleRepository.removeSlbId(entity.getId(), context.getTarget());
                        probeRepository.removeSlbId(entity.getId(), context.getTarget());
                        lbRuleRepository.removeSlbId(entity.getId(), context.getTarget());
                    } else {
                        logger.error("删除负载均衡器失败：" + result.getMessage());
                        message = result.getMessage();
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate,
                            MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                    //站内信推送
                    NotifyMessage notifyMessage = new NotifyMessage(context, "提示:", message, null,
                            true, false);
                    amqpTemplate.convertAndSend("event.notice.queue", notifyMessage);
                } catch (Exception e) {
                    logger.error("remove slb fail:", e);
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), message, operate,
                            MapTools.simpleMap("vendorId", vendor.getId()), operateCategory, context));
                }
            });
            return new BocloudResult<>(true, "任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("remove slb fail:", e);
            return new BocloudResult<>(false, "删除负载均衡器失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Slb> detail(Long id, RequestContext context) {
        try {
            Slb entity = slbRepository.query(id);
            Assert.notNull(entity, "数据不存在");
            return new BocloudResult<>(true, entity, "查询详情成功");
        } catch (Exception e) {
            logger.error("query slb detail fail:", e);
            return new BocloudResult<>(false, "查询详情失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> apply(ApplicationParam param) {
        try {
            Assert.notNull(param, "参数格式错误");
            ServiceOrder order = param.getOrder();
            Assert.notNull(order, "订单不存在");
            List<OrderItem> items = order.getItems();
            Assert.notEmpty(items, "订单明细不存在");
            // 申请人
            RequestContext context = param.getContext();
            Assert.notNull(context, "申请人不存在");
            // 位置
            LocationModel location = param.getLocation();
            // 订购信息
            EmptionModel emption = param.getEmption();
            // 使用时长信息
            DurationModel duration = emption.getDuration();
            // 使用时长单位Hour/Month
            DurationModel.Mode mode = duration.getMode();
            // 时长
            Integer month = duration.getAmount();
            // 申请个数
            Integer count = null == emption.getCount() ? 1 : emption.getCount();
            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);
            }
            CloudVendor vendor = cloudVendorRepository.query(location.getVendorId());
            Assert.notNull(vendor, "当前可用域未绑定云平台");
            logger.info("apply slb start...");
            for (int i = 0; i < count; i++) {
                OrderItem orderItem = items.get(i);
                Slb entityParams = JSONObject.parseObject(param.getConfigs().toJSONString(), Slb.class);
                if (null != slbRepository.getByName(entityParams.getVendorId(), entityParams.getResourceGroupId(), entityParams.getName())) {
                    return new BocloudResult<>(false, "名称已存在");
                }
                ResourceGroup resourceGroup = resourceGroupRepository.query(entityParams.getResourceGroupId());
                if (ObjectUtils.isEmpty(resourceGroup)) {
                    logger.error("get resourceGroup failure");
                    return new BocloudResult<>(false, "资源组不能为空");
                }
                // 公共ipuuid
                List<String> publicIPAddressUuids = new ArrayList<>();
                List<Long> publicIPAddressIds = new ArrayList<>();
                for (Long ipId : entityParams.getPublicIPAddressIds()) {
                    PublicIPAddress publicIPAddress = publicIPAddressRepository.query(ipId);
                    publicIPAddressIds.add(publicIPAddress.getId());
                    publicIPAddressUuids.add(publicIPAddress.getUuid());
                }

                List<InboundNatPoolModel> inboundNatPoolModels = new ArrayList<>();
                entityParams.getInboundNatPools().forEach(pool -> {
                    InboundNatPoolModel natPoolModel = new InboundNatPoolModel();
                    BeanUtils.copyProperties(pool, natPoolModel);
                    inboundNatPoolModels.add(natPoolModel);
                });

                SlbModel model = new SlbModel();
                BeanUtils.copyProperties(entityParams, model);
                model.setResourceGroupName(resourceGroup.getName());
                model.setPublicIPAddressUuids(publicIPAddressUuids);
                model.setInboundNatPoolModels(inboundNatPoolModels);
                BocloudResult result = loadBalanceDriver.create(vendor.getUuid(), entityParams.getRegionId(), model);
                if (result.isSuccess()) {
                    SlbModel newModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
                            SlbModel.class);
                    BeanUtils.copyProperties(newModel, entityParams);
                    entityParams.setCreatorId(context.getTarget());
                    entityParams.setResourceGroupId(resourceGroup.getId());
                    entityParams.setTenantId(context.getTenant());
                    entityParams.setProjectId(context.getProject());
                    //entityParams.setItemUuid(orderItem.getSn());
                    slbRepository.save(entityParams);
                    newModel.getInboundNatPoolModels().forEach(natPoolModel -> {
                        InboundNatPool natPool = new InboundNatPool();
                        BeanUtils.copyProperties(natPoolModel, natPool);
                        natPool.setSlbId(entityParams.getId());
                        natPool.setVendorId(entityParams.getVendorId());
                        natPool.setCreatorId(context.getTarget());
                        inboundNatPoolRepository.save(natPool);
                    });
                    newModel.getFrontEndModels().forEach(frontEndModel -> {
                        FrontEnd frontEnd = new FrontEnd();
                        BeanUtils.copyProperties(frontEndModel, frontEnd);
                        frontEnd.setSlbId(entityParams.getId());
                        frontEnd.setVendorId(entityParams.getVendorId());
                        PublicIPAddress publicIPAddress = publicIPAddressRepository.getByUuid(entityParams.getVendorId(), frontEndModel.getPublicIpUuid());
                        Optional.ofNullable(publicIPAddress).ifPresent(ipAddress -> frontEnd.setPublicIpId(ipAddress.getId()));
                        frontEndRepository.save(frontEnd);
                        if (!ObjectUtils.isEmpty(publicIPAddress)) {
                            ResourcePublicIPAddressRelation relation = new ResourcePublicIPAddressRelation();
                            relation.setIpId(publicIPAddress.getId());
                            relation.setResourceId(frontEnd.getId());
                            relation.setResourceType("frontEnd");
                            resourcePublicIPAddressRelationRepository.save(relation);
                        }
                    });
                    Slb slb = entityParams;
                    List<ResourceModel> resources = new ArrayList<>();
                    ObjectRelation relation = new ObjectRelation(context.getTarget(), slb.getId(), false,
                            ResourceCategory.LoadBalance.name(), context.getCatalog().name(), 0);
                    relation.setExpiredTime(calendar.getTime());
                    objectRelationRepository.save(relation);
                    BocloudResult bocloudResult = new BocloudResult(true, "【" + slb.getName() + "】创建成功【"
                            + result.getMessage() + "】");
                    resources.add(new ResourceModel(slb.getName(), slb.getUuid(), param.getService(), slb.getUuid(), param.getOrder().getSn()));
                    // 通知订单
                    OrderMessage message = new OrderMessage(orderItem.getSn(), OrderMessage.Operation.Application, OrderItemStatus.OpenedSuccess,
                            null, bocloudResult.getMessage(), slb.getGmtCreate(), calendar.getTime(), resources,
                            ResourceCategory.LoadBalance.name(), context);
                    message.setCategory(ResourceCategory.LoadBalance.name());
                    // 通知订单
                    amqpTemplate.convertAndSend("resource.result.queue", message);
                } else {
                    logger.error("创建负载均衡器失败：" + result.getMessage());
                    return new BocloudResult(false, result.getMessage());
                }
            }
            // 发送给云平台统计队列对云平台重新统计
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(Common.VENDORID, vendor.getId());
            amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
            logger.info("apply slb end...");
            return new BocloudResult<>(true, "负载均衡器申请成功");
        } catch (Exception e) {
            logger.error("Apply slb error：{}", e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> extension(ExtensionParam param) {
        try {
            Slb slb = slbRepository.getByItemUuid(param.getInstance());
            Assert.notNull(slb, "负载均衡器不存在");
            ObjectRelation relation = objectRelationRepository.get(slb.getId(), ResourceCategory.LoadBalance.name());
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(relation.getExpiredTime());
            calendar.add(Calendar.MONTH, param.getExtension());
            objectRelationRepository.updateExpriedTime(slb.getId(), calendar.getTime(), ResourceCategory.LoadBalance.name(),
                    param.getContext().getCatalog().name());
            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.LoadBalance.name());
            message.setMessage("负载均衡器延期成功");
            amqpTemplate.convertAndSend("resource.result.queue", message);
            return new BocloudResult<>(true, "负载均衡器延期成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> cancelation(CancelationParam param) {
        try {
            Slb slb = slbRepository.getByItemUuid(param.getInstance());
            Assert.notNull(slb, "负载均衡器不存在");
            RequestContext context = param.getContext();
            BocloudResult result = this.remove(slb.getId(), context);
            Assert.isTrue(result.isSuccess(), result.getMessage());
            OrderMessage orderMessage = new OrderMessage(param.getInstance(), OrderMessage.Operation.Cancelation,
                    OrderItemStatus.UnsubscribeSuccess, null, "负载均衡器删除成功", null, null, new ArrayList<>(),
                    ResourceCategory.LoadBalance.name(), context);
            orderMessage.setCategory(ResourceCategory.LoadBalance.name());
            orderMessage.setQuotas(new ArrayList<>());
            amqpTemplate.convertAndSend("resource.result.queue", orderMessage);
            return new BocloudResult<>(true, "负载均衡器删除成功");
        } catch (Exception e) {
            logger.error("Get error message：{}", e.getMessage());
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult assign(UserAssignParams params, RequestContext context) {
        // 资源ID
        Long id = params.getId();
        // 租户用户ID
        Long userId = params.getUserId();
        // 租户用户所在项目
        Long projectId = params.getProjectId();
        Long tenantId = params.getTenantId();
        try {
            Slb slb = slbRepository.query(id);
            Assert.notNull(slb, "负载均衡器不存在");
            slb.setTenantId(tenantId);
            slb.setProjectId(projectId);
            slb.setUserId(userId);
            slbRepository.update(slb);
            return new BocloudResult(true, slb, "操作成功");
        } catch (Exception e) {
            logger.error("assign slb  fail:", e);
            return new BocloudResult(false, "操作失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> assignBatch(UserAssignParams params, RequestContext context) {
        // 资源ID
        List<Long> ids = params.getIds();
        for (Long id : ids) {
            // 租户用户ID
            Long userId = params.getUserId();
            // 租户用户所在项目
            Long projectId = params.getProjectId();
            Long tenantId = params.getTenantId();
            try {
                Slb slb = slbRepository.query(id);
                Assert.notNull(slb, "负载均衡器不存在");
                slb.setTenantId(tenantId);
                slb.setProjectId(projectId);
                slb.setUserId(userId);
                slbRepository.update(slb);
            } catch (Exception e) {
                logger.error("assign slb  fail:", e);
                return new BocloudResult(false, "操作失败:" + e.getMessage());
            }
        }
        return new BocloudResult(true, "操作成功");
    }
}
