From 286a7bb05c6f21d1d10cc954d4b682778446410b Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Sun, 4 Aug 2024 19:41:45 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat=20:=20=EB=9E=8C=EB=8B=A4=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=ED=8A=B8=EB=A6=AC=EA=B1=B0=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 7 +++ .../photo/service/FaceDetectionService.java | 8 +++ .../service/FaceDetectionServiceImpl.java | 56 +++++++++++++++++++ .../umc/naoman/global/config/S3Config.java | 10 ++++ 4 files changed, 81 insertions(+) create mode 100644 src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java create mode 100644 src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java diff --git a/build.gradle b/build.gradle index 1d8ccbe0..1d80df4a 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,13 @@ dependencies { implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.0") implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3' implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + + //AWS lambda + implementation 'com.amazonaws:aws-java-sdk-lambda:1.12.767' + + //elasticSearch에 포함되어 있음. 추후 제거 예정 + implementation 'com.fasterxml.jackson.core:jackson-databind' + } tasks.named('test') { diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java new file mode 100644 index 00000000..4d22febe --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java @@ -0,0 +1,8 @@ +package com.umc.naoman.domain.photo.service; + +import java.util.List; + +public interface FaceDetectionService { + + void detectFaces(List nameList, Long shareGroupId); +} diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java new file mode 100644 index 00000000..831f1efd --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java @@ -0,0 +1,56 @@ +package com.umc.naoman.domain.photo.service; +import com.amazonaws.services.lambda.AWSLambda; +import com.amazonaws.services.lambda.model.InvokeRequest; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class FaceDetectionServiceImpl implements FaceDetectionService{ + @Value("${spring.lambda.function.name}") + private String lambdaFunctionName; + private final AWSLambda awsLambda; + private final ObjectMapper objectMapper = new ObjectMapper(); + @Getter + @Setter + @AllArgsConstructor + private class Body{ + private String name; + private Long shareGroupId; + } + @Getter + @Setter + @AllArgsConstructor + private class PayLoad{ + private Body body; + } + + @Override + public void detectFaces(List nameList, Long shareGroupId) { + nameList.forEach(name->invokeLambda(name,shareGroupId)); + } + + private void invokeLambda(String name, Long shareGroupId) { + InvokeRequest invokeRequest = createInvokeRequest(name, shareGroupId); + awsLambda.invoke(invokeRequest); + } + + private InvokeRequest createInvokeRequest(String name, Long shareGroupId) { + PayLoad payLoad = new PayLoad(new Body(name,shareGroupId)); + String lambdaPayload = null; + try { + lambdaPayload = objectMapper.writeValueAsString(payLoad); + } catch (JsonProcessingException e) { + throw new RuntimeException("Failed to create lambda payload"); + } + return new InvokeRequest() + .withFunctionName(lambdaFunctionName) + .withPayload(lambdaPayload); + } + +} diff --git a/src/main/java/com/umc/naoman/global/config/S3Config.java b/src/main/java/com/umc/naoman/global/config/S3Config.java index 87a51e2c..9788ba6c 100644 --- a/src/main/java/com/umc/naoman/global/config/S3Config.java +++ b/src/main/java/com/umc/naoman/global/config/S3Config.java @@ -2,6 +2,8 @@ import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.lambda.AWSLambda; +import com.amazonaws.services.lambda.AWSLambdaClientBuilder; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import org.springframework.beans.factory.annotation.Value; @@ -32,4 +34,12 @@ public AmazonS3 amazonS3() { .withCredentials(new AWSStaticCredentialsProvider(awsCredentialsProvider())) .build(); } + + @Bean + public AWSLambda awsLambda() { + return AWSLambdaClientBuilder.standard() + .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentialsProvider())) + .build(); + } } From d97a6c2bc8455aefb5abd0e7306da3c4a2499ba6 Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Sun, 4 Aug 2024 23:24:12 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat=20:=20aws=20labmda=20sdk=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index c3ef2775..2a0617fb 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,9 @@ dependencies { implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3' implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + //AWS lambda + implementation 'com.amazonaws:aws-java-sdk-lambda:1.12.767' + //elasticsearch implementation 'org.springframework.data:spring-data-elasticsearch' From e9005868b8dc71b4bf8113cda67406605c3068b1 Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Wed, 7 Aug 2024 17:45:43 +0900 Subject: [PATCH 03/11] =?UTF-8?q?refact=20:=20aws=20lambda=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EA=B2=BD=EB=A1=9C=20=EB=B0=94=EA=BF=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../naoman/domain/photo/service/FaceDetectionServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java index 831f1efd..8b6a053f 100644 --- a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java @@ -12,7 +12,7 @@ @Service @RequiredArgsConstructor public class FaceDetectionServiceImpl implements FaceDetectionService{ - @Value("${spring.lambda.function.name}") + @Value("${spring.lambda.function.detect_face}") private String lambdaFunctionName; private final AWSLambda awsLambda; private final ObjectMapper objectMapper = new ObjectMapper(); From 94de986d7f586767d913686b5428241f19fd6d86 Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Wed, 7 Aug 2024 18:07:23 +0900 Subject: [PATCH 04/11] =?UTF-8?q?feat=20:=20=EB=9E=8C=EB=8B=A4=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20payload=EB=A7=8C=EB=93=A4=20=EB=95=8C=20class->json?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=ED=99=98=20=EC=8B=9C=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/error/code/AwsLambdaErrorCode.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/com/umc/naoman/global/error/code/AwsLambdaErrorCode.java diff --git a/src/main/java/com/umc/naoman/global/error/code/AwsLambdaErrorCode.java b/src/main/java/com/umc/naoman/global/error/code/AwsLambdaErrorCode.java new file mode 100644 index 00000000..3816f2be --- /dev/null +++ b/src/main/java/com/umc/naoman/global/error/code/AwsLambdaErrorCode.java @@ -0,0 +1,16 @@ +package com.umc.naoman.global.error.code; + +import com.umc.naoman.global.error.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum AwsLambdaErrorCode implements ErrorCode { + AWS_JsonProcessing_Exception(500, "EA000", "AWS Lambda JsonProcessingException 발생"), + ; + + private final int status; + private final String code; + private final String message; +} From 79aa6f6439c36bb1806fdf50e7451b532584a722 Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Wed, 7 Aug 2024 18:07:41 +0900 Subject: [PATCH 05/11] =?UTF-8?q?refact=20:=20=EC=96=BC=EA=B5=B4=20?= =?UTF-8?q?=EA=B0=90=EC=A7=80=20=EB=9E=8C=EB=8B=A4=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=97=AC=EB=9F=AC=EA=B0=9C=EB=A5=BC=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B2=83=EC=97=90=EC=84=9C=20=EB=8C=80?= =?UTF-8?q?=ED=91=9C=20=EB=9E=8C=EB=8B=A4=EB=A5=BC=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/FaceDetectionServiceImpl.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java index 8b6a053f..c7a4cb53 100644 --- a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java @@ -3,6 +3,8 @@ import com.amazonaws.services.lambda.model.InvokeRequest; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.umc.naoman.global.error.BusinessException; +import com.umc.naoman.global.error.code.AwsLambdaErrorCode; import lombok.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -13,44 +15,41 @@ @RequiredArgsConstructor public class FaceDetectionServiceImpl implements FaceDetectionService{ @Value("${spring.lambda.function.detect_face}") - private String lambdaFunctionName; + private String detectFaceDummyLambda; private final AWSLambda awsLambda; private final ObjectMapper objectMapper = new ObjectMapper(); + @Getter @Setter @AllArgsConstructor - private class Body{ - private String name; - private Long shareGroupId; + private class PayLoad{ + private Body body; } + @Getter @Setter @AllArgsConstructor - private class PayLoad{ - private Body body; + private class Body{ + private List nameList; + private List memberIdList; + private Long shareGroupId; } @Override public void detectFaces(List nameList, Long shareGroupId) { - nameList.forEach(name->invokeLambda(name,shareGroupId)); - } - - private void invokeLambda(String name, Long shareGroupId) { - InvokeRequest invokeRequest = createInvokeRequest(name, shareGroupId); - awsLambda.invoke(invokeRequest); - } - - private InvokeRequest createInvokeRequest(String name, Long shareGroupId) { - PayLoad payLoad = new PayLoad(new Body(name,shareGroupId)); + List memberIdList = null; //TODO: shareGroupId로 memberIdList 조회하는 로직 추가 + PayLoad payLoad = new PayLoad(new Body(nameList,memberIdList,shareGroupId)); String lambdaPayload = null; + try { lambdaPayload = objectMapper.writeValueAsString(payLoad); } catch (JsonProcessingException e) { - throw new RuntimeException("Failed to create lambda payload"); + throw new BusinessException(AwsLambdaErrorCode.AWS_JsonProcessing_Exception,e); } - return new InvokeRequest() - .withFunctionName(lambdaFunctionName) + InvokeRequest invokeRequest = new InvokeRequest() + .withFunctionName(detectFaceDummyLambda) .withPayload(lambdaPayload); - } + awsLambda.invoke(invokeRequest); + } } From 9b7bcc23ff874af9887bbaeacd23d6f1eb770ec3 Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Wed, 7 Aug 2024 18:21:59 +0900 Subject: [PATCH 06/11] =?UTF-8?q?feat=20:=20=EB=B9=84=EB=8F=99=EA=B8=B0=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=B4=20AsyncConfig=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/naoman/global/config/AsyncConfig.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/com/umc/naoman/global/config/AsyncConfig.java diff --git a/src/main/java/com/umc/naoman/global/config/AsyncConfig.java b/src/main/java/com/umc/naoman/global/config/AsyncConfig.java new file mode 100644 index 00000000..5f760c59 --- /dev/null +++ b/src/main/java/com/umc/naoman/global/config/AsyncConfig.java @@ -0,0 +1,25 @@ +package com.umc.naoman.global.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +@EnableAsync +@Configuration +public class AsyncConfig implements AsyncConfigurer { + + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(10); + executor.setMaxPoolSize(20); + executor.setQueueCapacity(30); + executor.setKeepAliveSeconds(30); + executor.setThreadNamePrefix("async-"); + executor.initialize(); + return executor; + } +} \ No newline at end of file From 6bf05905e9ee839594a0d88fc7cd940767e26825 Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Wed, 7 Aug 2024 18:24:00 +0900 Subject: [PATCH 07/11] =?UTF-8?q?feat=20:=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EC=8B=9C=20=EC=82=AC=EC=A7=84=EC=97=90=EC=84=9C=20=EC=96=BC?= =?UTF-8?q?=EA=B5=B4=20=EC=9D=B8=EC=8B=9D=ED=95=98=EB=8A=94=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EB=B9=84=EB=8F=99=EA=B8=B0=ED=95=A8?= =?UTF-8?q?=EC=88=98=EB=A1=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/naoman/domain/photo/service/FaceDetectionService.java | 2 +- .../naoman/domain/photo/service/FaceDetectionServiceImpl.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java index 4d22febe..74cf77a5 100644 --- a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java @@ -4,5 +4,5 @@ public interface FaceDetectionService { - void detectFaces(List nameList, Long shareGroupId); + void detectFace(List nameList, Long shareGroupId); } diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java index c7a4cb53..391e8e5a 100644 --- a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java @@ -7,6 +7,7 @@ import com.umc.naoman.global.error.code.AwsLambdaErrorCode; import lombok.*; import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.List; @@ -36,7 +37,8 @@ private class Body{ } @Override - public void detectFaces(List nameList, Long shareGroupId) { + @Async + public void detectFace(List nameList, Long shareGroupId) { List memberIdList = null; //TODO: shareGroupId로 memberIdList 조회하는 로직 추가 PayLoad payLoad = new PayLoad(new Body(nameList,memberIdList,shareGroupId)); String lambdaPayload = null; From 42a46535634aac491713d95cecca12f7b6daf1da Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Sat, 10 Aug 2024 15:51:55 +0900 Subject: [PATCH 08/11] =?UTF-8?q?=20feat=20:=20=EC=83=88=EB=A1=9C=EC=9A=B4?= =?UTF-8?q?=20=EB=A7=B4=EB=B2=84=EA=B0=80=20=EC=83=88=EB=A1=9C=EC=9A=B4=20?= =?UTF-8?q?=EA=B7=B8=EB=A3=B9=EC=97=90=20=EC=B0=B8=EC=97=AC=ED=96=88?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C,=20=ED=95=B4=EB=8B=B9=20=EB=A7=B4?= =?UTF-8?q?=EB=B2=84=20=ED=83=9C=EA=B7=B8=ED=95=98=EB=8A=94=20=EB=9E=8C?= =?UTF-8?q?=EB=8B=A4=20=ED=98=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/FaceVectorRepository.java | 9 --- .../repository/PhotoEsRepository.java | 9 --- .../SampleFaceVectorRepository.java | 9 --- .../photo/service/FaceDetectionService.java | 3 +- .../service/FaceDetectionServiceImpl.java | 56 ++++++++++++++----- 5 files changed, 44 insertions(+), 42 deletions(-) delete mode 100644 src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/FaceVectorRepository.java delete mode 100644 src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsRepository.java delete mode 100644 src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/SampleFaceVectorRepository.java diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/FaceVectorRepository.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/FaceVectorRepository.java deleted file mode 100644 index e0a52c7d..00000000 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/FaceVectorRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.umc.naoman.domain.photo.elasticsearch.repository; - -import com.umc.naoman.domain.photo.elasticsearch.document.FaceVector; -import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface FaceVectorRepository extends ElasticsearchRepository { -} diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsRepository.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsRepository.java deleted file mode 100644 index e081d3be..00000000 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.umc.naoman.domain.photo.elasticsearch.repository; - -import com.umc.naoman.domain.photo.elasticsearch.document.PhotoEs; -import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface PhotoEsRepository extends ElasticsearchRepository { -} diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/SampleFaceVectorRepository.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/SampleFaceVectorRepository.java deleted file mode 100644 index 98a866d9..00000000 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/SampleFaceVectorRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.umc.naoman.domain.photo.elasticsearch.repository; - -import com.umc.naoman.domain.photo.elasticsearch.document.SampleFaceVector; -import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface SampleFaceVectorRepository extends ElasticsearchRepository { -} diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java index 74cf77a5..0d66aaf3 100644 --- a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionService.java @@ -4,5 +4,6 @@ public interface FaceDetectionService { - void detectFace(List nameList, Long shareGroupId); + void detectFaceUploadPhoto(List photoNameList, Long shareGroupId); + void detectFaceJoinShareGroup(Long memberId, Long shareGroupId); } diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java index 391e8e5a..66fae004 100644 --- a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java @@ -1,8 +1,11 @@ package com.umc.naoman.domain.photo.service; import com.amazonaws.services.lambda.AWSLambda; +import com.amazonaws.services.lambda.model.InvocationType; import com.amazonaws.services.lambda.model.InvokeRequest; +import com.amazonaws.services.lambda.model.InvokeResult; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.umc.naoman.domain.shareGroup.service.ShareGroupService; import com.umc.naoman.global.error.BusinessException; import com.umc.naoman.global.error.code.AwsLambdaErrorCode; import lombok.*; @@ -11,36 +14,40 @@ import org.springframework.stereotype.Service; import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class FaceDetectionServiceImpl implements FaceDetectionService{ - @Value("${spring.lambda.function.detect_face}") - private String detectFaceDummyLambda; + @Value("${spring.lambda.function.detect_face_photo}") + private String detectFacePhotoLambda; + @Value("${spring.lambda.function.join_share_group}") + private String detectFaceShareGroupLambda; private final AWSLambda awsLambda; private final ObjectMapper objectMapper = new ObjectMapper(); + private final ShareGroupService shareGroupService; @Getter - @Setter @AllArgsConstructor - private class PayLoad{ - private Body body; + private class DetectFacePhotoPayload { + private List nameList; + private List memberIdList; + private Long shareGroupId; } @Getter - @Setter @AllArgsConstructor - private class Body{ - private List nameList; - private List memberIdList; + private class DetectFaceShareGroupPayload { + private Long memberId; private Long shareGroupId; } @Override - @Async - public void detectFace(List nameList, Long shareGroupId) { - List memberIdList = null; //TODO: shareGroupId로 memberIdList 조회하는 로직 추가 - PayLoad payLoad = new PayLoad(new Body(nameList,memberIdList,shareGroupId)); + public void detectFaceUploadPhoto(List photoNameList, Long shareGroupId) { + List memberIdList = shareGroupService.findProfileListByShareGroupId(shareGroupId).stream() + .map(profile -> profile.getMember().getId()) + .collect(Collectors.toList()); + DetectFacePhotoPayload payLoad = new DetectFacePhotoPayload(photoNameList,memberIdList,shareGroupId); String lambdaPayload = null; try { @@ -49,9 +56,30 @@ public void detectFace(List nameList, Long shareGroupId) { throw new BusinessException(AwsLambdaErrorCode.AWS_JsonProcessing_Exception,e); } InvokeRequest invokeRequest = new InvokeRequest() - .withFunctionName(detectFaceDummyLambda) + .withInvocationType(InvocationType.Event) + .withFunctionName(detectFacePhotoLambda) .withPayload(lambdaPayload); awsLambda.invoke(invokeRequest); } + + @Override + public void detectFaceJoinShareGroup(Long memberId, Long shareGroupId) { + DetectFaceShareGroupPayload payLoad = new DetectFaceShareGroupPayload(memberId,shareGroupId); + String lambdaPayload = null; + + try { + lambdaPayload = objectMapper.writeValueAsString(payLoad); + } catch (JsonProcessingException e) { + throw new BusinessException(AwsLambdaErrorCode.AWS_JsonProcessing_Exception,e); + } + InvokeRequest invokeRequest = new InvokeRequest() + .withInvocationType(InvocationType.Event) + .withFunctionName(detectFaceShareGroupLambda) + .withPayload(lambdaPayload); + + awsLambda.invoke(invokeRequest); + } + + } From 864a1c8898a7c01e7a521d600fc1045906fbddfe Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Sat, 10 Aug 2024 15:54:23 +0900 Subject: [PATCH 09/11] =?UTF-8?q?fix=20:=20=EC=82=AC=EC=A7=84=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=8B=9C=20rds=20id=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=90=98=EB=A1=9D=20=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/PhotoEsClientRepository.java | 28 ++++++++++--------- .../elasticsearch/service/PhotoEsService.java | 4 --- .../service/PhotoEsServiceImpl.java | 13 --------- 3 files changed, 15 insertions(+), 30 deletions(-) delete mode 100644 src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsService.java delete mode 100644 src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsServiceImpl.java diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsClientRepository.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsClientRepository.java index d78fa7dd..da92b187 100644 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsClientRepository.java +++ b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/repository/PhotoEsClientRepository.java @@ -6,6 +6,7 @@ import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.Hit; import com.umc.naoman.domain.photo.elasticsearch.document.PhotoEs; +import com.umc.naoman.domain.photo.entity.Photo; import com.umc.naoman.global.error.BusinessException; import com.umc.naoman.global.error.code.ElasticsearchErrorCode; import lombok.RequiredArgsConstructor; @@ -27,23 +28,24 @@ public class PhotoEsClientRepository { private final ElasticsearchClient elasticsearchClient; //사진 업로드 시 ES에 벌크로 업로드 - public void savePhotoBulk(List url, List nameList, Long shareGroupId) { - List photoEsList = new ArrayList<>(); - for(int i=0; i photoList) { + List photoEsList = photoList.stream() + .map(photo -> PhotoEs.builder() + .rdsId(photo.getId()) + .shareGroupId(photo.getShareGroup().getId()) + .faceTag(new ArrayList<>()) + .downloadTag(new ArrayList<>()) + .url(photo.getUrl()) + .name(photo.getName()) + .createdAt(esTimeFormat(photo.getCreatedAt())) + .build()) + .toList(); BulkRequest.Builder bulkBuilder = new BulkRequest.Builder(); for(PhotoEs photoEs :photoEsList){ bulkBuilder.operations(op ->op .index(idx -> idx .index("photos_es") - .routing(shareGroupId.toString()) + .routing(photoEs.getShareGroupId().toString()) .document(photoEs) ) ); @@ -84,7 +86,7 @@ public Page findPhotoEsByShareGroupId(Long shareGroupId, Pageable pagea } //특정 공유 그룹의 얼굴이 태그된 사진 검색 - public Page findPhotoEsByShareGroupIdAndFaceTag(Long shareGroupId,Long faceTag, Pageable pageable) throws IOException{ + public Page findPhotoEsByShareGroupIdAndFaceTag(Long shareGroupId,Long faceTag, Pageable pageable) { SearchResponse response = null; try{ response = elasticsearchClient.search(s->s diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsService.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsService.java deleted file mode 100644 index 0e52701a..00000000 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.umc.naoman.domain.photo.elasticsearch.service; - -public interface PhotoEsService { -} diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsServiceImpl.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsServiceImpl.java deleted file mode 100644 index 1b465064..00000000 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/service/PhotoEsServiceImpl.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.umc.naoman.domain.photo.elasticsearch.service; - -import com.umc.naoman.domain.photo.elasticsearch.repository.FaceVectorRepository; -import com.umc.naoman.domain.photo.elasticsearch.repository.PhotoEsRepository; -import com.umc.naoman.domain.photo.service.PhotoService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class PhotoEsServiceImpl implements PhotoEsService { - -} From db5da69b0cb1694ac64e68306917d8cbcd71981d Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Sat, 10 Aug 2024 15:55:55 +0900 Subject: [PATCH 10/11] =?UTF-8?q?refact=20:=20=EC=97=98=EB=9D=BC=EC=8A=A4?= =?UTF-8?q?=ED=8B=B1=EC=84=9C=EC=B9=98=20=EC=9D=B8=EB=8D=B1=EC=8A=A4=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../photo/elasticsearch/document/FaceVector.java | 9 +-------- .../domain/photo/elasticsearch/document/PhotoEs.java | 10 +--------- .../photo/elasticsearch/document/SampleFaceVector.java | 5 ----- .../domain/photo/elasticsearch/index/face_vectors.json | 4 ++-- .../domain/photo/elasticsearch/index/photos_es.json | 4 +++- .../elasticsearch/index/sample_photo_vectors.json | 4 ++-- 6 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/FaceVector.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/FaceVector.java index a5f8adb4..b05afbe3 100644 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/FaceVector.java +++ b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/FaceVector.java @@ -15,16 +15,9 @@ @Builder @NoArgsConstructor @AllArgsConstructor -@Document(indexName = "face_vectors") public class FaceVector { - @Id - private String id; - @Field(type = FieldType.Long) private String shareGroupId; - @Field(type = FieldType.Keyword) - private String keyValue; - @Field(type = FieldType.Date) + private String name; private String date; - @Field(type = FieldType.Dense_Vector) private List faceVector; } diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/PhotoEs.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/PhotoEs.java index e4a6478d..3e3642bb 100644 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/PhotoEs.java +++ b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/PhotoEs.java @@ -13,20 +13,12 @@ @Builder @NoArgsConstructor @AllArgsConstructor -@Document(indexName = "photos_es") public class PhotoEs { - @Id - private String id; - @Field(type = FieldType.Long) + private Long rdsId; private Long shareGroupId; - @Field(type = FieldType.Keyword) private String url; - @Field(type = FieldType.Keyword) private String name; - @Field(type = FieldType.Date) private String createdAt; - @Field(type = FieldType.Long) private List faceTag; - @Field(type = FieldType.Long) private List downloadTag; } diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/SampleFaceVector.java b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/SampleFaceVector.java index 51b35ca5..0f61323b 100644 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/SampleFaceVector.java +++ b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/document/SampleFaceVector.java @@ -15,12 +15,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -@Document(indexName = "sample_face_vectors") public class SampleFaceVector { - @Id - private String id; - @Field(type = FieldType.Long) private Long memberId; - @Field(type = FieldType.Dense_Vector) private List faceVector; } diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/face_vectors.json b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/face_vectors.json index b36b48dc..ba1a9280 100644 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/face_vectors.json +++ b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/face_vectors.json @@ -14,7 +14,7 @@ "shareGroupId" : { "type" : "long" }, - "keyValue" : { + "name" : { "type" : "keyword" }, "createdAt" : { @@ -23,7 +23,7 @@ }, "faceVector" : { "type": "dense_vector", - "dims": 128, + "dims": 512, "index": true, "similarity" : "dot_product" } diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/photos_es.json b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/photos_es.json index c1525e96..906f6dda 100644 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/photos_es.json +++ b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/photos_es.json @@ -1,4 +1,3 @@ - { "settings" : { "index" :{ @@ -12,6 +11,9 @@ "required" : true }, "properties" : { + "rdsId" : { + "type" : "long" + }, "shareGroupId" : { "type" : "long" }, diff --git a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/sample_photo_vectors.json b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/sample_photo_vectors.json index ceb7f512..a034dc13 100644 --- a/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/sample_photo_vectors.json +++ b/src/main/java/com/umc/naoman/domain/photo/elasticsearch/index/sample_photo_vectors.json @@ -13,8 +13,8 @@ }, "faceVector" : { "type": "dense_vector", - "dims": 128, - "index": true, + "dims": 512, + "index": false, "similarity" : "dot_product" } } From 9fbc4a10586c44b479f36190a731d111ceefb17a Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Sat, 10 Aug 2024 19:45:10 +0900 Subject: [PATCH 11/11] =?UTF-8?q?refact=20:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/FaceDetectionServiceImpl.java | 32 ++++++++----------- .../config/{S3Config.java => AwsConfig.java} | 2 +- 2 files changed, 15 insertions(+), 19 deletions(-) rename src/main/java/com/umc/naoman/global/config/{S3Config.java => AwsConfig.java} (98%) diff --git a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java index 66fae004..70508e51 100644 --- a/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/photo/service/FaceDetectionServiceImpl.java @@ -2,7 +2,6 @@ import com.amazonaws.services.lambda.AWSLambda; import com.amazonaws.services.lambda.model.InvocationType; import com.amazonaws.services.lambda.model.InvokeRequest; -import com.amazonaws.services.lambda.model.InvokeResult; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.umc.naoman.domain.shareGroup.service.ShareGroupService; @@ -10,7 +9,6 @@ import com.umc.naoman.global.error.code.AwsLambdaErrorCode; import lombok.*; import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.List; @@ -18,11 +16,11 @@ @Service @RequiredArgsConstructor -public class FaceDetectionServiceImpl implements FaceDetectionService{ - @Value("${spring.lambda.function.detect_face_photo}") - private String detectFacePhotoLambda; - @Value("${spring.lambda.function.join_share_group}") - private String detectFaceShareGroupLambda; +public class FaceDetectionServiceImpl implements FaceDetectionService { + @Value("${spring.lambda.function.detect_face_upload_photo}") + private String detectFaceUploadPhotoLambda; + @Value("${spring.lambda.function.detect_face_join_share_group}") + private String detectFaceJoinShareGroupLambda; private final AWSLambda awsLambda; private final ObjectMapper objectMapper = new ObjectMapper(); private final ShareGroupService shareGroupService; @@ -30,7 +28,7 @@ public class FaceDetectionServiceImpl implements FaceDetectionService{ @Getter @AllArgsConstructor private class DetectFacePhotoPayload { - private List nameList; + private List photoNameList; private List memberIdList; private Long shareGroupId; } @@ -47,17 +45,17 @@ public void detectFaceUploadPhoto(List photoNameList, Long shareGroupId) List memberIdList = shareGroupService.findProfileListByShareGroupId(shareGroupId).stream() .map(profile -> profile.getMember().getId()) .collect(Collectors.toList()); - DetectFacePhotoPayload payLoad = new DetectFacePhotoPayload(photoNameList,memberIdList,shareGroupId); + DetectFacePhotoPayload payLoad = new DetectFacePhotoPayload(photoNameList, memberIdList, shareGroupId); String lambdaPayload = null; try { lambdaPayload = objectMapper.writeValueAsString(payLoad); } catch (JsonProcessingException e) { - throw new BusinessException(AwsLambdaErrorCode.AWS_JsonProcessing_Exception,e); + throw new BusinessException(AwsLambdaErrorCode.AWS_JsonProcessing_Exception, e); } InvokeRequest invokeRequest = new InvokeRequest() - .withInvocationType(InvocationType.Event) - .withFunctionName(detectFacePhotoLambda) + .withInvocationType(InvocationType.Event) //비동기 호출 + .withFunctionName(detectFaceUploadPhotoLambda) .withPayload(lambdaPayload); awsLambda.invoke(invokeRequest); @@ -65,21 +63,19 @@ public void detectFaceUploadPhoto(List photoNameList, Long shareGroupId) @Override public void detectFaceJoinShareGroup(Long memberId, Long shareGroupId) { - DetectFaceShareGroupPayload payLoad = new DetectFaceShareGroupPayload(memberId,shareGroupId); + DetectFaceShareGroupPayload payLoad = new DetectFaceShareGroupPayload(memberId, shareGroupId); String lambdaPayload = null; try { lambdaPayload = objectMapper.writeValueAsString(payLoad); } catch (JsonProcessingException e) { - throw new BusinessException(AwsLambdaErrorCode.AWS_JsonProcessing_Exception,e); + throw new BusinessException(AwsLambdaErrorCode.AWS_JsonProcessing_Exception, e); } InvokeRequest invokeRequest = new InvokeRequest() - .withInvocationType(InvocationType.Event) - .withFunctionName(detectFaceShareGroupLambda) + .withInvocationType(InvocationType.Event) //비동기 호출 + .withFunctionName(detectFaceJoinShareGroupLambda) .withPayload(lambdaPayload); awsLambda.invoke(invokeRequest); } - - } diff --git a/src/main/java/com/umc/naoman/global/config/S3Config.java b/src/main/java/com/umc/naoman/global/config/AwsConfig.java similarity index 98% rename from src/main/java/com/umc/naoman/global/config/S3Config.java rename to src/main/java/com/umc/naoman/global/config/AwsConfig.java index 9788ba6c..4c9969fc 100644 --- a/src/main/java/com/umc/naoman/global/config/S3Config.java +++ b/src/main/java/com/umc/naoman/global/config/AwsConfig.java @@ -12,7 +12,7 @@ import org.springframework.context.annotation.Primary; @Configuration -public class S3Config { +public class AwsConfig { @Value("${spring.cloud.aws.credentials.access-key}") private String accessKey;