Skip to content

Commit

Permalink
Merge pull request #48 from NU-BIM/feat/convert-photo-url
Browse files Browse the repository at this point in the history
[NB-215, NB-216] 이미지 주소 변환 구현 및 main 작성 반영
  • Loading branch information
liljoon authored Sep 6, 2024
2 parents 226c05f + d2db463 commit 2acfcb8
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 0 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/main_Release_Deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: main Repository Release Deploy
run-name: "main Deploy: Triggered by ${{ github.actor }}"

env:
AWS_DEFAULT_REGION: ap-northeast-2

on:
release:
types:
- published

permissions:
contents: read
id-token: write

jobs:
build:
runs-on: ubuntu-latest

env:
RELEASE_VERSION: ${{ github.event.release.tag_name }}

steps:
- name: Display Release Information
run: |
echo "Release Version: ${{ env.RELEASE_VERSION }}"
- name: Checkout code
uses: actions/checkout@v4

- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_DEFAULT_REGION }}
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions_be

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: Build and Push Docker Image
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: ${{ secrets.AWS_ECR_PROD_REPOSITORY }}
IMAGE_TAG: ${{ env.RELEASE_VERSION }}
run: |
docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG .
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
docker tag $REGISTRY/$REPOSITORY:$IMAGE_TAG $REGISTRY/$REPOSITORY:latest
docker push $REGISTRY/$REPOSITORY:latest
deploy:
needs: build
runs-on: ubuntu-latest

steps:
- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_DEFAULT_REGION }}
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions_be

- name: Deploy to Amazon ECS
run: |
aws ecs update-service \
--cluster ${{ secrets.AWS_ECS_CLUSTER_NAME }} \
--service ${{ secrets.AWS_ECS_SERVICE_NAME }} \
--region ${{ env.AWS_DEFAULT_REGION }} \
--force-new-deployment
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.soyeon.nubim.common.util.aws;

import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;

public class InvalidS3UrlException extends ResponseStatusException {
public InvalidS3UrlException() {
super(HttpStatus.BAD_REQUEST, "Invalid S3 URL format");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.soyeon.nubim.common.util.aws;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Service
@AllArgsConstructor
@NoArgsConstructor
public class S3AndCdnUrlConverter {
@Value("${spring.cloud.aws.s3.bucket}")
private String bucketName;
@Value("${spring.cloud.aws.region.static}")
private String region;

@Value("${CDN_URL}")
private String cdnUrl;

public String convertS3UrlToPath(String s3Url) {
String s3BucketUrlPrefix = String.format("https://%s.s3.%s.amazonaws.com", bucketName, region);

// S3 URL이 유효한지 확인
if (s3Url.startsWith(s3BucketUrlPrefix)) {
return s3Url.replace(s3BucketUrlPrefix, "");
} else {
throw new InvalidS3UrlException();
}
}

public String convertPathToCdnUrl(String path) {
return cdnUrl + path;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import org.springframework.stereotype.Component;

import com.soyeon.nubim.common.util.aws.S3AndCdnUrlConverter;
import com.soyeon.nubim.domain.album.Album;
import com.soyeon.nubim.domain.album.Location;
import com.soyeon.nubim.domain.album.dto.AlbumCreateRequestDto;
Expand All @@ -25,10 +26,14 @@
public class AlbumMapper {

private final LocationMapper locationMapper;
private final S3AndCdnUrlConverter s3AndCdnUrlConverter;

public Album toEntity(AlbumCreateRequestDto albumCreateRequestDto, User user) {
Map<Integer, String> photoUrls = albumCreateRequestDto.getPhotoUrls();

// S3 url 제거 후 경로만 저장
photoUrls.forEach((key, value) -> photoUrls.put(key, s3AndCdnUrlConverter.convertS3UrlToPath(value)));

List<LocationCreateRequestDto> locationDtos = albumCreateRequestDto.getLocations();
List<Location> locations = locationMapper.toEntityListFromCreateDto(locationDtos);

Expand All @@ -47,6 +52,9 @@ public Album toEntity(AlbumCreateRequestDto albumCreateRequestDto, User user) {
public AlbumCreateResponseDto toAlbumCreateResponseDto(Album album) {
Map<Integer, String> photoUrls = album.getPhotoUrls();

// cdn 경로 붙여서 반환
photoUrls.forEach((key, value) -> photoUrls.put(key, s3AndCdnUrlConverter.convertPathToCdnUrl(value)));

List<Location> locations = album.getLocations();
List<LocationCreateResponseDto> locationCreateResponseDtos =
locationMapper.toLocationCreateResponseDtoList(locations);
Expand All @@ -65,6 +73,9 @@ public AlbumCreateResponseDto toAlbumCreateResponseDto(Album album) {
public AlbumReadResponseDto toAlbumReadResponseDto(Album album) {
Map<Integer, String> photoUrls = album.getPhotoUrls();

// cdn 경로 붙여서 반환
photoUrls.forEach((key, value) -> photoUrls.put(key, s3AndCdnUrlConverter.convertPathToCdnUrl(value)));

List<Location> locations = album.getLocations();
List<LocationReadResponseDto> locationReadResponseDtos =
locationMapper.toLocationReadResponseDtoList(locations);
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/application-prod.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
spring:
config:
import: 'aws-parameterstore:/prod/'
jpa:
hibernate:
ddl-auto: validate

springdoc:
api-docs:
enabled: false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.soyeon.nubim.common.util.aws;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class S3AndCdnUrlConverterTest {

private S3AndCdnUrlConverter s3AndCdnUrlConverter;

@BeforeEach
void setup() {
String bucketName = "my-s3-bucket";
String region = "ap-northeast-2";
String cdnUrl = "https://cdn.example.com";

s3AndCdnUrlConverter = new S3AndCdnUrlConverter(bucketName, region, cdnUrl);
}

@Test
void testConvertS3UrlToPath_ValidS3Url() {
// given
String s3Url = "https://my-s3-bucket.s3.ap-northeast-2.amazonaws.com/path/example";
String expectedPath = "/path/example";

// when
String result = s3AndCdnUrlConverter.convertS3UrlToPath(s3Url);

// then
assertEquals(expectedPath, result);
}

@Test
void testConvertS3UrlToPath_InvalidS3Url() {
// given
String invalidS3Url = "https://other-bucket.s3.ap-northeast-2.amazonaws.com/path/example";

// when & then
assertThrows(InvalidS3UrlException.class, () -> {
s3AndCdnUrlConverter.convertS3UrlToPath(invalidS3Url);
});
}

@Test
void testConvertPathToCdnUrl() {
// given
String path = "/path/example";
String expectedCdnUrl = "https://cdn.example.com/path/example";

// when
String result = s3AndCdnUrlConverter.convertPathToCdnUrl(path);

// then
assertEquals(expectedCdnUrl, result);
}
}

0 comments on commit 2acfcb8

Please sign in to comment.