Skip to content

Commit

Permalink
not working
Browse files Browse the repository at this point in the history
  • Loading branch information
Zwiterrion committed Nov 28, 2024
1 parent 7b42f37 commit dd39fe1
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 69 deletions.
1 change: 1 addition & 0 deletions daikoku/app/controllers/AssetsController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ class TeamAssetsController(
)
}
case None =>
println("HEHE")
NotFound(Json.obj("error" -> "Asset not found!"))
}
}
Expand Down
105 changes: 60 additions & 45 deletions daikoku/app/services/AssetsService.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package fr.maif.otoroshi.daikoku.services

import fr.maif.otoroshi.daikoku.actions.ApiActionContext
import fr.maif.otoroshi.daikoku.audit.AuditTrailEvent
import fr.maif.otoroshi.daikoku.ctrls.CmsApiActionContext
import fr.maif.otoroshi.daikoku.domain.{Asset, AssetId}
import fr.maif.otoroshi.daikoku.env.Env
import fr.maif.otoroshi.daikoku.logger.AppLogger
import fr.maif.otoroshi.daikoku.services.NormalizeSupport.normalize
import fr.maif.otoroshi.daikoku.utils.IdGenerator
import fr.maif.otoroshi.daikoku.utils.StringImplicits.BetterString
import org.apache.pekko.http.scaladsl.model.{ContentType, ContentTypes, HttpResponse}
import org.apache.pekko.http.scaladsl.util.FastFuture
import org.apache.pekko.stream.connectors.s3.ObjectMetadata
import org.apache.pekko.stream.scaladsl.{Sink, Source}
Expand Down Expand Up @@ -153,6 +152,10 @@ class AssetsService {
.flatMap(slug => if (slug.isEmpty) None else Some(slug))
val assetId = AssetId(IdGenerator.uuid)

println(contentType)

Future.successful(Ok(Json.obj()))

ctx.tenant.bucketSettings match {
case None =>
FastFuture.successful(
Expand Down Expand Up @@ -281,28 +284,29 @@ class AssetsService {
def listAssets[T](ctx: ApiActionContext[T])(implicit env: Env) = {
implicit val ec = env.defaultExecutionContext

ctx.request.getQueryString("teamId") match {
case Some(teamId) =>
ctx.tenant.bucketSettings match {
case None =>
FastFuture.successful(
NotFound(Json.obj("error" -> "No bucket config found !"))
)
case Some(cfg) =>
env.assetsStore.listTenantAssets(ctx.tenant.id)(cfg).map { res =>
Ok(JsArray(res.map(_.asJson)))
}
}
ctx.tenant.bucketSettings match {
case None =>
ctx.tenant.bucketSettings match {
case None =>
FastFuture.successful(
NotFound(Json.obj("error" -> "No bucket config found !"))
)
case Some(cfg) =>
env.assetsStore.listTenantAssets(ctx.tenant.id)(cfg).map { res =>
Ok(JsArray(res.map(_.asJson)))
}
FastFuture.successful(
NotFound(Json.obj("error" -> "No bucket config found !"))
)
case Some(cfg) =>
for {
slugs <- env.dataStore.assetRepo
.forTenant(ctx.tenant)
.findWithProjection(Json.obj(), Json.obj("slug" -> true, "_id" -> true))
.map(items => items.foldLeft(Map.empty[String, Option[String]]) { case (acc, item) =>
acc + ((item \ "_id").as[String] -> (item \ "slug").asOpt[String])
})
assets <- env.assetsStore.listTenantAssets(ctx.tenant.id)(cfg)
} yield {
Ok(JsArray(assets.map(item => {
val id = item.content.key.split("/").last

(slugs.get(id) match {
case Some(slug) => item.copy(slug = slug)
case None => item
}).asJson
})))
}
}
}
Expand Down Expand Up @@ -382,6 +386,7 @@ class AssetsService {
) = {
implicit val ec = env.defaultExecutionContext


ctx.tenant.bucketSettings match {
case None =>
FastFuture.successful(
Expand Down Expand Up @@ -415,28 +420,38 @@ class AssetsService {
case Some(_) if download =>
env.assetsStore
.getTenantAsset(ctx.tenant.id, AssetId(assetId))(cfg)
.map {
case None =>
NotFound(Json.obj("error" -> "Asset not found!"))
case Some((source, meta)) =>
val filename = meta.metadata
.filter(_.name().startsWith("x-amz-meta-"))
.find(_.name() == "x-amz-meta-filename")
.map(_.value())
.getOrElse("asset.txt")

Ok.sendEntity(
HttpEntity.Streamed(
source,
None,
meta.contentType
.map(Some.apply)
.getOrElse(Some("application/octet-stream"))
)
)
.withHeaders(
"Content-Disposition" -> s"""attachment; filename="$filename""""
)
.map { case (metadata, data, s3Source) =>

// case None =>
// NotFound(Json.obj("error" -> "Asset not found!"))
// case Some((source, meta)) =>
// val filename = meta.metadata
// .filter(_.name().startsWith("x-amz-meta-"))
// .find(_.name() == "x-amz-meta-filename")
// .map(_.value())
// .getOrElse("asset.txt")

// Ok.send(
val entity = org.apache.pekko.http.scaladsl.model.HttpEntity(
metadata.contentType
.flatMap(ContentType.parse(_).toOption)
.getOrElse(ContentTypes.`application/octet-stream`),
metadata.contentLength,
s3Source)

Ok.sendEntity(HttpEntity.Streamed(entity, None, None))

// )
// HttpEntity.Streamed(
// Source.single(source),
// None,
// meta.contentType
// .map(Some.apply)
// .getOrElse(Some("application/octet-stream"))
// )
// .withHeaders(
// "Content-Disposition" -> s"""attachment; filename="$filename""""
// )
}
case Some(url) =>
env.wsClient
Expand Down
99 changes: 75 additions & 24 deletions daikoku/app/utils/s3.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ package fr.maif.otoroshi.daikoku.utils
import com.amazonaws.auth.{AWSStaticCredentialsProvider, BasicAWSCredentials}
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import com.amazonaws.services.s3.model.PutObjectRequest
import com.amazonaws.{ClientConfiguration, HttpMethod, SdkClientException}
import fr.maif.otoroshi.daikoku.domain._
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.http.scaladsl.model.{
ContentType,
ContentTypes,
HttpHeader
}
import org.apache.pekko.http.scaladsl.model.{ContentType, ContentTypes, HttpHeader}
import org.apache.pekko.stream.Materializer
import org.apache.pekko.stream.connectors.s3.headers.CannedAcl
import org.apache.pekko.stream.connectors.s3.scaladsl.S3
Expand All @@ -35,7 +32,8 @@ class BadFileContentFromContentType()

case class S3ListItem(
content: ListBucketResultContents,
objectMetadata: ObjectMetadata
objectMetadata: ObjectMetadata,
slug: Option[String] = None
) {
def asJson: JsValue =
Json.obj(
Expand All @@ -57,7 +55,8 @@ case class S3ListItem(
objectMetadata.metadata
.filter(_.name().startsWith("x-amz-meta-"))
.map(h => (h.name().replace("x-amz-meta-", ""), JsString(h.value())))
)
),
"slug" -> slug
)
}

Expand Down Expand Up @@ -121,7 +120,9 @@ class AssetsDataStore(actorSystem: ActorSystem)(implicit
override def getRegion: Region = Region.of(conf.region)
},
listBucketApiVersion = ApiVersion.ListBucketVersion2
).withEndpointUrl(conf.endpoint)
)
.withEndpointUrl(conf.endpoint)
.withAccessStyle(AccessStyle.PathAccessStyle)
S3Attributes.settings(settings)
}

Expand All @@ -140,6 +141,7 @@ class AssetsDataStore(actorSystem: ActorSystem)(implicit
val ctype = ContentType
.parse(contentType)
.getOrElse(ContentTypes.`application/octet-stream`)

val meta = MetaHeaders(
Map(
"filename" -> name,
Expand All @@ -151,6 +153,14 @@ class AssetsDataStore(actorSystem: ActorSystem)(implicit
"content-type" -> ctype.value
)
)

lazy val opts = new ClientConfiguration()
lazy val endpointConfiguration =
new EndpointConfiguration(conf.endpoint, conf.region)
lazy val credentialsProvider = new AWSStaticCredentialsProvider(
new BasicAWSCredentials(conf.access, conf.secret)
)

val sink = S3
.multipartUpload(
bucket = conf.bucket,
Expand Down Expand Up @@ -278,7 +288,7 @@ class AssetsDataStore(actorSystem: ActorSystem)(implicit
contentType = ctype,
metaHeaders = meta,
cannedAcl = CannedAcl.Private, // CannedAcl.PublicRead
chunkingParallelism = 1
chunkingParallelism = 1,
)
.withAttributes(s3ClientSettingsAttrs)
content.toMat(sink)(Keep.right).run()
Expand Down Expand Up @@ -312,17 +322,24 @@ class AssetsDataStore(actorSystem: ActorSystem)(implicit
val attrs = s3ClientSettingsAttrs
S3.listBucket(conf.bucket, Some(s"/${tenant.value}/tenant-assets"))
.mapAsync(1) { content =>
val none: Option[ObjectMetadata] = None
S3.getObjectMetadata(conf.bucket, content.key)
.withAttributes(attrs)
.runFold(none)((_, opt) => opt)
.map {
case None =>
S3ListItem(
content,
ObjectMetadata(collection.immutable.Seq.empty[HttpHeader])
// S3.getObjectMetadata(conf.bucket, content.key)
// .withAttributes(s3ClientSettingsAttrs)
// .toMat(Sink.head)(Keep.both)
// .run()
// ._2
// .map(meta => S3ListItem(content, meta.getOrElse(ObjectMetadata(Seq.empty))))
val (metadataFuture, _dataFuture) = S3.getObject(
conf.bucket,
content.key
)
case Some(meta) => S3ListItem(content, meta)
.withAttributes(s3ClientSettingsAttrs)
.toMat(Sink.head)(Keep.both)
.run()

for {
metadata <- metadataFuture
} yield {
S3ListItem(content, metadata)
}
}
.withAttributes(attrs)
Expand All @@ -343,11 +360,45 @@ class AssetsDataStore(actorSystem: ActorSystem)(implicit

def getTenantAsset(tenant: TenantId, asset: AssetId)(implicit
conf: S3Configuration
): Future[Option[(Source[ByteString, NotUsed], ObjectMetadata)]] = {
val none: Option[(Source[ByteString, NotUsed], ObjectMetadata)] = None
S3.getObject(conf.bucket, s"/${tenant.value}/tenant-assets/${asset.value}")
.withAttributes(s3ClientSettingsAttrs)
.runFold(none)((opt, _) => opt)
): Future[(ObjectMetadata, ByteString, Source[ByteString, Future[ObjectMetadata]])] = {
// val none: Option[(Source[ByteString, NotUsed], ObjectMetadata)] = None

// val s3Source: Source[ByteString, Future[ObjectMetadata]] = S3.getObject(conf.bucket, s"/${tenant.value}/tenant-assets/${asset.value}")
// s3Source
val s3Source: Source[ByteString, Future[ObjectMetadata]] =
S3.getObject(conf.bucket, s"/${tenant.value}/tenant-assets/${asset.value}")

val (metadataFuture, dataFuture) =
s3Source.toMat(Sink.head)(Keep.both).run()

for {
m <- metadataFuture
d <- dataFuture
} yield {
(m, d, s3Source)
}

// val (meta, data) = S3.getObject(conf.bucket, s"/${tenant.value}/tenant-assets/${asset.value}")
// .withAttributes(s3ClientSettingsAttrs)
// .toMat(Sink.head)(Keep.both)
// .run()
//
// for {
// m <- meta
// d <- data
// } yield {
// (d, m)
// }

// S3.getObject(conf.bucket, s"/${tenant.value}/tenant-assets/${asset.value}")
// .withAttributes(s3ClientSettingsAttrs)
// .runFold(none) { case (meta, data) =>
//
// println(meta)
// println(data)
//
// meta
// }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ export const AssetsList = ({
header: translate('Title'),
meta: { style: { textAlign: 'left' } },
}),
columnHelper.accessor(row => row.slug || '--', {
header: translate('Slug'),
meta: { style: { textAlign: 'left' } },
}),
columnHelper.accessor(row => row.meta.desc || '--', {
header: translate('Description'),
meta: { style: { textAlign: 'left' } },
Expand Down
1 change: 1 addition & 0 deletions daikoku/javascript/src/types/tenant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ export interface IAsset {
contentType: string;
meta: { [key: string]: string };
link: string;
slug?: string;
}

export interface ITenantAdministration {
Expand Down

0 comments on commit dd39fe1

Please sign in to comment.