diff options
author | Kseniya Tomskikh <ktomskikh@driver.xyz> | 2018-10-17 17:02:58 +0800 |
---|---|---|
committer | Kseniya Tomskikh <ktomskikh@driver.xyz> | 2018-10-17 17:02:58 +0800 |
commit | 95c3aeecd7e6ad04ce8d216c09e779f5ca38aa6a (patch) | |
tree | dfc94f20d00c84f9dde120f065bfc9298bdff0dc /core-storage/src/main/scala/xyz/driver/core/storage/FileSystemBlobStorage.scala | |
parent | f5d0b038457ed9d01687f0949e22e08a6b116066 (diff) | |
parent | a43556851bf986b81351fc9f1ae5ba51bf21dc47 (diff) | |
download | driver-core-kseniya/typized-id.tar.gz driver-core-kseniya/typized-id.tar.bz2 driver-core-kseniya/typized-id.zip |
Merge branch 'master' into kseniya/typized-idkseniya/typized-id
Diffstat (limited to 'core-storage/src/main/scala/xyz/driver/core/storage/FileSystemBlobStorage.scala')
-rw-r--r-- | core-storage/src/main/scala/xyz/driver/core/storage/FileSystemBlobStorage.scala | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/core-storage/src/main/scala/xyz/driver/core/storage/FileSystemBlobStorage.scala b/core-storage/src/main/scala/xyz/driver/core/storage/FileSystemBlobStorage.scala new file mode 100644 index 0000000..e12c73d --- /dev/null +++ b/core-storage/src/main/scala/xyz/driver/core/storage/FileSystemBlobStorage.scala @@ -0,0 +1,82 @@ +package xyz.driver.core.storage + +import java.net.URL +import java.nio.file.{Files, Path, StandardCopyOption} + +import akka.stream.scaladsl.{FileIO, Sink, Source} +import akka.util.ByteString +import akka.{Done, NotUsed} + +import scala.collection.JavaConverters._ +import scala.concurrent.{ExecutionContext, Future} + +/** A blob store that is backed by a local filesystem. All objects are stored relative to the given + * root path. Slashes ('/') in blob names are treated as usual path separators and are converted + * to directories. */ +class FileSystemBlobStorage(root: Path)(implicit ec: ExecutionContext) extends BlobStorage { + + private def ensureParents(file: Path): Path = { + Files.createDirectories(file.getParent()) + file + } + + private def file(name: String) = root.resolve(name) + + override def uploadContent(name: String, content: Array[Byte]): Future[String] = Future { + Files.write(ensureParents(file(name)), content) + name + } + override def uploadFile(name: String, content: Path): Future[String] = Future { + Files.copy(content, ensureParents(file(name)), StandardCopyOption.REPLACE_EXISTING) + name + } + + override def exists(name: String): Future[Boolean] = Future { + val path = file(name) + Files.exists(path) && Files.isReadable(path) + } + + override def list(prefix: String): Future[Set[String]] = Future { + val dir = file(prefix) + Files + .list(dir) + .iterator() + .asScala + .map(p => root.relativize(p)) + .map(_.toString) + .toSet + } + + override def content(name: String): Future[Option[Array[Byte]]] = exists(name) map { + case true => + Some(Files.readAllBytes(file(name))) + case false => None + } + + override def download(name: String): Future[Option[Source[ByteString, NotUsed]]] = Future { + if (Files.exists(file(name))) { + Some(FileIO.fromPath(file(name)).mapMaterializedValue(_ => NotUsed)) + } else { + None + } + } + + override def upload(name: String): Future[Sink[ByteString, Future[Done]]] = Future { + val f = ensureParents(file(name)) + FileIO.toPath(f).mapMaterializedValue(_.map(_ => Done)) + } + + override def delete(name: String): Future[String] = exists(name).map { e => + if (e) { + Files.delete(file(name)) + } + name + } + + override def url(name: String): Future[Option[URL]] = exists(name) map { + case true => + Some(root.resolve(name).toUri.toURL) + case false => + None + } +} |