protected BackupStorageVO(BackupStorageVO vo) { this.setUuid(vo.getUuid()); this.setAttachedZoneRefs(vo.getAttachedZoneRefs()); this.setCreateDate(vo.getCreateDate()); this.setDescription(vo.getDescription()); this.setLastOpDate(vo.getLastOpDate()); this.setName(vo.getName()); this.setState(vo.getState()); this.setStatus(vo.getStatus()); this.setTotalCapacity(vo.getTotalCapacity()); this.setType(vo.getType()); this.setUrl(vo.getUrl()); this.setAvailableCapacity(vo.getAvailableCapacity()); }
private void checkResize() { if (originalCopy != null && capacityVO != null && originalCopy.getTotalCapacity() != 0 && originalCopy.getTotalCapacity() != capacityVO.getTotalCapacity()) { logger.debug(String.format("the capacity of backup storage[uuid:%s] changed from %s to %s, this indicates the backup storage is re-sized." + " We need to recalculate its capacity", capacityVO.getUuid(), originalCopy.getTotalCapacity(), capacityVO.getTotalCapacity())); // primary storage re-sized } }
private boolean lockCapacity() { if (backupStorageUuid != null) { capacityVO = dbf.getEntityManager().find(BackupStorageVO.class, backupStorageUuid, LockModeType.PESSIMISTIC_WRITE); } if (capacityVO != null) { totalForLog = capacityVO.getTotalCapacity(); availForLog = capacityVO.getAvailableCapacity(); originalCopy = new BackupStorageVO(); originalCopy.setAvailableCapacity(capacityVO.getAvailableCapacity()); originalCopy.setTotalCapacity(capacityVO.getTotalCapacity()); } return capacityVO != null; }
@Override public String getSyncSignature() { return String.format("connect-backup-storage-%s", self.getUuid()); }
protected BackupStorageInventory(BackupStorageVO vo) { this.setCreateDate(vo.getCreateDate()); this.setDescription(vo.getDescription()); this.setLastOpDate(vo.getLastOpDate()); this.setName(vo.getName()); this.setState(vo.getState().toString()); this.setStatus(vo.getStatus().toString()); this.setTotalCapacity(vo.getTotalCapacity()); this.setAvailableCapacity(vo.getAvailableCapacity()); this.setType(vo.getType()); this.setUrl(vo.getUrl()); this.setUuid(vo.getUuid()); this.attachedZoneUuids = new ArrayList<String>(vo.getAttachedZoneRefs().size()); for (BackupStorageZoneRefVO ref : vo.getAttachedZoneRefs()) { if (!this.attachedZoneUuids.contains(ref.getZoneUuid())) { this.attachedZoneUuids.add(ref.getZoneUuid()); } } }
final BackupStorageFactory factory = getBackupStorageFactory(type); BackupStorageVO vo = new BackupStorageVO(); if (msg.getResourceUuid() != null) { vo.setUuid(msg.getResourceUuid()); } else { vo.setUuid(Platform.getUuid()); vo.setUrl(msg.getUrl()); vo.setType(type.toString()); vo.setName(msg.getName()); vo.setDescription(msg.getDescription()); vo.setState(BackupStorageState.Enabled); vo.setStatus(BackupStorageStatus.Connecting); addBackupStoragestruct.setType(vo.getType()); cmsg.setNewAdd(true); cmsg.setBackupStorageUuid(inv.getUuid()); bus.makeTargetServiceIdByResourceUuid(cmsg, BackupStorageConstant.SERVICE_ID, vo.getUuid()); bus.send(cmsg, new CloudBusCallBack(msg) { @Override
@Transactional private void handle(ReturnBackupStorageMsg msg) { self = dbf.getEntityManager().find(BackupStorageVO.class, self.getUuid(), LockModeType.PESSIMISTIC_WRITE); long availSize = self.getAvailableCapacity() + msg.getSize(); if (availSize > self.getTotalCapacity()) { availSize = self.getTotalCapacity(); } self.setAvailableCapacity(availSize); dbf.getEntityManager().merge(self); bus.reply(msg, new ReturnBackupStorageReply()); }
@Transactional(readOnly = true) private List<PrimaryStorageVO> considerImageBackupStorageRef(PrimaryStorageAllocationSpec spec, List<PrimaryStorageVO> vos){ List<BackupStorageVO> bsvos = SQL.New("select bs" + " from BackupStorageVO bs, ImageBackupStorageRefVO ref" + " where ref.imageUuid = :imgUuid" + " and bs.uuid = ref.backupStorageUuid", BackupStorageVO.class) .param("imgUuid", spec.getImageUuid()) .list(); vos.removeIf(ps -> bsvos.stream().noneMatch(bs -> { List<String> relatedPsUuids = BackupStorageType.valueOf(bs.getType()).findRelatedPrimaryStorage(bs.getUuid()); return relatedPsUuids == null || relatedPsUuids.contains(ps.getUuid()); }) ); return vos; }
private BackupStorageMediator getBackupStorageMediator(String bsUuid) { BackupStorageVO bsvo = dbf.findByUuid(bsUuid, BackupStorageVO.class); BackupStorageMediator mediator = backupStorageMediators.get(bsvo.getType()); if (mediator == null) { throw new CloudRuntimeException(String.format("cannot find BackupStorageMediator for type[%s]", bsvo.getType())); } mediator.backupStorage = BackupStorageInventory.valueOf(bsvo); return mediator; }
protected void updateCapacity(Long totalCapacity, Long availableCapacity) { if (totalCapacity == null || availableCapacity == null) { return; } BackupStorageVO vo = dbf.findByUuid(self.getUuid(), BackupStorageVO.class); vo.setTotalCapacity(totalCapacity); vo.setAvailableCapacity(availableCapacity); dbf.update(vo); }
@Override public Void call() throws Exception { if (status == self.getStatus()) { completion.done(); return null; } changeStatus(status); logger.debug(String.format("backup storage[uuid:%s, name:%s] change status from %s to %s", self.getUuid(), self.getName(), self.getStatus(), status)); completion.done(); return null; } });
private void logCapacityChange() { if (logger.isTraceEnabled()) { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); int index = 0; String fileName = BackupStorageCapacityUpdater.class.getSimpleName() + ".java"; for (int i=0; i<stackTraceElements.length; i++) { if (fileName.equals(stackTraceElements[i].getFileName())) { index = i; } } StackTraceElement caller = stackTraceElements[index+1]; logger.trace(String.format("[Backup Storage Capacity] %s:%s:%s changed the capacity of the backup storage[uuid:%s] as:\n" + "total: %s --> %s\n" + "available: %s --> %s\n" , caller.getFileName(), caller.getMethodName(), caller.getLineNumber(), capacityVO.getUuid(), totalForLog, capacityVO.getTotalCapacity(), availForLog, capacityVO.getAvailableCapacity())); } }
@Override public void run(MessageReply reply) { if (reply.isSuccess()) { BackupStorageVO srcBS = dbf.findByUuid(self.getUuid(), BackupStorageVO.class); srcBS.setAvailableCapacity(srcBS.getAvailableCapacity() + spec.getSize()); dbf.update(srcBS); logger.info(String.format("Deleted image %s and returned space[size:%s] to BS[uuid:%s] after image migration", spec.getInstallPath(), spec.getSize(), self.getUuid())); trash.removeFromDb(spec.getTrashId()); result.setSize(spec.getSize()); result.setResourceUuids(CollectionDSL.list(spec.getResourceUuid())); completion.success(result); } else { logger.warn(String.format("Failed to delete image %s in image migration.", spec.getInstallPath())); completion.fail(reply.getError()); } } });
protected void exceptionIfImageSizeGreaterThanAvailableCapacity(String url) { if (CoreGlobalProperty.UNIT_TEST_ON) { return; } url = url.trim(); if (!url.startsWith("http") && !url.startsWith("https")) { return; } String len; try { HttpHeaders header = restf.getRESTTemplate().headForHeaders(URI.create(url)); len = header.getFirst("Content-Length"); } catch (Exception e) { throw new OperationFailureException(operr("cannot get image. The image url is %s. Exception is %s", url, e.toString())); } if (len == null) { return; } long size = Long.valueOf(len); if (size > self.getAvailableCapacity()) { throw new OperationFailureException(operr("the backup storage[uuid:%s, name:%s] has not enough capacity to download the image[%s]." + "Required size:%s, available size:%s", self.getUuid(), self.getName(), url, size, self.getAvailableCapacity())); } }
protected boolean changeStatus(BackupStorageStatus status) { if (status == self.getStatus()) { return false; } BackupStorageStatus oldStatus = self.getStatus(); self.setStatus(status); dbf.update(self); BackupStorageStatusChangedData d = new BackupStorageStatusChangedData(); d.setBackupStorageUuid(self.getUuid()); d.setNewStatus(status.toString()); d.setOldStatus(oldStatus.toString()); d.setInventory(BackupStorageInventory.valueOf(self)); evtf.fire(BackupStorageCanonicalEvents.BACKUP_STORAGE_STATUS_CHANGED, d); logger.debug(String.format("change backup storage[uuid:%s] status to %s", self.getUuid(), status)); return true; } }
@Transactional private boolean _update(Long total, Long avail) { if (!lockCapacity()) { logDeletedBackupStorage(); return false; } if (total != null) { capacityVO.setTotalCapacity(total); } if (avail != null) { capacityVO.setAvailableCapacity(avail); } merge(); return true; }
@Transactional private boolean reserve(String bsUuid, long size) { BackupStorageVO vo = dbf.getEntityManager().find(BackupStorageVO.class, bsUuid, LockModeType.PESSIMISTIC_WRITE); if (vo == null) { logger.warn(String.format("reservation failure, cannot find backup storage[uuid:%s]", bsUuid)); return false; } if (vo.getAvailableCapacity() < size) { logger.warn(String.format("reservation failure, cannot reserve capacity[%s bytes] on backup storage[uuid:%s]", size, bsUuid)); return false; } long avail = vo.getAvailableCapacity() - size; vo.setAvailableCapacity(avail); dbf.getEntityManager().merge(vo); logger.debug(String.format("reserve %s bytes on backup storage[uuid:%s, total capacity:%s, available capacity:%s]", size, bsUuid, vo.getTotalCapacity(), avail)); return true; }
@Transactional private boolean _decreaseAvailableCapacity(long size) { if (!lockCapacity()) { logDeletedBackupStorage(); return false; } capacityVO.setAvailableCapacity(capacityVO.getAvailableCapacity() - size); merge(); return true; }