Skip to content

Commit

Permalink
Merge pull request #21 from icerockdev/put-object-by-stream-request-body
Browse files Browse the repository at this point in the history
Added correct method to support putObject via inputStream
  • Loading branch information
oyakovlev authored Jul 25, 2024
2 parents dc5a432 + e67a355 commit c9d1ca3
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repositories {
}

// Append dependency
implementation("com.icerockdev:storage-service:0.7.0")
implementation("com.icerockdev:storage-service:0.8.0")
````

## Library usage
Expand Down
2 changes: 1 addition & 1 deletion storage-service/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ apply(plugin = "java")
apply(plugin = "kotlin")

group = "com.icerockdev"
version = "0.7.0"
version = "0.8.0"

val sourcesJar by tasks.registering(Jar::class) {
archiveClassifier.set("sources")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
package com.icerockdev.service.storage.preview

import com.icerockdev.service.storage.s3.IS3Storage
import com.icerockdev.service.storage.s3.dto.FileObjectDto
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.withContext
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -69,7 +69,11 @@ class PreviewService(
val preview = it.imageProcessor(it, imageBytes)
val dstKey = getPreviewName(srcKey, it)

storage.put(dstBucket, dstKey, preview)
storage.put(
dstBucket,
dstKey,
FileObjectDto(preview.inputStream().buffered(), preview.size.toLong())
)
}
} catch (e: PreviewException){
logger.error(e.localizedMessage, e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

package com.icerockdev.service.storage.s3

import com.icerockdev.service.storage.s3.dto.FileObjectDto
import com.icerockdev.service.storage.s3.policy.builder.PolicyBuilder
import com.icerockdev.service.storage.s3.policy.builder.PrincipalBuilder
import com.icerockdev.service.storage.s3.policy.builder.ResourceBuilder
import com.icerockdev.service.storage.s3.policy.builder.StatementBuilder
import com.icerockdev.service.storage.s3.policy.dto.Principal
import com.icerockdev.service.storage.s3.policy.dto.Resource
import com.icerockdev.service.storage.s3.policy.dto.Statement
import software.amazon.awssdk.core.ResponseInputStream
import software.amazon.awssdk.services.s3.S3Configuration
Expand Down Expand Up @@ -44,8 +44,11 @@ interface IS3Storage {

fun put(bucket: String, key: String, stream: InputStream, metadata: Map<String, String>? = null): Boolean

@Deprecated("Pointless method that simply wraps byteArray")
fun put(bucket: String, key: String, byteArray: ByteArray, metadata: Map<String, String>? = null): Boolean

fun put(bucket: String, key: String, file: FileObjectDto, metadata: Map<String, String>? = null): Boolean

fun copy(srcBucket: String, srcKey: String, dstBucket: String, dstKey: String): Boolean

/**
Expand All @@ -59,7 +62,11 @@ interface IS3Storage {

fun getBucketPolicy(bucket: String): String?

fun putBucketPolicy(bucket: String, confirmRemoveSelfBucketAccess: Boolean = false, configure: PolicyBuilder.() -> Unit): Boolean
fun putBucketPolicy(
bucket: String,
confirmRemoveSelfBucketAccess: Boolean = false,
configure: PolicyBuilder.() -> Unit
): Boolean

fun deleteBucketPolicy(bucket: String): Boolean

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package com.icerockdev.service.storage.s3

import com.icerockdev.service.storage.mime.MimeTypeDetector
import com.icerockdev.service.storage.s3.dto.FileObjectDto
import com.icerockdev.service.storage.s3.policy.builder.PolicyBuilder
import com.icerockdev.service.storage.s3.policy.builder.PrincipalBuilder
import com.icerockdev.service.storage.s3.policy.builder.ResourceBuilder
Expand Down Expand Up @@ -58,6 +59,7 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
.build()
)
} catch (e: NoSuchKeyException) {
logger.debug(e.localizedMessage, e)
null
}
}
Expand Down Expand Up @@ -125,6 +127,7 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
client.headBucket(HeadBucketRequest.builder().bucket(bucket).build())
true
} catch (e: NoSuchBucketException) {
logger.debug(e.localizedMessage, e)
false
}
}
Expand All @@ -139,11 +142,13 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
)
true
} catch (e: BucketAlreadyExistsException) {
logger.debug(e.localizedMessage, e)
false
} catch (e: BucketAlreadyOwnedByYouException) {
logger.debug(e.localizedMessage, e)
false
} catch (e: S3Exception) {
logger.error(e.localizedMessage, e)
logger.debug(e.localizedMessage, e)
false
}
}
Expand All @@ -153,6 +158,7 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
client.deleteBucket(DeleteBucketRequest.builder().bucket(bucket).build())
true
} catch (e: NoSuchBucketException) {
logger.debug(e.localizedMessage, e)
false
}
}
Expand All @@ -174,6 +180,7 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
)
true
} catch (e: NoSuchKeyException) {
logger.debug(e.localizedMessage, e)
false
}
}
Expand All @@ -182,6 +189,7 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
return put(bucket, key, stream.buffered(), metadata)
}

@Deprecated("Pointless method that simply wraps byteArray")
override fun put(bucket: String, key: String, byteArray: ByteArray, metadata: Map<String, String>?): Boolean {
val stream = byteArray.inputStream().buffered()
return put(bucket, key, stream, metadata)
Expand All @@ -202,6 +210,28 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
client.putObject(request, RequestBody.fromBytes(stream.readBytes()))
true
} catch (e: S3Exception) {
logger.debug(e.localizedMessage, e)
false
}
}

override fun put(bucket: String, key: String, file: FileObjectDto, metadata: Map<String, String>?): Boolean {

val request = PutObjectRequest.builder()
.bucket(bucket)
.key(key)
.acl(ObjectCannedACL.PUBLIC_READ)
.contentEncoding("UTF-8")
.contentType(MimeTypeDetector.detect(file.inputStream).toString())
.metadata(metadata ?: emptyMap())
.contentLength(file.size)
.build()

return try {
client.putObject(request, RequestBody.fromInputStream(file.inputStream, file.size))
true
} catch (e: S3Exception) {
logger.debug(e.localizedMessage, e)
false
}
}
Expand All @@ -219,8 +249,10 @@ class S3StorageImpl(private val client: S3Client, private val preSigner: S3Presi
client.copyObject(request)
true
} catch (e: NoSuchBucketException) {
logger.debug(e.localizedMessage, e)
false
} catch (e: NoSuchKeyException) {
logger.debug(e.localizedMessage, e)
false
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.icerockdev.service.storage.s3.dto

import java.io.BufferedInputStream

data class FileObjectDto(
val inputStream: BufferedInputStream,
val size: Long
)
9 changes: 4 additions & 5 deletions storage-service/src/test/kotlin/S3StorageTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.icerockdev.service.storage.mime.MimeTypeDetector
import com.icerockdev.service.storage.s3.IS3Storage
import com.icerockdev.service.storage.s3.S3StorageImpl
import com.icerockdev.service.storage.s3.minioConfBuilder
import com.icerockdev.service.storage.s3.dto.FileObjectDto
import com.icerockdev.service.storage.s3.policy.dto.ActionEnum
import com.icerockdev.service.storage.s3.policy.dto.EffectEnum
import com.icerockdev.service.storage.s3.policy.dto.Policy
Expand Down Expand Up @@ -253,15 +254,13 @@ class S3StorageTest {

val (jpgFileName, jpgStream) = getFile(FileType.JPG)
val mimeType = MimeTypeDetector.detect(jpgStream)
val jpgFileByteArray = jpgStream.readAllBytes()

jpgStream.close()
val fileSize = jpgStream.available().toLong()

// Check wrong cases
assertFalse(storage.objectExists(bucketName, jpgFileName))

// Put object to storage
assertTrue(storage.put(bucketName, jpgFileName, jpgFileByteArray.inputStream()))
assertTrue(storage.put(bucketName, jpgFileName, FileObjectDto(jpgStream.buffered(), fileSize)))

// Check object exist
assertTrue(storage.objectExists(bucketName, jpgFileName))
Expand All @@ -271,7 +270,7 @@ class S3StorageTest {
assertEquals("image/jpeg", mimeType.toString())
assertEquals(mimeType.toString(), jpgObject?.response()?.contentType())

assertEquals(jpgFileByteArray.size.toLong(), jpgObject?.response()?.contentLength())
assertEquals(fileSize, jpgObject?.response()?.contentLength())

assertTrue {
storage.deleteBucketWithObjects(bucketName)
Expand Down

0 comments on commit c9d1ca3

Please sign in to comment.