in server/src/main/java/com/epam/aidial/core/server/controller/ResourceOperationController.java [60:115]
public Future<?> move() {
context.getRequest()
.body()
.compose(buffer -> {
MoveResourcesRequest request;
try {
request = ProxyUtil.convertToObject(buffer, MoveResourcesRequest.class);
} catch (Exception e) {
log.error("Invalid request body provided", e);
throw new IllegalArgumentException("Can't initiate move resource request. Incorrect body provided");
}
String sourceUrl = request.getSourceUrl();
if (sourceUrl == null) {
throw new IllegalArgumentException("sourceUrl must be provided");
}
String destinationUrl = request.getDestinationUrl();
if (destinationUrl == null) {
throw new IllegalArgumentException("destinationUrl must be provided");
}
ResourceDescriptor source = ResourceDescriptorFactory.fromAnyUrl(sourceUrl, encryptionService);
ResourceDescriptor destination = ResourceDescriptorFactory.fromAnyUrl(destinationUrl, encryptionService);
if (!source.getType().equals(destination.getType())) {
throw new IllegalArgumentException("source and destination resources must be the same type");
}
if (source.getUrl().equals(destination.getUrl())) {
throw new IllegalArgumentException("source and destination resources cannot be the same");
}
Set<ResourceDescriptor> resources = Set.of(source, destination);
Map<ResourceDescriptor, Set<ResourceAccessType>> permissions =
accessService.lookupPermissions(resources, context);
if (!permissions.get(source).containsAll(ResourceAccessType.ALL)) {
throw new PermissionDeniedException("no read and write access to source resource");
}
if (!permissions.get(destination).contains(ResourceAccessType.WRITE)) {
throw new PermissionDeniedException("no write access to destination resource");
}
List<String> buckets = List.of(source.getBucketLocation(), destination.getBucketLocation());
return vertx.executeBlocking(() -> lockService.underBucketLocks(buckets, () -> {
resourceOperationService.moveResource(source, destination, request.isOverwrite());
return null;
}), false);
})
.onSuccess(ignore -> context.respond(HttpStatus.OK))
.onFailure(this::handleServiceError);
return Future.succeededFuture();
}