public SnapshotLeaf buildRootLeaf(String uuid) { VolumeSnapshotVO s = dbf.findByUuid(uuid, VolumeSnapshotVO.class); SimpleQuery<VolumeSnapshotVO> q = dbf.createQuery(VolumeSnapshotVO.class); q.add(VolumeSnapshotVO_.treeUuid, Op.EQ, s.getTreeUuid()); List<VolumeSnapshotVO> vos = q.list(); VolumeSnapshotTree tree = VolumeSnapshotTree.fromVOs(vos); SnapshotLeaf leaf = tree.getRoot(); if (!leaf.getInventory().getUuid().equals(uuid)) { Assert.fail(String.format("snapshot[%s] is not root snapshot", uuid)); } return leaf; } }
private void walkDownLeaf(SnapshotLeaf leaf, List<VolumeSnapshotInventory> path, List<List<VolumeSnapshotInventory>> ret) { if (leaf.getChildren().isEmpty()) { List<VolumeSnapshotInventory> copy = new ArrayList<VolumeSnapshotInventory>(); copy.addAll(path); copy.add(leaf.getInventory()); ret.add(copy); return; } path.add(leaf.getInventory()); for (SnapshotLeaf l : leaf.getChildren()) { walkDownLeaf(l, path, ret); } path.remove(leaf.getInventory()); }
final List<VolumeSnapshotInventory> children = new ArrayList<VolumeSnapshotInventory>(); for (VolumeSnapshotTree t : p.snapshotTrees) { children.addAll(t.getRoot().getDescendants());
for (VolumeSnapshotInventory inv : currentLeaf.getDescendants()) { if (inv.isLatest()) { ancestorOfLatest = true;
currentLeaf.walkUp(new Function<Boolean, VolumeSnapshotInventory>() { @Override public Boolean call(VolumeSnapshotInventory arg) {
paramIn.setSnapshot(currentLeaf.getInventory()); paramIn.setImage(ImageInventory.valueOf(dbf.findByUuid(msg.getImageUuid(), ImageVO.class))); WorkflowTemplate workflowTemplate = ext.createTemplateFromVolumeSnapshot(paramIn); chain.setName(String.format("create-template-from-snapshot-%s-%s", currentLeaf.getInventory().getName(), currentLeaf.getUuid())); chain.putData( e(ParamIn.class, paramIn),
@Override public void run(FlowTrigger trigger, Map data) { ErrorCodeList errList = new ErrorCodeList(); new While<>(currentLeaf.getDescendants()).all((sp, whileCompletion) -> { Optional<VolumeSnapshotDeletionProtector> protector = pluginRgty.getExtensionList(VolumeSnapshotDeletionProtector.class).stream().filter(p -> p.getPrimaryStorageType().equals(primaryStorageType)) .findFirst();
changeStatusOfSnapshots(StatusEvent.ready, currentLeaf.getDescendants(), new Completion(msg, completion) { @Override public void success() {
List<VolumeSnapshotVO> vos = q.list(); VolumeSnapshotTree tree = VolumeSnapshotTree.fromVOs(vos); inv.setTree(tree.getRoot().toLeafInventory()); reply.setInventories(Arrays.asList(inv)); } else if (msg.getVolumeUuid() != null) { List<VolumeSnapshotVO> vos = sq.list(); VolumeSnapshotTree tree = VolumeSnapshotTree.fromVOs(vos); inv.setTree(tree.getRoot().toLeafInventory()); treeInventories.add(inv);
for (VolumeSnapshotInventory inv : currentLeaf.getDescendants()) { List<String> buuids = CollectionUtils.transformToList(inv.getBackupStorageRefs(), new Function<String, VolumeSnapshotBackupStorageRefInventory>() { @Override
@Override public void run(final FlowTrigger trigger, Map data) { final List<VolumeSnapshotPrimaryStorageDeletionMsg> pmsgs = CollectionUtils.transformToList(currentLeaf.getDescendants(), new Function<VolumeSnapshotPrimaryStorageDeletionMsg, VolumeSnapshotInventory>() { @Override public VolumeSnapshotPrimaryStorageDeletionMsg call(VolumeSnapshotInventory arg) {
public static VolumeSnapshotTree fromInventories(List<VolumeSnapshotInventory> invs) { VolumeSnapshotTree tree = new VolumeSnapshotTree(); Map<String, SnapshotLeaf> map = new HashMap<String, SnapshotLeaf>(); for (VolumeSnapshotInventory inv : invs) { SnapshotLeaf leaf = map.get(inv.getUuid()); if (leaf == null) { leaf = new SnapshotLeaf(); leaf.inventory = inv; map.put(inv.getUuid(), leaf); } else { leaf.inventory = inv; } if (inv.getParentUuid() != null) { SnapshotLeaf parent = map.get(inv.getParentUuid()); if (parent == null) { parent = new SnapshotLeaf(); parent.setUuid(inv.getParentUuid()); map.put(parent.getUuid(), parent); } parent.children.add(leaf); leaf.parent = parent; } else { tree.root = leaf; } tree.volumeUuid = inv.getVolumeUuid(); } DebugUtils.Assert(tree.root != null, "why tree root is null???"); return tree; }
@Override public void run(final FlowTrigger trigger, Map data) { MergeVolumeSnapshotOnPrimaryStorageMsg mmsg = new MergeVolumeSnapshotOnPrimaryStorageMsg(); VolumeSnapshotInventory from = currentLeaf.getParent() == null ? currentLeaf.getInventory() : currentLeaf.getParent().getInventory(); mmsg.setFrom(from); VolumeVO vol = dbf.findByUuid(currentRoot.getVolumeUuid(), VolumeVO.class); mmsg.setTo(VolumeInventory.valueOf(vol)); mmsg.setFullRebase(currentLeaf.getParent() == null); bus.makeTargetServiceIdByResourceUuid(mmsg, PrimaryStorageConstant.SERVICE_ID, currentRoot.getPrimaryStorageUuid()); bus.send(mmsg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { trigger.fail(reply.getError()); } else { trigger.next(); } } }); } });
@Override protected void scripts() { String psUuid = q(VolumeSnapshotVO.class) .select(VolumeSnapshotVO_.primaryStorageUuid) .eq(VolumeSnapshotVO_.uuid, currentRoot.getUuid()) .findValue(); if (psUuid != null) { ret.value = false; return; } // the snapshot is on neither primary storage, delete it and descendants List<String> uuids = currentLeaf.getDescendants().stream().map(VolumeSnapshotInventory::getUuid).collect(Collectors.toList()); if (!uuids.isEmpty()) { sql(VolumeSnapshotVO.class).in(VolumeSnapshotVO_.uuid, uuids).hardDelete(); } if (!q(VolumeSnapshotVO.class).eq(VolumeSnapshotVO_.treeUuid, currentRoot.getTreeUuid()).isExists()) { logger.debug(String.format("volume snapshot tree[uuid:%s] has no leaf, delete it", currentRoot.getTreeUuid())); sql(VolumeSnapshotTreeVO.class).eq(VolumeSnapshotTreeVO_.uuid, currentRoot.getTreeUuid()).hardDelete(); } ret.value = true; } }.execute();
public List<VolumeSnapshotInventory> getAncestors() { if (ancestors == null) { ancestors = new ArrayList<VolumeSnapshotInventory>(); walkUp(new Function<Boolean, VolumeSnapshotInventory>() { @Override public Boolean call(VolumeSnapshotInventory arg) { ancestors.add(arg); return false; } }); Collections.reverse(ancestors); } return ancestors; }
@Override public void rollback(final FlowRollback trigger, Map data) { changeStatusOfSnapshots(StatusEvent.ready, currentLeaf.getDescendants(), new Completion(trigger) { @Override public void success() { trigger.rollback(); } @Override public void fail(ErrorCode errorCode) { trigger.rollback(); } }); } });
private SnapshotLeaf walkDown(SnapshotLeaf leaf, Function<Boolean, VolumeSnapshotInventory> func) { if (func.call(leaf.inventory)) { return leaf; } if (leaf.getChildren().isEmpty()) { return null; } for (SnapshotLeaf l : leaf.getChildren()) { SnapshotLeaf ret = walkDown(l, func); if (ret != null) { return ret; } } return null; }
private void marshal(APIQueryVolumeSnapshotTreeReply reply) { if (reply.getInventories() == null) { // this is for count return; } for (VolumeSnapshotTreeInventory inv : reply.getInventories()) { SimpleQuery<VolumeSnapshotVO> sq = dbf.createQuery(VolumeSnapshotVO.class); sq.add(VolumeSnapshotVO_.treeUuid, Op.EQ, inv.getUuid()); List<VolumeSnapshotVO> vos = sq.list(); VolumeSnapshotTree tree = VolumeSnapshotTree.fromVOs(vos); inv.setTree(tree.getRoot().toLeafInventory()); } }
public void run(final FlowTrigger trigger, Map data) { changeStatusOfSnapshots(StatusEvent.delete, currentLeaf.getDescendants(), new Completion(trigger) { @Override public void success() { trigger.next(); } @Override public void fail(ErrorCode errorCode) { trigger.fail(errorCode); } }); }