diff --git a/src/main/kotlin/team/darkmoderap/aikon/domain/exchange/controller/ExchangeController.kt b/src/main/kotlin/team/darkmoderap/aikon/domain/exchange/controller/ExchangeController.kt new file mode 100644 index 0000000..bc940d3 --- /dev/null +++ b/src/main/kotlin/team/darkmoderap/aikon/domain/exchange/controller/ExchangeController.kt @@ -0,0 +1,29 @@ +package team.darkmoderap.aikon.domain.exchange.controller + +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestPart +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestController +import org.springframework.web.multipart.MultipartFile +import team.darkmoderap.aikon.domain.exchange.service.ExchangeFileService + +@RestController +@RequestMapping("/exchange") +class ExchangeController( + private val exchangeFileService: ExchangeFileService, +) { + @PostMapping("/upload", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) + @ResponseStatus(HttpStatus.NO_CONTENT) + fun uploadIncoming( + @RequestPart("file") file: MultipartFile, + ) { + exchangeFileService.uploadIncoming(file) + } + + @GetMapping("/outgoing", produces = [MediaType.IMAGE_PNG_VALUE]) + fun downloadOutgoing(): ByteArray = exchangeFileService.downloadOutgoing() +} diff --git a/src/main/kotlin/team/darkmoderap/aikon/domain/exchange/service/ExchangeFileService.kt b/src/main/kotlin/team/darkmoderap/aikon/domain/exchange/service/ExchangeFileService.kt new file mode 100644 index 0000000..20b386b --- /dev/null +++ b/src/main/kotlin/team/darkmoderap/aikon/domain/exchange/service/ExchangeFileService.kt @@ -0,0 +1,43 @@ +package team.darkmoderap.aikon.domain.exchange.service + +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.beans.factory.annotation.Value +import org.springframework.http.MediaType +import org.springframework.stereotype.Service +import org.springframework.web.multipart.MultipartFile +import software.amazon.awssdk.core.sync.RequestBody +import software.amazon.awssdk.services.s3.S3Client +import software.amazon.awssdk.services.s3.model.GetObjectRequest +import software.amazon.awssdk.services.s3.model.PutObjectRequest + +@Service +class ExchangeFileService( + @Qualifier("exchangeS3Client") private val s3Client: S3Client, + @Value("\${exchange.minio.bucket}") private val bucket: String, +) { + fun uploadIncoming( + file: MultipartFile, + fileName: String = "Aikon500.png", + ) { + val request = + PutObjectRequest + .builder() + .bucket(bucket) + .key("incoming/$fileName") + .contentType(file.contentType ?: MediaType.APPLICATION_OCTET_STREAM_VALUE) + .build() + + file.inputStream.use { s3Client.putObject(request, RequestBody.fromInputStream(it, file.size)) } + } + + fun downloadOutgoing(fileName: String = "report500.png"): ByteArray { + val request = + GetObjectRequest + .builder() + .bucket(bucket) + .key("outgoing/$fileName") + .build() + + return s3Client.getObjectAsBytes(request).asByteArray() + } +} diff --git a/src/main/kotlin/team/darkmoderap/aikon/global/config/ExchangeMinioConfig.kt b/src/main/kotlin/team/darkmoderap/aikon/global/config/ExchangeMinioConfig.kt new file mode 100644 index 0000000..239231f --- /dev/null +++ b/src/main/kotlin/team/darkmoderap/aikon/global/config/ExchangeMinioConfig.kt @@ -0,0 +1,27 @@ +package team.darkmoderap.aikon.global.config + +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider +import software.amazon.awssdk.regions.Region +import software.amazon.awssdk.services.s3.S3Client +import java.net.URI + +@Configuration +class ExchangeMinioConfig { + @Bean("exchangeS3Client") + fun exchangeS3Client( + @Value("\${exchange.minio.endpoint}") endpoint: String, + @Value("\${exchange.minio.access-key}") accessKey: String, + @Value("\${exchange.minio.secret-key}") secretKey: String, + ): S3Client = + S3Client + .builder() + .endpointOverride(URI.create(endpoint)) + .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey))) + .region(Region.US_EAST_1) + .forcePathStyle(true) + .build() +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0b02def..bef4a59 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -40,3 +40,10 @@ aws: endpoint: ${S3_ENDPOINT:} path-style-access-enabled: ${S3_PATH_STYLE_ACCESS_ENABLED:true} presigned-url-expiration-seconds: ${S3_PRESIGNED_URL_EXPIRATION_SECONDS:3600} + +exchange: + minio: + endpoint: ${EXCHANGE_MINIO_ENDPOINT:http://localhost:9000} + access-key: ${EXCHANGE_MINIO_ACCESS_KEY:exchange-partner} + secret-key: ${EXCHANGE_MINIO_SECRET_KEY:} + bucket: ${EXCHANGE_MINIO_BUCKET:exchange}