Newer
Older
/*
* This file is part of vospace-rest
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.oats.vospace;
import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.datamodel.NodeUtils;
import it.inaf.oats.vospace.exception.InvalidArgumentException;
import it.inaf.oats.vospace.exception.NodeBusyException;
import it.inaf.oats.vospace.persistence.NodeDAO.ShortNodeDescriptor;
import java.util.Optional;
import net.ivoa.xml.vospace.v2.Transfer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.CannotSerializeTransactionException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
@Service
@EnableTransactionManagement
public class CopyService extends AbstractNodeService {
@Autowired
private NodeBranchService nodeBranchService;
@Transactional(rollbackFor = {Exception.class}, isolation = Isolation.REPEATABLE_READ)
public String processCopyNodes(Transfer transfer, String jobId, User user) {
String sourcePath = URIUtils.returnVosPathFromNodeURI(transfer.getTarget(), authority);
// Get Destination Vos Path (it's in transfer direction)
String destinationPath = URIUtils.returnVosPathFromNodeURI(transfer.getDirection(), authority);
// Destination source to be returned, null if no copy was performed
String destinationCopyRoot = null;
this.validatePath(sourcePath);
this.validatePath(destinationPath);
if (sourcePath.equals(destinationPath)) {
return null;
try {
// check source branch for read and lock it
nodeBranchService.checkBranchForReadAndLock(sourcePath, jobId, user);
// Check destination
Optional<ShortNodeDescriptor> destShortNodeDescriptor
= nodeDao.getShortNodeDescriptor(destinationPath, user.getName(), user.getGroups());
if (destShortNodeDescriptor.isPresent()) {
this.validateDestinationContainer(destShortNodeDescriptor.get(), destinationPath);
destinationCopyRoot = destinationPath + "/" + NodeUtils.getNodeName(sourcePath);
} else {
// Check if parent exists
String destinationParentPath = NodeUtils.getParentPath(destinationPath);
Optional<ShortNodeDescriptor> destShortNodeDescriptorParent
= nodeDao.getShortNodeDescriptor(destinationParentPath, user.getName(), user.getGroups());
if (destShortNodeDescriptorParent.isPresent()) {
this.validateDestinationContainer(destShortNodeDescriptorParent.get(), destinationParentPath);
destinationCopyRoot = destinationPath;
} else {
throw new UnsupportedOperationException("Creation of destination upon copy not supported");
}
}
nodeDao.copyBranch(
sourcePath,
} catch (CannotSerializeTransactionException ex) {
// Concurrent transactions attempted to modify this set of nodes
throw new NodeBusyException(sourcePath);
}
return destinationCopyRoot;