package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.compute.ImageDriver;
import com.bocloud.cmp.driver.compute.ServerDriver;
import com.bocloud.cmp.driver.compute.ServerTemplateDriver;
import com.bocloud.cmp.entity.enums.BocloudStatus;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.*;
import com.bocloud.common.model.*;
import com.bocloud.common.model.RequestContext.Catalog;
import com.bocloud.common.utils.*;
import com.bocloud.ims.common.config.StorageConfig;
import com.bocloud.ims.entity.common.Project;
import com.bocloud.ims.entity.common.User;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.interfaces.manageone.ManageOneAccountService;
import com.bocloud.ims.interfaces.resource.ImageService;
import com.bocloud.ims.interfaces.resource.ResourcePoolService;
import com.bocloud.ims.repository.resource.*;
import com.bocloud.ims.service.internal.CosInternalService;
import com.bocloud.ims.service.internal.SmsProjectService;
import com.bocloud.ims.service.internal.SmsUserService;
import com.bocloud.ims.service.transporter.vendor.PowervcTransporter;
import com.bocloud.ims.service.transporter.vendor.SmartxTransporter;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * 镜像实现类
 *
 * @author DZG
 * @since V1.0 2016年9月13日
 */
@Service("imageService")
public class ImageServiceImpl implements ImageService {

	private static Logger logger = LoggerFactory.getLogger(ImageServiceImpl.class);
	@Autowired
	private ImageRepository imageRepository;
	@Autowired
	private ImageVolumeRepository imageVolumeRepository;
	@Autowired
	private RegionRepository regionRepository;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private VolumeRepository volumeRepository;
	@Autowired
	private ImageDriver imageDriver;
    @Autowired
    private ServerTemplateDriver serverTemplateDriver;
	@Autowired
	private ServerDriver serverDriver;
	@Autowired
	private PowervcTransporter powervcTransportor;
    @Autowired
    private SmartxTransporter smartTransporter;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private CloudServerRepository cloudServerRepository;
	@Autowired
	private StoreHostRepository storeHostRepository;
	@Autowired
	private NetworkHostRepository networkHostRepository;
	@Autowired
	private NetworkCardRepository networkCardRepository;
	@Autowired
	private StorageConfig storageConfig;
	@Autowired
	private CosInternalService cosInternalService;
	@Autowired
	private SmsProjectService smsProjectService;
	@Autowired
	private AmqpTemplate amqpTemplate;
	@Autowired
	private ObjectRelationRepository objectRelationRepository;
	@Autowired
	private SmsUserService smsUserService;
	@Autowired
	private ServerVolumeRepository serverVolumeRepository;
    @Autowired
    private ServerImageRepository serverImageRepository;
	@Autowired
	private OSTenantRepository osTenantRepository;
	@Autowired
	private ManageOneAccountService accountService;
	@Autowired
	private ResourceEventRepository resourceEventRepository;
	@Autowired
	private ResourceGroupRepository resourceGroupRepository;
	@Autowired
	private ResourcePoolService resourcePoolService;
	@Autowired
	private FlavorRepository flavorRepository;

	@Override
	public BocloudResult list(Pager pager, RequestContext context) {
		try {
			List<Image> list = new ArrayList<>();
			List<SimpleBean> beans = null;
			int total = 0;
			GridBean gridBean = null;

			Boolean applyList = false;
			List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
			for (Param param : params) {
				Map<String, Object> paramMap = param.getParam();
				if (paramMap.containsKey("applyList")) {
					applyList = Boolean.valueOf(String.valueOf(paramMap.get("applyList")));
					paramMap.remove("applyList");
					break;
				}
			}

			Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
			Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
			Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
			Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);
			sorter.put("gmt_create", Common.ONE);
			sorter.put("os_type", Common.ZERO);
			Catalog catalog = context.getCatalog();
			if ((Catalog.Tenant == catalog || Catalog.User == catalog) && !applyList) {
				String vendorType = null;
				for (Param param : params) {
					Map<String, Object> paramMap = param.getParam();
					if (paramMap.containsKey("vendorType")) {
						vendorType = String.valueOf(paramMap.get("vendorType"));
						paramMap.remove("vendorType");
					}
				}
				Long tenantId = context.getTenant();
				params.add(new Param(MapTools.simpleMap("tenantId", tenantId), Sign.EQ));
				List<Long> tenantVendorIds = resourcePoolService.listTenantVendorIds(tenantId, vendorType);
				tenantVendorIds.add(-1L);
				total = imageRepository.count(params, tenantVendorIds);
				List<Image> imageList = this.imageRepository.list(page, rows, params, sorter, tenantVendorIds);
				gridBean = GridHelper.getBean(page, rows, total, imageList);
			} else {
				total = this.imageRepository.count(params);
				if (simple) {
					beans = this.imageRepository.list(params, sorter);
					gridBean = new GridBean(1, 1, total, beans);
				} else {
					list = this.imageRepository.list(page, rows, params, sorter);
					// 镜像数据处理
					for (Image image : list) {
						if (null != image.getResourceGroupId()) {
							Optional.ofNullable(resourceGroupRepository.query(image.getResourceGroupId()))
									.map(ResourceGroup::getName).ifPresent(image::setResourceGroupName);
						}
						if(null != image.getSize()) {
							image.setSize(new BigDecimal(image.getSize()).setScale(2, RoundingMode.HALF_UP).doubleValue());
						}
					}
					gridBean = GridHelper.getBean(page, rows, total, list);
				}
			}
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query image list fail:", e);
			return new BocloudResult<>(false, "查询失败", null, null);
		}
	}

	private BocloudResult listTenantPublic(JSONObject object, RequestContext context) {
		if (null == object) {
			return new BocloudResult<>(false, "参数格式错误");
		}
		Long vendorId = object.getLong(Common.VENDORID);
		String regionId = object.getString("regionId");
		String status = object.getString("status");
		try {
			List<Param> params = new ArrayList<>();
			if (null != vendorId) {
				params.add(new Param(MapTools.simpleMap("regionId", regionId), Sign.EQ));
			}
			if (!StringUtils.isEmpty(regionId)) {
				params.add(new Param(MapTools.simpleMap("status", status), Sign.EQ));
			}
			if (!StringUtils.isEmpty(status)) {
				params.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
			}
			// 查询租户下的镜像
			Map<String, String> sorter = Maps.newHashMap();
			sorter.put("gmt_create", Common.ONE);
			sorter.put("os_type", Common.ZERO);
			List<Image> list = this.imageRepository.list(1, Integer.MAX_VALUE, params, sorter, context.getTenant(),
					null);
			// 查询共有镜像
			params.add(new Param(MapTools.simpleMap("imageType", "PUBLIC"), Sign.EQ));
			List<Image> publicList = this.imageRepository.list(1, Integer.MAX_VALUE, params, sorter, 0L, null);
			publicList.addAll(list);
			return new BocloudResult<>(true, publicList, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BocloudResult<>(false, "查询失败!");
		}

	}

	private BocloudResult listByCategory(JSONObject object) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(object.getLong("vendorId"));
			if (null == vendor) {
				return new BocloudResult<>(false, "平台信息异常！");
			}
			// 操作系统类型(Linux/Windows)
			String osCategory = object.getString("osCategory");
			// 操作系统版本
			String osVersion = object.getString("osVersion");

			if (StringUtils.isEmpty(osCategory) || StringUtils.isEmpty(osVersion)) {
				return new BocloudResult<>(false, "参数格式错误！");
			}
			List<Image> images = imageRepository.listByVendorId(vendor.getId());
			Image targetImage = null;
			if (CloudProvider.MANAGEONE.name().equals(vendor.getType())) {
				targetImage = images.stream().filter(image -> !StringUtils.isEmpty(image.getImageLabel())
						&& image.getImageLabel().contains(osCategory) && image.getImageLabel().contains(osVersion)
						&& "public".equalsIgnoreCase(image.getImageType())).findFirst()
						.orElseThrow(() -> new Exception("未找到合适的镜像"));
			} else {
				targetImage = images.stream().filter(image -> !StringUtils.isEmpty(image.getImageLabel())
						&& image.getImageLabel().contains(osCategory) && image.getImageLabel().contains(osVersion))
						.findFirst().orElseThrow(() -> new Exception("未找到合适的镜像"));
			}
			if (null == targetImage) {
				return new BocloudResult<>(false, "未找到合适的镜像!");
			} else {
				List<NetworkCard> cards = networkCardRepository.listByHost(targetImage.getTemplateId(), "VM");
				targetImage.setNetworkCards(cards);
				return new BocloudResult<>(true, targetImage, "查询成功！");
			}
		} catch (Exception e) {
			logger.error("查询镜像失败：" + e.getMessage());
			return new BocloudResult<>(false, "查询镜像失败：" + e.getMessage());
		}
	}

	private BocloudResult listByImageType(String condition, RequestContext context) {
		try {
			JSONObject object = JSONObject.parseObject(condition);
			Long vendorId = object.getLong("vendorId");
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult<>(false, "云平台信息不存在");
			}
			List<Image> list = new ArrayList<>();
			List<Param> params = new ArrayList<>();
			params.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
			if (object.containsKey("status")) {
				params.add(new Param(MapTools.simpleMap("status", object.getString("status")), Sign.EQ));
			}
			if (object.containsKey("regionId")) {
				params.add(new Param(MapTools.simpleMap("regionId", object.getString("regionId")), Sign.EQ));
			}
			if (object.containsKey("imageType")) {
				String imageType = object.getString("imageType");
				params.add(new Param(MapTools.simpleMap("imageType", imageType), Sign.EQ));
				if ("PRIVATE".equalsIgnoreCase(imageType)) {
					Catalog catalog = context.getCatalog();
					if (catalog.equals(Catalog.Tenant) || catalog.equals(Catalog.User)) {
						params.add(new Param(MapTools.simpleMap("tenantId", context.getTenant()), Sign.EQ));
					}
				}
			}
			if (CloudProvider.TIANYI.name().equals(vendor.getType())) {
				list = this.imageRepository.listHighConfig(1, Integer.MAX_VALUE, params, null);
			} else {
				list = this.imageRepository.list(1, Integer.MAX_VALUE, params, null);
			}
			Map<String, List<Image>> imageMap = new HashMap<String, List<Image>>();
			for (Image image : list) {
				if (imageMap.containsKey(image.getOsType())) {
					List<Image> oldList = imageMap.get(image.getOsType());
					oldList.add(image);
					imageMap.put(image.getOsType(), oldList);
				} else {
					List<Image> newList = new ArrayList<Image>();
					newList.add(image);
					imageMap.put(image.getOsType(), newList);
				}
			}

			return new BocloudResult<>(true, imageMap, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

	@Override
	public BocloudResult<Image> detail(Long id) {
		try {
			Image image = imageRepository.query(id);
			Region region = regionRepository.query(image.getRegion());
			CloudVendor cloudVendor = cloudVendorRepository.query(image.getVendorId());
			if (null != region) {
				image.setRegionName(region.getName());
			}
			if (null != cloudVendor) {
				image.setVendorName(cloudVendor.getName());
			}
			if (null != image.getTemplateId()) {
				CloudServer server = cloudServerRepository.query(image.getTemplateId());
				if (null != server) {
					List<NetworkCard> cards = networkCardRepository.listByHost(server.getId(), "VM");
					server.setNetcards(cards);
				}
				image.setServer(server);
			}
			if (!StringUtils.isEmpty(image.getTenantUuid())) {
				OSTenant osTenant = osTenantRepository.getByTenantUuid(image.getTenantUuid(), image.getVendorId());
				if (null != osTenant) {
					image.setOsTenantName(osTenant.getName());
				}
			}
			if (null != image.getResourceGroupId()) {
				Optional.ofNullable(resourceGroupRepository.query(image.getResourceGroupId()))
						.map(ResourceGroup::getName).ifPresent(image::setResourceGroupName);
			}
			return new BocloudResult<>(true, image, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

    @Override
    public BocloudResult remove(Long id, RequestContext context) {
        String path = Image.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            Image image = imageRepository.query(id);
            if (null == image) {
                logger.warn("image data not exist");
                return new BocloudResult<>(false, "数据不存在");
            }
            // 如果删除的是物理镜像
            if (null != image.getCatalog() && "PM".equals(image.getCatalog())) {
                imageRepository.remove(id, context.getTarget());
                return new BocloudResult<>(true, "删除物理镜像[" + image.getName() + "]成功");
            }
            CloudVendor vendor = cloudVendorRepository.query(image.getVendorId());
            new Thread(() -> {
                String operate = vendor.getType().toLowerCase() + ".image";
                String moduleName = CloudProvider.POWERVC.name().equals(vendor.getType()) ? "映像" : "镜像";
                try {
                    BocloudResult result = null;
                    CloudProvider type = CloudProvider.valueOf(vendor.getType());
                    switch (type) {
                        case OPENSTACK:
						case EASYSTACK:
                        case FUSIONCLOUD:
                        case MANAGEONE:
                        case POWERVC:
                        case TENCENT:
                        case AZURE:
                        case AWS:
                        case TCE:
                        case HUAWEI:
                        case HCSO:
                        case QCLOUD:
                        case PQCLOUD:
                        case TIANYI:
                        case ALIYUN:
                            result =
                                imageDriver.remove(image.getImageUuid(), vendor.getUuid(), image.getRegionId(), null);
                            break;
                        case VMWARE:
                            result = serverDriver.remove(image.getImageUuid(), image.getName(), vendor.getUuid(), null);
                            break;
                        case SMARTX:
                            if ("ISO".equals(image.getCatalog())) {
                                result = imageDriver.remove(image.getImageUuid(), vendor.getUuid(), null, null);
                            } else if ("VM".equals(image.getCatalog())) {
                                ServerTemplateModel paramModel = new ServerTemplateModel();
                                paramModel.setTemplateUuid(image.getImageUuid());
                                result = serverTemplateDriver.remove(vendor.getUuid(), null, paramModel);
                                if (result.isSuccess()) {
                                    String taskUuid = result.getData().toString();
                                    VendorTaskMsg taskMsg = smartTransporter.getTask(vendor, taskUuid, context.getTarget());
                                    result = new BocloudResult(taskMsg.getSmartSucceed(), taskMsg.getSmartFinalErrorMessage());
                                }
                            }
                            break;
                        default:
                            result = new BocloudResult<>(false, "暂不支持该平台");
                            break;
                    }
                    String content;
                    if (result.isSuccess()) {
                        imageRepository.remove(id, context.getTarget());
                        // 如果是镜像是VMware模板，删除模板以及相关表数据
                        if (CloudProvider.VMWARE.name().equals(type.name())) {
                            Long serverId = image.getTemplateId();
                            storeHostRepository.deleteByHost(serverId, "VM");
                            networkHostRepository.deleteByHost(serverId, "VM");
                            networkCardRepository.removeByHost(serverId, "VM", context.getTarget());
                            cloudServerRepository.remove(image.getTemplateId(), context.getTarget());
                        }
                        // 如果是镜像是Smart-X模板，删除模板以及相关表数据
                        if (CloudProvider.SMARTX.name().equals(type.name()) && "VM".equals(image.getCatalog())) {
                            CloudServer cloudServer = cloudServerRepository.getByInstanceId(image.getImageUuid());
                            cloudServerRepository.remove(cloudServer.getId(), context.getTarget());
                            networkCardRepository.removeByHost(cloudServer.getId(), "VM", context.getTarget());
                            serverVolumeRepository.removeBySid(cloudServer.getId());
                            serverImageRepository.removeBySid(cloudServer.getId());
                        }
                        if (CloudProvider.POWERVC.name().equals(type.name())) {
                            imageVolumeRepository.removeByImage(id);
                        }
                        if (null != context.getTenant() && 0L != context.getTenant()) {
                            objectRelationRepository.deleteByRid(id, ResourceCategory.Image.name());
                        }
                        result.setSuccess(true);
                        content = moduleName + "【" + image.getName() + "】删除成功!";
                    } else {
                        content = moduleName + "【" + image.getName() + "】删除失败!详情：" + result.getMessage();
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
                    // 发送给云平台统计队列对云平台重新统计
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put(Common.VENDORID, vendor.getId());
                    amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
                } catch (Exception e) {
                    logger.error("Get Message Exception:", e);
                    resourceEventPublisher.send(new OperateResult(false, "镜像【" + image.getName() + "】删除失败!", operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
                }
            }).start();
            return new BocloudResult<>(true, "删除任务已经下发，正在执行……");
        } catch (Exception e) {
            logger.error("remove image fail:", e);
            return new BocloudResult<>(false, "删除失败");
        }
    }

	@Override
	public BocloudResult modify(ImgBean bean, Long userId) {
		String path = Image.class.getSimpleName() + "_" + bean.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Image image = imageRepository.query(bean.getId());
			if (null == image) {
				logger.warn("image does not exist!");
				return new BocloudResult<>(false, "数据不存在!");
			}
			// 如果修改的是物理镜像
			if (null != image.getCatalog() && "PM".equals(image.getCatalog())) {
				image.setName(bean.getName());
				image.setRemark(bean.getRemark());
				image.setMenderId(userId);
				imageRepository.update(image);
				return new BocloudResult<>(true, "镜像修改成功");
			}
			CloudVendor vendor = cloudVendorRepository.query(image.getVendorId());
			if (null == vendor) {
				logger.error("get cloudVendor failure");
				return new BocloudResult<>(false, "镜像配置失败");
			}
			bean.setCatalog(image.getCatalog());
			bean.setImageLabel(image.getImageLabel());
			bean.setRegionId(image.getRegionId());
			bean.setVendorId(image.getVendorId());
			BeanUtils.copyProperties(bean, image);
			BocloudResult result = imageDriver.modify(vendor.getUuid(), image.getRegionId(),
					JSONObject.parseObject(JSONObject.toJSONString(image), ImageModel.class));
			if (null == result || result.isFailed()) {
				logger.error("imageDriver modify failure");
				return new BocloudResult<>(false, "镜像配置失败");
			}
			ImageModel model = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), ImageModel.class);
			model.setRemark(image.getRemark());
			BeanUtils.copyProperties(model, image);
			image.setMenderId(userId);
			if (StringUtils.isEmpty(image.getOsCategory())) {
				image.setOsCategory(bean.getOsCategory());
			}
			if (StringUtils.isEmpty(image.getOsName())) {
				image.setOsName(bean.getOsName());
			}
			imageRepository.update(image);
			return new BocloudResult<>(true, "镜像配置成功");
		} catch (Exception e) {
			logger.error("Modify image fail:", e);
			return new BocloudResult<>(false, "镜像配置失败", null, null);
		}
	}

	@Override
	public BocloudResult update(ImgBean bean, Long userId) {
		String path = Image.class.getSimpleName() + "_" + bean.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Image image = imageRepository.query(bean.getId());
			if (null == image) {
				logger.warn("image does not exist!");
				return new BocloudResult<>(false, "数据不存在!");
			}
			CloudVendor vendor = cloudVendorRepository.query(image.getVendorId());
			if (null != vendor && CloudProvider.MANAGEONE.name().equals(vendor.getType())
					&& "private".equals(image.getImageType())) {
				return new BocloudResult<>(false, "此镜像为私有镜像，不能用于公共镜像配置");
			}
			image.setImageLabel(bean.getImageLabel());
			image.setRemark(bean.getRemark());
			image.setMenderId(userId);
			imageRepository.update(image);
			return new BocloudResult<>(true, "镜像配置成功");
		} catch (Exception e) {
			logger.error("Modify image fail:", e);
			return new BocloudResult<>(false, "镜像配置失败");
		}
	}

	@Override
	public BocloudResult create(Image bean, RequestContext context) {
		try {
			// 创建物理机镜像
			if ("PM".equalsIgnoreCase(bean.getCatalog())) {
				if (this.imageRepository.exists(bean.getOsType(), bean.getOsVersion())) {
					logger.warn("physical image {} already exist", JSONObject.toJSONString(bean));
					return new BocloudResult<>(false, "添加镜像[" + bean.getName() + "]失败：镜像已经存在");
				}
				bean.preSave(context.getTarget(), context.getTarget(), null, 0L, context.getProject());
				imageRepository.save(bean);
				return new BocloudResult<>(true, "添加物理机镜像[" + bean.getName() + "]成功");
			}

            CloudVendor vendor = cloudVendorRepository.query(bean.getVendorId());
            if (null == vendor) {
                logger.error("get cloudVendor failure");
                return new BocloudResult<>(false, "平台不存在或已被删除");
            }
            String moduleName;
            if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
                moduleName = "映像";
            } else if (CloudProvider.SMARTX.name().equals(vendor.getType())) {
                moduleName = "ISO映像";
            } else {
                moduleName = "镜像";
            }
            String instanceId = null;
            CloudServer server = null;
            if (CloudProvider.HUAWEI.name().equals(vendor.getType())
            	|| CloudProvider.HCSO.name().equals(vendor.getType())
                || CloudProvider.MANAGEONE.name().equals(vendor.getType())) {
                server = cloudServerRepository.query(bean.getServerId());
                if (null == server) {
                    return new BocloudResult<>(false, "要转换的云主机不存在");
                }

				instanceId = server.getInstanceId();
				bean.setRegionId(server.getRegionId());
				bean.setId(null);
			}
			if (CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())) {
				if (bean.getServerId() != null) {
					server = cloudServerRepository.query(bean.getServerId());
					if (null == server) {
						return new BocloudResult<>(false, "要转换的云主机不存在");
					}
					if (!"STOPPED".equals(server.getStatus())) {
						return new BocloudResult<>(false, "该操作需要在关机状态下执行");
					}
					instanceId = server.getInstanceId();
					// 如果serverId不为空，说明是从云主机转化的镜像,这里加个字段值以便provider判断是哪种方式
					bean.setImageSource("makeImage");
					bean.setRegionId(server.getRegionId());
					bean.setId(null);
				} else if (bean.getServerId() == null && bean.getFilePath() != null) {
					// 如果serverId不为空，说明是从云主机转化的镜像,这里加个字段值以便provider判断是哪种方式
					bean.setImageSource("uploadImage");
				}

			}
			if (CloudProvider.TENCENT.name().equals(vendor.getType())
					|| CloudProvider.TCE.name().equals(vendor.getType())
					|| CloudProvider.QCLOUD.name().equals(vendor.getType())
					|| CloudProvider.PQCLOUD.name().equals(vendor.getType())
					|| CloudProvider.TIANYI.name().equals(vendor.getType())) {
				server = cloudServerRepository.query(bean.getId());
				if (null == server) {
					return new BocloudResult<>(false, "要转换的云主机不存在");
				}
				if ("RUNNING".equals(server.getStatus())) {
					return new BocloudResult<>(false, "该操作需要在关机状态下执行");
				}
				instanceId = server.getInstanceId();
				bean.setRegionId(server.getRegionId());
				bean.setId(null);
			}
			if (CloudProvider.AWS.name().equals(vendor.getType())) {
				server = cloudServerRepository.query(bean.getId());
				if (null == server) {
					return new BocloudResult<>(false, "要转换的云主机不存在");
				}
				instanceId = server.getInstanceId();
				bean.setRegionId(server.getRegionId());
				bean.setProjectId(0L);
				bean.setId(null);
			}
			if (CloudProvider.AZURE.name().equals(vendor.getType())) {
				server = cloudServerRepository.query(bean.getServerId());
				Assert.notNull(server, "要转换的云主机不存在");
				ResourceGroup resourceGroup = resourceGroupRepository.query(bean.getResourceGroupId());
				Assert.notNull(resourceGroup, "资源组不存在");
				instanceId = server.getInstanceId();
				bean.setRegionId(server.getRegionId());
				bean.setProjectId(0L);
				bean.setResourceGroupName(resourceGroup.getName());
				bean.setId(null);
			}
			if ((CloudProvider.OPENSTACK.name().equals(vendor.getType())
					|| CloudProvider.EASYSTACK.name().equals(vendor.getType()))
					&& (context.getCatalog().equals(Catalog.Tenant) || context.getCatalog().equals(Catalog.User))) {
				Long tenantId = context.getTenant();

				OSTenant osTenant = osTenantRepository.getByTenantId(tenantId, vendor.getId());
				if (null == osTenant) {
					return new BocloudResult<>(false, "当前租户关联OpenStack项目异常，请检查当前租户是否关联资源池");
				}
				bean.setOsTenantName(osTenant.getName());
				bean.setTenantId(tenantId);
				bean.setCreatorId(context.getTarget());
				bean.setMenderId(context.getTarget());
				bean.setOwnerId(context.getTarget());
			}
			if (CloudProvider.ALIYUN.name().equals(vendor.getType())) {
				server = cloudServerRepository.query(bean.getServerId());
				if (null == server) {
					return new BocloudResult(false, "要转换的云主机不存在");
				}
				List<Volume> volumes = volumeRepository.listByServerId(server.getId(), server.getVendorId(), true);
				if (ListTool.isEmpty(volumes)) {
					return new BocloudResult<>(false, "当前机器暂无系统盘，不允许创建镜像");
				}
				instanceId = volumes.get(0).getVolumeUuid();
				bean.setRegionId(server.getRegionId());
				bean.setId(null);
				bean.setImageType("PRIVATE");
				bean.setResourceGroupUuid(server.getResourceGroupUuid());
			}
			bean.setStatus(BocloudStatus.Server.BUILDING.name());
			bean.setCatalog("VM");
			if (null != server) {
				bean.setCreatorId(server.getCreatorId());
				bean.setTenantId(server.getTenantId());
				bean.setProjectId(server.getProjectId());
				bean.setMenderId(server.getMenderId());
			}
			ImageModel model = JSONObject.parseObject(JSONObject.toJSONString(bean), ImageModel.class);
			model.setInstanceId(instanceId);
			model.setInstanceUuid(instanceId);
			if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
				if (bean.getVolumes() == null || bean.getVolumes().size() == 0) {
					return new BocloudResult<>(false, "需要添加存储卷");
				}
				model.setDiskDeviceMappings(new ArrayList<>());
				for (Volume volume : bean.getVolumes()) {
					Volume volumeFromDB = volumeRepository.query(volume.getId());
					if (volumeFromDB == null) {
						return new BocloudResult<>(false, "未找到存储卷：" + volume.getId());
					}
					List<ServerVolume> serverVolumes = serverVolumeRepository.listByVolumeId(volume.getId());
					if (serverVolumes != null && serverVolumes.size() > 0) {
						return new BocloudResult<>(false, "存储卷：" + volumeFromDB.getName() + "已经附加到云主机");
					}
					List<ImageVolume> imageVolumes = imageVolumeRepository.listByVolume(volume.getId());
					if (imageVolumes != null && imageVolumes.size() > 0
							&& !volumeFromDB.getBootVolume().equals(volume.getBootVolume())) {
						return new BocloudResult<>(false,
								"存储卷：" + volumeFromDB.getName() + "已作为" + (volumeFromDB.getBootVolume() ? "引导卷" : "数据卷")
										+ "添加到其他映像，" + "不可再作为" + (volume.getBootVolume() ? "引导卷" : "数据卷") + "添加到当前映像");
					}
					VolumeModel volumeModel = new VolumeModel();
					BeanUtils.copyProperties(volumeFromDB, volumeModel);
					volumeModel.setBootVolume(volume.getBootVolume());
					model.getDiskDeviceMappings().add(volumeModel);
				}
			}
			if (!CloudProvider.POWERVC.name().equals(vendor.getType())) {
				imageRepository.save(bean);
			}
			final CloudServer cloudServer = server;
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".image";
				String content = moduleName + "创建失败";
				logger.info("image file path : " + storageConfig.getPath() + bean.getFilePath());
				model.setFilePath(storageConfig.getPath() + bean.getFilePath());
				BocloudResult result = imageDriver.create(vendor.getUuid(), bean.getOsTenantName(), bean.getRegionId(), model);
                try {
                    if (result.isSuccess()) {
                        content = moduleName + "创建成功";
                        if (CloudProvider.POWERVC.name().equals(vendor.getType())) {
                            ImageModel imageModel = (ImageModel)result.getData();
                            bean.setImageUuid(imageModel.getImageUuid());
                            bean.setRegionId(model.getRegionId());
                            imageRepository.update(bean);
                            powervcTransportor.insertOrUpdate(vendor, imageModel, context.getTarget());
                            // 更新卷“是否引导集”状态
                            for (Volume volume : bean.getVolumes()) {
                                Volume volumeFromDB = volumeRepository.query(volume.getId());
                                if (volumeFromDB != null) {
                                    volumeFromDB.setBootVolume(volume.getBootVolume());
                                    volumeRepository.update(volumeFromDB);
                                }
                            }
                        } else if (CloudProvider.SMARTX.name().equals(vendor.getType())) {
                            ImageModel imageModel = (ImageModel) result.getData();
                            smartTransporter.convert(imageModel, bean);
                            imageRepository.update(bean);
                        } else {
                            ImageModel imageModel =
                                JSONObject.parseObject(JSONObject.toJSONString(result.getData()), ImageModel.class);
                            imageModel.setRemark(bean.getRemark());
                            BeanUtils.copyProperties(imageModel, bean);
                            if (!CloudProvider.TENCENT.name().equals(vendor.getType())
                                && !CloudProvider.TCE.name().equals(vendor.getType())
                                && !CloudProvider.AWS.name().equals(vendor.getType())
                                && !CloudProvider.PQCLOUD.name().equals(vendor.getType())
                                && !CloudProvider.OPENSTACK.name().equals(vendor.getType())
								&& !CloudProvider.EASYSTACK.name().equals(vendor.getType())) {
                                bean.setStatus("ACTIVE");
                            }
                            bean.setVendorId(vendor.getId());
                            bean.setVendorType(vendor.getType());
//                            bean.setMinRam(new BigDecimal(imageModel.getMinRam()));
                            imageRepository.update(bean);
                            // 保存云主机操作
                            if (cloudServer != null) {
                                // fusioncloud上传镜像的时候 cloudserver是null， 不需要保存云主机操作事件
                                ResourceEvent event = new ResourceEvent(cloudServer.getId(), "创建镜像", "云主机创建镜像成功",
                                    context.getTarget(), new Date(), "VM", vendor.getId(), context.getCatalog());
                                resourceEventRepository.save(event);
                            }
                        }
                    } else {
                        logger.error("创建镜像失败：" + result.getMessage());
                        imageRepository.remove(bean.getId(), context.getTarget());
                        if (CloudProvider.TENCENT.name().equals(vendor.getType())
                            || CloudProvider.TCE.name().equals(vendor.getType())
                            || CloudProvider.TIANYI.name().equals(vendor.getType())
                            || CloudProvider.AWS.name().equals(vendor.getType())
                            || CloudProvider.PQCLOUD.name().equals(vendor.getType())
                            || CloudProvider.MANAGEONE.name().equals(vendor.getType())
                            || CloudProvider.ALIYUN.name().equals(vendor.getType())) {
                            content = result.getMessage();
                        }
                        if (cloudServer != null) {
                            // fusioncloud上传镜像的时候 cloudserver是null， 不需要保存云主机操作事件
                            ResourceEvent event = new ResourceEvent(cloudServer.getId(), "创建镜像", "云主机创建镜像失败",
                                context.getTarget(), new Date(), "VM", vendor.getId(), context.getCatalog());
                            resourceEventRepository.save(event);
                        }
                    }
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
                    // 发送给云平台统计队列对云平台重新统计
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put(Common.VENDORID, vendor.getId());
                    amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
                } catch (Exception e) {
                    logger.error("Get error message:", e);
                    try {
                        imageRepository.remove(bean.getId(), context.getTarget());
                    } catch (Exception e1) {
                        logger.error("Get error message:", e1);
                    }
                    content = result.getMessage();
                    resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
                        MapTools.simpleMap(Common.VENDORID, vendor.getId()),
                        OperateResult.OperateCategory.ResourceEvent, context));
                }
            }).start();
            return new BocloudResult<>(true, moduleName + "创建任务已下发，正在执行...");
        } catch (Exception e) {
            logger.error("create image error", e);
            return new BocloudResult<>(false, "添加失败");
        }
    }

	@Override
	public BocloudResult listByStoreId(Long storeId) {
		try {
			List<Image> list = imageRepository.listByStoreId(storeId);
			return new BocloudResult<>(true, list, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

	@Override
	public BocloudResult listByVendor(Long vendorId) {
		try {
			List<Image> list = imageRepository.listByVendorId(vendorId);
			return new BocloudResult<>(true, list, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

	@Override
	public BocloudResult listByTenant(String params, RequestContext context) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (null == object) {
			return new BocloudResult<>(false, "参数格式错误");
		}
		String osCategory = object.getString("osCategory");
		String osName = object.getString("osName");
		String osVersion = object.getString("osVersion");
		Long vendorId = object.getLong(Common.VENDORID);
		String region = object.getString("regionId");
		Boolean hasConfig = object.getBoolean("hasConfig");
		String regionId = object.getString("regionId");
		try {
			List<Image> images = imageRepository.listByTenant(vendorId, context.getTenant(), region);
			List<Image> filterImgs = Lists.newArrayList();
			// 筛选镜像
			for (Image image : images) {
				String imgLabel = image.getImageLabel();
				if (StringUtils.isEmpty(imgLabel)) {
					continue;
				}
				JSONObject imgLabelObj = JSONObject.parseObject(imgLabel);
				if (null != hasConfig && hasConfig && null != imgLabelObj) {
					if (!StringUtils.isEmpty(regionId) && !regionId.equalsIgnoreCase(image.getRegionId())) {
						continue;
					}
					filterImgs.add(image);
				} else if (null != imgLabelObj && null != osCategory && null != osName && null != osVersion
						&& osCategory.equals(imgLabelObj.getString("os_category"))
						&& osName.equals(imgLabelObj.getString("os_name"))
						&& osVersion.equals(imgLabelObj.getString("os_version"))) {
					if (!StringUtils.isEmpty(regionId) && !regionId.equalsIgnoreCase(image.getRegionId())) {
						continue;
					}
					filterImgs.add(image);
				}
			}
			// 前端取值 minSize
			for (Image image : filterImgs) {
				if (null == image.getMinDisk() || image.getMinDisk() <= 0) {
					image.setMinDisk(null == image.getSize() ? 0 : image.getSize().longValue());
				}
			}
			return new BocloudResult<>(true, filterImgs, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

	@Override
	public BocloudResult apply(String params, RequestContext context) {
		JSONObject object = JSONObject.parseObject(params);
		// 使用时长
		Integer months = object.getInteger("months");
		// 云平台ID
		Long vendorId = object.getLong(Common.VENDORID);
		// 申请人
		User applyUser = JSONObject.parseObject(object.getString("applyUser"), User.class);
		try {
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				logger.error("get cloudVendor failure");
				return new BocloudResult<>(false, "云平台不存在");
			}
			Image bean = JSONObject.parseObject(params, Image.class);
			Long serverId = bean.getServerId();
			CloudServer server = cloudServerRepository.query(serverId);
			String regionId = null;
			if (CloudProvider.HUAWEI.name().equals(vendor.getType())
					|| CloudProvider.HCSO.name().equals(vendor.getType())
					|| CloudProvider.MANAGEONE.name().equals(vendor.getType())
					|| CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())
					|| CloudProvider.AWS.name().equals(vendor.getType())) {
				if (null == server) {
					return new BocloudResult<>(false, vendor.getType().toUpperCase() + ".image", "云主机不存在！");
				}
				bean.setInstanceId(server.getInstanceId());
				bean.setRegionId(server.getRegionId());
				regionId = server.getRegionId();
			}
			if (CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())) {
				if (serverId != null) {
					if (null == server) {
						return new BocloudResult<>(false, "要转换的云主机不存在");
					}
					if (!"STOPPED".equals(server.getStatus())) {
						return new BocloudResult<>(false, "该操作需要在关机状态下执行");
					}
					// 如果serverId不为空，说明是从云主机转化的镜像,这里加个字段值以便provider判断是哪种方式
					bean.setImageSource("makeImage");
					bean.setInstanceId(server.getInstanceId());
					bean.setRegionId(server.getRegionId());
					regionId = server.getRegionId();
				} else if (bean.getServerId() == null && bean.getFilePath() != null) {
					// 如果serverId不为空，说明是从云主机转化的镜像,这里加个字段值以便provider判断是哪种方式
					bean.setImageSource("uploadImage");
				}
			}
			if (CloudProvider.QCLOUD.name().equals(vendor.getType())
					|| CloudProvider.TENCENT.name().equals(vendor.getType())
					|| CloudProvider.TCE.name().equals(vendor.getType())
					|| CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())) {
				if (null == server) {
					return new BocloudResult<>(false, vendor.getType().toUpperCase() + ".image", "云主机不存在！");
				}
				if ("RUNNING".equals(server.getStatus())) {
					return new BocloudResult<>(false, vendor.getType().toUpperCase() + ".image",
							"开机状态下的云主机不允许创建镜像，请关机！");
				}
				bean.setInstanceId(server.getInstanceId());
				bean.setRegionId(server.getRegionId());
				regionId = server.getRegionId();
			}
			bean.setStatus(BocloudStatus.Server.BUILDING.name());
			bean.setOwnerId(context.getTarget());
			bean.setCatalog("VM");
			imageRepository.save(bean);
			final String finalRegion = regionId;
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".image";
				String content = "申请创建镜像失败";
				bean.setFilePath(storageConfig.getPath() + bean.getFilePath());
				BocloudResult result = null;
				try {
					OSTenant osTenant = osTenantRepository.getByTenantId(context.getTenant(), vendor.getId());
					if (null == osTenant) {
						result = imageDriver.create(vendor.getUuid(), finalRegion,
								JSONObject.parseObject(JSONObject.toJSONString(bean), ImageModel.class));
					} else {
						result = imageDriver.create(vendor.getUuid(), osTenant.getName(), finalRegion,
								JSONObject.parseObject(JSONObject.toJSONString(bean), ImageModel.class));
					}
					if (result.isSuccess()) {
						content = "申请创建镜像成功";
						ImageModel imageModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
								ImageModel.class);
						imageModel.setRemark(bean.getRemark());
						String osCategory = null;
						String osVersion = null;
						String osName = null;
						if (CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())) {
							osCategory = bean.getOsCategory();
							osVersion = bean.getOsVersion();
							osName = bean.getOsName();
						}
						BeanUtils.copyProperties(imageModel, bean);
						bean.setStatus("ACTIVE");
						bean.setCreatorId(applyUser.getId());
						bean.setVendorId(vendor.getId());
						bean.setVendorType(vendor.getType());
						bean.setProjectId(context.getProject());
						bean.setTenantId(context.getTenant());
						if (!CloudProvider.FUSIONCLOUD.name().equals(vendor.getType())) {
							osCategory = imageModel.getOsCategory();
							osVersion = imageModel.getOsVersion();
							osName = imageModel.getOsName();
						}
						if (!StringUtils.isEmpty(osCategory) && !StringUtils.isEmpty(osVersion)
								&& !StringUtils.isEmpty(osName)) {
							JSONObject imageLabel = new JSONObject();
							imageLabel.put("os_category", osCategory);
							imageLabel.put("os_version", osVersion);
							imageLabel.put("os_name", osName);
							bean.setImageLabel(JSONObject.toJSONString(imageLabel));
						}
						imageRepository.update(bean);
						ObjectRelation relation = new ObjectRelation(context.getTarget(), bean.getId(), false,
								ResourceCategory.Image.name(), context.getCatalog().name(), 0);
						Calendar calendar = Calendar.getInstance();
						calendar.setTime(new Date());
						calendar.add(Calendar.MONTH, months);
						relation.setExpiredTime(calendar.getTime());
						objectRelationRepository.save(relation);
					} else {
						imageRepository.remove(bean.getId(), context.getTarget());
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
					// 站内信
					NotifyMessage message = new NotifyMessage(context, "云镜像申请", content, true, true);
					amqpTemplate.convertAndSend("event.notice.queue", message);
					// 发送给云平台统计队列对云平台重新统计
					JSONObject jsonObject = new JSONObject();
					jsonObject.put(Common.VENDORID, vendor.getId());
					amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
				} catch (Exception e) {
					// 更新订单状态
					cosInternalService.updateStatus(object.getLong("orderId"), "FAILURE", null, null);
					logger.error("Get error message:", e);
					try {
						imageRepository.remove(bean.getId(), context.getTarget());
					} catch (Exception e1) {
						logger.error("Get error message:", e1);
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
				}
			}).start();
			return new BocloudResult<>(true, "镜像申请创建任务已下发，正在执行...");
		} catch (Exception e) {
			// 更新订单状态
			cosInternalService.updateStatus(object.getLong("orderId"), "FAILURE", null, null);
			logger.error("create image error", e);
			return new BocloudResult<>(false, "镜像申请创建失败");
		}
	}

	@Override
	public BocloudResult updateExpriedTime(Long resId, Integer months, RequestContext context) {
		String path = Image.class.getSimpleName() + "_" + resId;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			ObjectRelation relation = objectRelationRepository.get(resId, ResourceCategory.Image.name());
			if (null == relation) {
				return new BocloudResult<>(false, "查织机构资源实体信息失败!");
			}
			BocloudResult<User> userResult = smsUserService.detail(relation.getTarget());
			if (userResult.isFailed()) {
				return new BocloudResult<>(false, "申请人不存在，云镜像延期失败");
			}
			User user = userResult.getData();
			if (null == user) {
				return new BocloudResult<>(false, "申请人不存在，云镜像延期失败");
			}
			Image image = imageRepository.query(resId);
			if (null == image) {
				return new BocloudResult<>(false, "云镜像不存在");
			}
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(relation.getExpiredTime());
			calendar.add(Calendar.MONTH, months);
			boolean flag = objectRelationRepository.updateExpriedTime(resId, calendar.getTime(),
					ResourceCategory.Image.name(), "USER");
			if (!flag) {
				return new BocloudResult<>(false, "云镜像延期失败!");
			}
			return new BocloudResult<>(true, "云镜像延期成功!");
		} catch (Exception e) {
			logger.error("update image expried time fail:", e);
			return new BocloudResult<>(false, "云镜像延期失败!");
		}
	}

	@Override
	public BocloudResult batchRemove(List<Long> ids, RequestContext context) {
		try {
			if (ids.isEmpty()) {
				return new BocloudResult<>(false, "没有需要删除的镜像！");
			}
			for (Long id : ids) {
				BocloudResult result = remove(id, context);
				if (result.isFailed()) {
					return result;
				}
			}
		} catch (Exception e) {
			logger.error("batch remove image fail:", e);
			return new BocloudResult<>(false, "批量删除任务下发失败");
		}
		return new BocloudResult<>(true, "批量删除任务已下发，正在执行...");
	}

	@Override
	public BocloudResult listByReg(String reg, Long vendorId) {
		try {
			List<Image> images = imageRepository.listByReg(reg, vendorId);
			return new BocloudResult<>(true, images, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult count(Long userId, Long projectId, Long tenantId) {
		try {
			List<Param> params = Lists.newArrayList();
			Catalog catalog = Catalog.Tenant;
			Long target = tenantId;
			if (null != userId) {
				target = userId;
				catalog = Catalog.User;
			}
			List<Project> projects = smsProjectService.projectsByCondition(target, catalog);
			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);
			}
			int total = this.imageRepository.count(params, 0L, projectIds);
			return new BocloudResult<>(true, total, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult imageExist(String osType, String osVersion) {
		try {
			if (this.imageRepository.exists(osType, osVersion)) {
				return new BocloudResult<>(true, "镜像已经存在");
			} else {
				return new BocloudResult<>(false, "镜像不存在");
			}
		} catch (Exception e) {
			logger.error("检查image是否存在异常:", e);
			return new BocloudResult<>(false, "检查image是否存在异常");
		}
	}

	@Override
	public BocloudResult remove(String osType, String osVersion, Long userId) {
		try {
			boolean success = this.imageRepository.deletePhysicalImage(osType, osVersion, userId);
			return new BocloudResult<>(success, success ? "删除物理镜像成功" : "删除物理镜像失败");
		} catch (Exception e) {
			logger.error("删除image异常:", e);
			return new BocloudResult<>(false, "删除物理机镜像异常");
		}
	}

	@Override
	public BocloudResult batchUpdate(BatchUpdateImageParam params, RequestContext context) {
		List<Long> ids = params.getIds();
		String imageLabel = params.getImageLabel();
		String remark = params.getRemark();
		try {
			List<BocloudResult> succResult = Lists.newArrayList();
			List<BocloudResult> failResult = Lists.newArrayList();
			for (Long id : ids) {
				ImgBean bean = new ImgBean();
				bean.setId(id);
				bean.setRemark(remark);
				bean.setImageLabel(imageLabel);
				BocloudResult result = update(bean, context.getTarget());
				if (result.isFailed()) {
					failResult.add(result);
				} else {
					succResult.add(result);
				}
			}
			return new BocloudResult<>(true, "批量保存成功【" + succResult.size() + "】个，失败【" + failResult.size() + "】个");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "批量保存失败");
		}
	}

	@Override
	public BocloudResult syncImages(String params, RequestContext context) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (object == null) {
			return new BocloudResult<>(false, "参数格式不正确");
		}
		try {
			Long vendorId = object.getLong(Common.VENDORID);
			Long imageId = object.getLong("imageId");
			String regions = object.getString("regions");
			List<String> regionList = JSONObject.parseArray(regions, String.class);
			if (null == regionList || regionList.size() <= 0) {
				return new BocloudResult<>(false, "地域信息有误！");
			}
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				logger.error("get cloudVendor failure");
				return new BocloudResult<>(false, "云供应商不存在");
			}
			Image image = imageRepository.query(imageId);
			if (!"ACTIVE".equals(image.getStatus())) {
				return new BocloudResult<>(false, "当前镜像状态不支持跨地域复制！");
			}
			if (image.getSize() > 50) {
				return new BocloudResult<>(false, "跨地域复制的镜像过大，应小于50GB！");
			}
			image.setStatus("SYNCING");
			imageRepository.update(image);
			String regionId = image.getRegionId();
			new Thread(() -> {
				String content = "镜像复制失败";
				String operate = vendor.getType().toLowerCase() + ".image";
				try {
					ImageModel imageModel = new ImageModel();
					imageModel.setImageUuids(new String[] { image.getImageUuid() });
					imageModel.setImageUuid(image.getImageUuid());

					for (String region : regionList) {
						imageModel.setName(image.getName());
						imageModel.setRegionId(region);
						BocloudResult bocloudResult = imageDriver.syncImages(vendor.getUuid(), regionId, imageModel);
						if (bocloudResult.isSuccess()) {
							ImageModel syncModel = JSONObject
									.parseObject(JSONObject.toJSONString(bocloudResult.getData()), ImageModel.class);
							// 插入新的镜像
							Image newimage = new Image();
							BeanUtils.copyProperties(image, newimage);
							newimage.setRegionId(region);
							newimage.setStatus("ACTIVE");
							newimage.setImageUuid(syncModel.getImageUuid());
							newimage.setId(null);
							imageRepository.save(newimage);
						}
					}
					content = "镜像跨域复制成功";
					image.setStatus("ACTIVE");
					imageRepository.update(image);
					resourceEventPublisher.send(new OperateResult(true, content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
				} catch (Exception e) {
					logger.error("Get error message:", e);
					resourceEventPublisher.send(new OperateResult(false, content, operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
				}
			}).start();
			return new BocloudResult<>(true, "镜像跨域复制，正在执行...");
		} catch (Exception e) {
			logger.error("create image error", e);
			return new BocloudResult<>(false, "镜像跨域复制失败");
		}
	}

	/**
	 * 镜像部分修改
	 *
	 * @param params
	 * @param context
	 * @return
	 */
	@Override
	public BocloudResult patch(Long id, JSONObject params, RequestContext context, String action) {
		if (null == action || "".equals(action)) {
			return new BocloudResult<>(false, "暂不支持此操作");
		}
		switch (action) {
		case "updateExpriedTime":
			return this.updateExpriedTime(id, params.getInteger("months"), context);
		case "syncImages":
			params.put("imageId", id);
			return this.syncImages(params.toJSONString(), context);
		case "shareImage":
			params.put("imageId", id);
			return this.shareImage(params.toJSONString(), context);
		case "update":
			ImgBean bean = JSONObject.parseObject(params.toJSONString(), ImgBean.class);
			bean.setId(id);
			return this.update(bean, context.getTarget());
		default:
			return new BocloudResult<>(false, "暂不支持此操作");
		}
	}

	/**
	 * 下载镜像
	 *
	 * @param id
	 * @return
	 */
	@Override
	public BocloudResult download(Long id) {
		try {
			Image image = imageRepository.query(id);
			if (null == image) {
				return new BocloudResult<>(false, "镜像不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(image.getVendorId());
			if (null == vendor) {
				return new BocloudResult<>(false, "云平台不存在");
			}
			String imageName = image.getName();
			if (StringUtils.isEmpty(imageName)) {
				imageName = IDFactory.instance().uuid() + ".img";
			} else {
				imageName = imageName.contains(".img") ? imageName : imageName + ".img";
			}
			BocloudResult result = imageDriver.download(vendor.getUuid(), null, null, image.getImageUuid(),
					storageConfig.getPath() + "/" + imageName);
			if (result.isFailed()) {
				return new BocloudResult<>(false, result.getMessage());
			}
			return new BocloudResult<>(true, result.getData(), "镜像下载成功");
		} catch (Exception e) {
			logger.error("Get error message：{}", e);
			return new BocloudResult<>(false, "镜像下载失败");
		}
	}

	@Override
	public BocloudResult shareImage(String params, RequestContext context) {
		JSONObject object = JSONTools.isJSONObj(params);
		if (object == null) {
			return new BocloudResult<>(false, "参数格式不正确");
		}
		// 获取传递的参数
		Long vendorId = object.getLong(Common.VENDORID);
		// 进行跨平台的vendorId 替换为账号id
		String account = object.getString("account");// 进行跨平台的vendorId
		Long imageId = object.getLong("imageId"); // 选中镜像的id
		// SHARE代表分享操作，CANCEL代表取消分享操作。
		String permission = object.getString("permission");
		try {
			// 判断平台是否存在
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				logger.error("get cloudVendor failure");
				return new BocloudResult<>(false, "云供应商不存在");
			}
			// 查询选中镜像的全部信息
			Image image = imageRepository.query(imageId);
			if (null == image) {
				return new BocloudResult<>(false, "镜像不存在！");
			}
			new Thread(new Runnable() {
				@Override
				public void run() {
					String info = "";
					if ("SHARE".equalsIgnoreCase(permission)) {
						info = "共享";
					} else if ("CANCEL".equalsIgnoreCase(permission)) {
						info = "取消共享";
					}
					String content = info + "操作失败";
					String operate = vendor.getType().toLowerCase() + ".image";
					try {
						ImageModel imageModel = new ImageModel();
						imageModel.setImageUuid(image.getImageUuid());
						imageModel.setAccountIds(new String[] { account });
						imageModel.setPermission(permission);
						BocloudResult bocloudResult = imageDriver.shareImage(vendor.getUuid(), image.getRegionId(),
								imageModel);
						if (bocloudResult.isSuccess()) {
							content = info + "操作成功";
						} else {
							content = bocloudResult.getMessage();
						}
						resourceEventPublisher.send(new OperateResult(bocloudResult.isSuccess(), content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					} catch (Exception e) {
						logger.error("镜像Error :", e);
						resourceEventPublisher.send(new OperateResult(false, content, operate,
								MapTools.simpleMap(Common.VENDORID, vendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					}
				}
			}).start();
			return new BocloudResult<>(true, "操作正在执行...");
		} catch (Exception e) {
			logger.error("share image fail:", e);
			return new BocloudResult<>(false, "镜像分享失败");
		}
	}

	@Override
	public BocloudResult<List<Volume>> listVolumeByImage(long imageId) {
		try {
			List<Volume> volumes = imageVolumeRepository.listVolumeByImage(imageId);
			return new BocloudResult<>(true, volumes, "查询成功");
		} catch (Exception e) {
			logger.error("查询失败", e);
			return new BocloudResult<>(false, "查询失败：" + e.getMessage());
		}
	}

    @Override
    public BocloudResult<GridBean<CloudServer>> listServerByImage(long imageId, Pager pager) {
        List<CloudServer> list = cloudServerRepository.listServerByImageId(imageId, pager);
        int count = cloudServerRepository.count(imageId, pager.getParams());
        GridBean<CloudServer> gridBean = new GridBean<>(pager.getPage(), pager.getRows(), count, list);
        return new BocloudResult<>(true, gridBean, "查询成功");
    }

	@Override
	public BocloudResult condition(String condition, RequestContext context) {
		condition = Optional.ofNullable(condition).orElse("");
		JSONObject object = JSONObject.parseObject(condition);
		if ("listByVendor".equalsIgnoreCase(object.getString("condition"))) {
			return this.listByVendor(object.getLong(Common.VENDORID));
		} else if ("listByStoreId".equalsIgnoreCase(object.getString("condition"))) {
			return this.listByStoreId(object.getLong("storeId"));
		} else if ("listByTenant".equalsIgnoreCase(object.getString("condition"))) {
			return this.listByTenant(condition, context);
		} else if ("listByReg".equalsIgnoreCase(object.getString("condition"))) {
			return this.listByReg(object.getString("reg"), object.getLong(Common.VENDORID));
		} else if ("count".equalsIgnoreCase(object.getString("condition"))) {
			return this.count(object.getLong("userId"), object.getLong("projectId"), object.getLong("tenantId"));
		} else if ("exist".equalsIgnoreCase(object.getString("condition"))) {
			return this.imageExist(object.getString("osType"), object.getString("osVersion"));
		} else if ("listByCondition".equalsIgnoreCase(object.getString("condition"))) {
			List<Image> images = imageRepository.listByCondition(object.getString("region"),
					object.getString("availablitiyZone"));
			return new BocloudResult<>(true, images, "查询成功");
		} else if ("listPublicImage".equalsIgnoreCase(object.getString("condition"))) {
			List<Image> images = imageRepository.listPublicImage(object.getLong("vendorId"));
			return new BocloudResult<>(true, images, "查询成功");
		} else if ("listByCategory".equalsIgnoreCase(object.getString("condition"))) {
			return listByCategory(object);
		} else if ("listTenantImages".equalsIgnoreCase(object.getString("condition"))) {
			return listTenantImages(object, context);
		} else if ("listsoftImages".equalsIgnoreCase(object.getString("condition"))) {
			return listSoftImages(object, context);
		} else if ("listTenantPublic".equalsIgnoreCase(object.getString("condition"))) {
			return listTenantPublic(object, context);
		} else if ("listByImageType".equalsIgnoreCase(object.getString("condition"))) {
			return listByImageType(condition, context);
		} else if ("listByService".equalsIgnoreCase(object.getString("condition"))) {
			return listByService(object);
		} else if ("listByFlavorId".equalsIgnoreCase(object.getString("condition"))) {
			return listByFlavorId(condition, context);
		}
		return new BocloudResult<>(false, "参数格式错误");
	}

	private BocloudResult listByFlavorId(String condition, RequestContext context) {
		try {
			JSONObject object = JSONObject.parseObject(condition);
			Long vendorId = object.getLong("vendorId");
			String regionId = null;
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult<>(false, "云平台信息不存在");
			}

			Long flavorId = object.getLong("flavorId");
			Flavor flavor = flavorRepository.query(flavorId);
			String flavorUuid = flavor.getFlavorUuid();


			List<Param> params = new ArrayList<>();
			params.add(new Param(MapTools.simpleMap("vendorId", vendorId), Sign.EQ));
			if (object.containsKey("status")) {
				params.add(new Param(MapTools.simpleMap("status", object.getString("status")), Sign.EQ));
			}
			if (object.containsKey("regionId")) {
				regionId = object.getString("regionId");
				params.add(new Param(MapTools.simpleMap("regionId", object.getString("regionId")), Sign.EQ));
			}
			if (object.containsKey("imageType")) {
				String imageType = object.getString("imageType");
				params.add(new Param(MapTools.simpleMap("imageType", imageType), Sign.EQ));
				if ("PRIVATE".equalsIgnoreCase(imageType)) {
					Catalog catalog = context.getCatalog();
					if (catalog.equals(Catalog.Tenant) || catalog.equals(Catalog.User)) {
						params.add(new Param(MapTools.simpleMap("tenantId", context.getTenant()), Sign.EQ));
					}
				}
			}

			List<Image> list = this.imageRepository.list(1,Integer.MAX_VALUE,params,null);

			BocloudResult bocloudResult = imageDriver.list(vendor.getUuid(), regionId, flavorUuid);
			if (bocloudResult.isSuccess() && bocloudResult.getData() != null){
				List<ImageModel> data = (List<ImageModel>) bocloudResult.getData();
				List<String> image = data.stream().map(ImageModel::getImageUuid).collect(Collectors.toList());
				list = list.stream().filter(e -> image.contains(e.getImageUuid())).collect(Collectors.toList());
			} else {
				logger.info("根据规格过滤镜像失败");
			}
			Map<String, List<Image>> imageMap = new HashMap<String, List<Image>>();
			for (Image image : list) {
				if (imageMap.containsKey(image.getOsType())) {
					List<Image> oldList = imageMap.get(image.getOsType());
					oldList.add(image);
					imageMap.put(image.getOsType(), oldList);
				} else {
					List<Image> newList = new ArrayList<Image>();
					newList.add(image);
					imageMap.put(image.getOsType(), newList);
				}
			}

			return new BocloudResult<>(true, imageMap, "查询成功!");
		} catch (Exception e) {
			logger.error("get image failure:", e);
			return new BocloudResult<>(false, "查询失败!");
		}
	}

	private BocloudResult listSoftImages(JSONObject object, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(object.getLong("vendorId"));
			if (null == vendor) {
				return new BocloudResult<>(false, "平台信息异常！");
			}
			String service = object.getString("service");
			List<Image> images = imageRepository.listByVendorId(vendor.getId());
			Map<String, List<Image>> imageMap = new HashMap<String, List<Image>>();
			for (Image img : images) {
				if (StringUtils.isEmpty(img.getImageLabel()) || !img.getImageLabel().contains(service)) {
					continue;
				}
				JSONObject labelObject = JSONObject.parseObject(img.getImageLabel(), JSONObject.class);
				String osCategory = labelObject.getString("osCategory");
				List<Image> list = imageMap.containsKey(osCategory) ? imageMap.get(osCategory) : new ArrayList<>();
				list.add(img);
				imageMap.put(osCategory, list);
			}
			if (imageMap.keySet().size() <= 0) {
				return new BocloudResult<>(false, "未找到合适的镜像!");
			}
			Set<String> osCategoryKeySet = imageMap.keySet();
			Map<String, List<String>> resultMap = new HashMap<>();
			for (String osCategroy : osCategoryKeySet) {
				List<String> versions = new ArrayList<>();
				List<Image> osCagetoryLists = imageMap.get(osCategroy);
				for (Image image : osCagetoryLists) {
					JSONObject labelObject = JSONObject.parseObject(image.getImageLabel(), JSONObject.class);
					String version = labelObject.getString("osVersion");
					if (!versions.contains(version)) {
						versions.add(version);
					}
				}
				resultMap.put(osCategroy, versions);
			}
			return new BocloudResult<>(true, resultMap, "查询成功！");
		} catch (Exception e) {
			logger.error("查询镜像失败：" + e.getMessage());
			return new BocloudResult<>(false, "查询镜像失败：" + e.getMessage());
		}
	}

	private BocloudResult listTenantImages(JSONObject object, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(object.getLong("vendorId"));
			if (null == vendor) {
				return new BocloudResult<>(false, "平台信息异常！");
			}
			String vendorType = vendor.getType();
			List<Image> images = imageRepository.listByVendorId(vendor.getId());
			if (vendor.getType().equals(CloudProvider.SANGFOR.name()) && "6.8".equals(vendor.getVersion())){
				images = images.stream()
						.filter(image -> image.getOsType().equals("cloudServerTemplate") &&
								object.getString("azUuid").equals(image.getAzUuid()))
						.collect(Collectors.toList());
			}
			Map<String, List<Image>> categoryMap = new HashMap<String, List<Image>>();
			for (Image img : images) {
				if (StringUtils.isEmpty(img.getImageLabel())) {
					continue;
				}
				JSONObject imageLabelObject = JSONObject.parseObject(img.getImageLabel(), JSONObject.class);
				// 是否与软件安装公用
				List<String> serviceTypes = JSONObject.parseArray(imageLabelObject.getString("servicesType"),
						String.class);
				if (!ListTool.isEmpty(serviceTypes) && !imageLabelObject.getBooleanValue("isShare")) {
					continue;
				}
				String osCategory = imageLabelObject.getString("osCategory");
				String osVersion = imageLabelObject.getString("osVersion");
				if(StringUtils.isEmpty(osCategory) || StringUtils.isEmpty(osVersion)) {
					continue;
				}
				List<Image> list = null;
				if (categoryMap.containsKey(osCategory)) {
					list = categoryMap.get(osCategory);
				} else {
					list = new ArrayList<>();
				}
				list.add(img);
				categoryMap.put(osCategory, list);
			}
			if (categoryMap.keySet().size() <= 0) {
				return new BocloudResult<>(false, "未找到合适的镜像!");
			}
			Long templateId;
			Set<String> osCategoryKeySet = categoryMap.keySet();
			Map<String, Object> resultMap = new HashMap<>();

			for (String osCategroy : osCategoryKeySet) {
				Map<String, List<Image>> osVersionMap = new HashMap<>();
				List<Image> osCagetoryLists = categoryMap.get(osCategroy);
				for (Image image : osCagetoryLists) {
					templateId = image.getTemplateId();
					JSONObject imageLabelObject = JSONObject.parseObject(image.getImageLabel(), JSONObject.class);
					List<Image> list = null;
					String osVersion = imageLabelObject.getString("osVersion");
					if (osVersionMap.containsKey(osVersion)) {
						list = osVersionMap.get(osVersion);
					} else {
						list = new ArrayList<>();
					}
					// 增加磁盘信息和网卡信息
					if (CloudProvider.FUSIONSPHERE.name().equals(vendorType)){
						List<Volume> volumes = volumeRepository.listByServerId(templateId);
						image.setVolumes(volumes);
						List<NetworkCard> networkCards = networkCardRepository.listByServerId(templateId);
						image.setNetworkCards(networkCards);
					}
                    if (CloudProvider.VMWARE.name().equals(vendorType) ||
                            CloudProvider.SMARTX.name().equals(vendorType)) {
						List<NetworkCard> cards = networkCardRepository.listByHost(templateId, "VM");
						image.setNetworkCards(cards);
                        CloudServer cloudServer = cloudServerRepository.query(templateId);
                        image.setTemplateName(cloudServer.getName());
                        image.setTemplateDisk(cloudServer.getDisk());
					}
					if (CloudProvider.SMARTX.name().equals(vendorType)) {
						List<ServerVolume> serverVolumes = serverVolumeRepository.listByServerId(templateId);
						List<Volume> volumes = volumeRepository.listVolumeByServerId(templateId);
						// 在SmartX中，模板中的云硬盘容量有可能不等于该云硬盘的实际容量，所以这里需要一个额外处理
						for (Volume volume : volumes) {
							for (ServerVolume serverVolume : serverVolumes) {
								if (serverVolume.getVolumeId().equals(volume.getId())) {
									volume.setBlockSize(1D);
									volume.setBlockCount(serverVolume.getVolumeSize());
									volume.setSize(serverVolume.getVolumeSizeGB());
									break;
								}
							}

						}
						image.setVolumes(volumes);
					}
					list.add(image);
					osVersionMap.put(osVersion, list);
				}
				resultMap.put(osCategroy, osVersionMap);
			}
			return new BocloudResult<>(true, resultMap, "查询成功！");
		} catch (Exception e) {
			logger.error("查询镜像失败：" + e.getMessage());
			return new BocloudResult<>(false, "查询镜像失败：" + e.getMessage());
		}
	}

	private BocloudResult listByService(JSONObject object) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(object.getLong("vendorId"));
			if (null == vendor) {
				return new BocloudResult<>(false, "平台信息异常！");
			}
			// 操作系统类型(Linux/Windows)
			String osCategory = object.getString("osCategory");
			// 操作系统版本
			String osVersion = object.getString("osVersion");
			// 中间件服务
			String serviceType = object.getString("serviceType");
			if (StringUtils.isEmpty(osCategory) || StringUtils.isEmpty(osVersion) || StringUtils.isEmpty(serviceType)) {
				return new BocloudResult<>(false, "参数格式错误！");
			}
			List<Image> images = imageRepository.listByVendorId(vendor.getId());
			Image targetImage = images.stream()
					.filter(image -> !StringUtils.isEmpty(image.getImageLabel())
							&& image.getImageLabel().contains(osCategory) && image.getImageLabel().contains(osVersion)
							&& image.getImageLabel().contains(serviceType))
					.findFirst().orElseThrow(() -> new Exception("未找到合适的镜像"));
			if (null == targetImage) {
				return new BocloudResult<>(false, "未找到合适的镜像!");
			}
			List<NetworkCard> cards = networkCardRepository.listByHost(targetImage.getTemplateId(), "VM");
			targetImage.setNetworkCards(cards);
			return new BocloudResult<>(true, targetImage, "查询成功！");
		} catch (Exception e) {
			logger.error("查询镜像失败：" + e.getMessage());
			return new BocloudResult<>(false, "查询镜像失败：" + e.getMessage());
		}
	}

	@Override
	public BocloudResult copy(Image bean, RequestContext context) {
		try {
			Image sourceImage = imageRepository.query(bean.getId());
			if (null == sourceImage) {
				return new BocloudResult(false, "要复制的镜像不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(sourceImage.getVendorId());
			if (null == vendor) {
				logger.error("get cloudVendor failure");
				return new BocloudResult(false, "平台不存在或已被删除");
			}
			bean.setId(null);
			bean.setImageType("PRIVATE");
			bean.setStatus(BocloudStatus.Server.BUILDING.name());
			bean.setCreatorId(context.getTarget());
			bean.setVendorId(vendor.getId());
			bean.setCatalog("VM");
			bean.setVendorType(vendor.getType());
			ImageModel model = JSONObject.parseObject(JSONObject.toJSONString(bean), ImageModel.class);
			model.setSourceImageId(sourceImage.getImageUuid());
			model.setSourceRegion(sourceImage.getRegionId());
			imageRepository.save(bean);
			final Image finalImage = sourceImage;
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".image";
				BocloudResult result = imageDriver.copy(model, vendor.getUuid(), bean.getRegionId());
				try {
					if (result.isSuccess()) {
						String regionId = bean.getRegionId();
						ImageModel imageModel = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
								ImageModel.class);
						imageModel.setRemark(bean.getRemark());
						BeanUtils.copyProperties(imageModel, bean);
						if (org.apache.commons.lang3.StringUtils.isBlank(bean.getRegionId())) {
							bean.setRegionId(regionId);
						}
						imageRepository.update(bean);
						// 保存操作
						ResourceEvent event = new ResourceEvent(finalImage.getId(), "复制镜像", "镜像复制成功",
								context.getTarget(), new Date(), "IMAGE", vendor.getId(), context.getCatalog());
						resourceEventRepository.save(event);
					} else {
						logger.error("复制镜像失败：" + result.getMessage());
						imageRepository.remove(bean.getId(), context.getTarget());
						ResourceEvent event = new ResourceEvent(finalImage.getId(), "复制镜像", "镜像复制失败",
								context.getTarget(), new Date(), "IMAGE", vendor.getId(), context.getCatalog());
						resourceEventRepository.save(event);
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
					// 发送给云平台统计队列对云平台重新统计
					JSONObject jsonObject = new JSONObject();
					jsonObject.put(Common.VENDORID, vendor.getId());
					amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
				} catch (Exception e) {
					logger.error("Get error message:", e);
					try {
						imageRepository.remove(bean.getId(), context.getTarget());
					} catch (Exception e1) {
						logger.error("Get error message:", e1);
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), "镜像复制失败", operate,
							MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
				}
			}).start();
			return new BocloudResult(true, "镜像复制任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("copy image error", e);
			return new BocloudResult(false, "镜像复制失败");
		}
	}
}