Я бы отделил создание FileSystem
, которое может перемещать файлы внутри одной и той же файловой системы, и создание, которое может делать это между файловыми системами.
Для простой реализации файловой системы, я бы создал sealed trait
с различными системами:
sealed trait FileSystem {
def moveFile(path: String)
}
object FileSystem {
class HDFSSystem extends FileSystem {
override def moveFile(path: String): Unit = ???
}
class S3FileSystem extends FileSystem {
override def moveFile(path: String): Unit = ???
}
def apply(path: String): Either[Throwable, FileSystem] = {
val properties: Properties = new Properties()
properties.load(
Source
.fromFile(s"${System.getProperty("user.dir")}\\src\\main\\resources\\$path")
.reader
)
val srcPath = properties.getProperty("srcPath")
val destPath = properties.getProperty("destPath")
if (!srcPath.equalsIgnoreCase(destPath))
Left(new Exception("Source and dest paths should be equal"))
else {
path.toLowerCase() match {
case s3 if s3.startsWith("s3") => Right(new S3FileSystem)
case hdfs if hdfs.startsWith("hdfs") => Right(new HDFSSystem)
case _ => Left(new Exception(s"Received unknown file system prefix: $path"))
}
}
}
}
Для многократной передачи файловой системы я бы использовал другую абстракцию, заключающую в себе FileSystem
. Вот эскиз:
abstract class MultiFileSystemTransfer[A <: FileSystem, B <: FileSystem](
val srcSystem: A,
val dstSystem: B
) {
def moveFile(srcPath: String, dstPath: String): Unit
}
object MultiFileSystemTransfer {
class S3ToS3FileSystemTransfer private
extends MultiFileSystemTransfer[FileSystem.S3FileSystem, FileSystem.S3FileSystem] {
override def moveFile(srcPath: String, dstPath: String): Unit = ???
}
}
Мы можем еще больше улучшить пути, которые на самом деле берутся из базовых файловых систем, предоставляемых с использованием Тип членов :
sealed trait FileSystem {
type Path
def moveFile(path: Path)
}
object FileSystem {
class HDFSSystem extends FileSystem {
type Path = String
override def moveFile(path: Path): Unit = ???
}
}
abstract class MultiFileSystemTransfer[A <: FileSystem, B <: FileSystem](
val srcSystem: A,
val dstSystem: B
) {
def moveFile(srcPath: srcSystem.Path, dstPath: dstSystem.Path): Unit
}
object MultiFileSystemTransfer {
class S3ToS3FileSystemTransfer(srcPath: FileSystem.S3FileSystem, dstPath: FileSystem.S3FileSystem)
extends MultiFileSystemTransfer[FileSystem.S3FileSystem, FileSystem.S3FileSystem](
srcPath,
dstPath
) {
override def moveFile(srcPath: srcSystem.Path, dstPath: dstSystem.Path): Unit = ???
}
}