diff --git a/.aws/task-definition.json b/.aws/task-definition-prd.json similarity index 100% rename from .aws/task-definition.json rename to .aws/task-definition-prd.json diff --git a/.aws/task-definition-stg.json b/.aws/task-definition-stg.json new file mode 100644 index 00000000..612ef744 --- /dev/null +++ b/.aws/task-definition-stg.json @@ -0,0 +1,146 @@ +{ + "taskDefinitionArn": "arn:aws:ecs:ap-northeast-2:750773866215:task-definition/gloddy-stg-task:1", + "containerDefinitions": [ + { + "name": "springboot", + "image": "750773866215.dkr.ecr.ap-northeast-2.amazonaws.com/gloddy-stg:latest", + "cpu": 768, + "memory": 1024, + "portMappings": [ + { + "name": "springboot-8080-tcp", + "containerPort": 8080, + "hostPort": 8080, + "protocol": "tcp", + "appProtocol": "http" + } + ], + "essential": true, + "environment": [], + "environmentFiles": [ + { + "value": "arn:aws:s3:::gloddy-env/env/gloddy-stg.env", + "type": "s3" + } + ], + "mountPoints": [], + "volumesFrom": [], + "ulimits": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/gloddy-stg-task", + "awslogs-region": "ap-northeast-2", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + }, + { + "name": "datadog-agent", + "image": "public.ecr.aws/datadog/agent:latest", + "cpu": 197, + "memory": 512, + "portMappings": [ + { + "name": "datadog-agent-8126-tcp", + "containerPort": 8126, + "hostPort": 8126, + "protocol": "tcp", + "appProtocol": "http" + }, + { + "containerPort": 8125, + "hostPort": 8125, + "protocol": "udp" + } + ], + "essential": false, + "environment": [ + { + "name": "DD_SITE", + "value": "us5.datadoghq.com" + }, + { + "name": "DD_APM_ENABLED", + "value": "true" + }, + { + "name": "DD_DOGSTATSD_NON_LOCAL_TRAFFIC", + "value": "true" + } + ], + "environmentFiles": [ + { + "value": "arn:aws:s3:::gloddy-env/env/datadog.env", + "type": "s3" + } + ], + "mountPoints": [], + "volumesFrom": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/datadog-agent-stg", + "awslogs-region": "ap-northeast-2", + "awslogs-stream-prefix": "ecs" + }, + "secretOptions": [] + } + } + ], + "family": "gloddy-stg-task", + "executionRoleArn": "arn:aws:iam::750773866215:role/ecsTaskExecutionRole", + "networkMode": "awsvpc", + "revision": 1, + "volumes": [], + "status": "ACTIVE", + "requiresAttributes": [ + { + "name": "com.amazonaws.ecs.capability.logging-driver.awslogs" + }, + { + "name": "ecs.capability.execution-role-awslogs" + }, + { + "name": "com.amazonaws.ecs.capability.ecr-auth" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19" + }, + { + "name": "ecs.capability.env-files.s3" + }, + { + "name": "ecs.capability.execution-role-ecr-pull" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18" + }, + { + "name": "ecs.capability.task-eni" + }, + { + "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29" + } + ], + "placementConstraints": [], + "compatibilities": [ + "EC2", + "FARGATE" + ], + "requiresCompatibilities": [ + "FARGATE" + ], + "cpu": "1024", + "memory": "2048", + "runtimePlatform": { + "cpuArchitecture": "X86_64", + "operatingSystemFamily": "LINUX" + }, + "registeredAt": "2023-10-22T13:44:26.368Z", + "registeredBy": "arn:aws:iam::750773866215:root", + "tags": [] +} \ No newline at end of file diff --git a/.github/workflows/DeployOnPRD.yml b/.github/workflows/DeployOnPRD.yml index fbed71f1..347cc1ed 100644 --- a/.github/workflows/DeployOnPRD.yml +++ b/.github/workflows/DeployOnPRD.yml @@ -10,7 +10,7 @@ env: ECR_REPOSITORY: gloddy-prd ECS_SERVICE: gloddy-prd-ecs-service ECS_CLUSTER: gloddy-ecs-prd - ECS_TASK_DEFINITION: .aws/task-definition.json + ECS_TASK_DEFINITION: .aws/task-definition-prd.json CONTAINER_NAME: springboot diff --git a/.github/workflows/DeployOnSTG.yml b/.github/workflows/DeployOnSTG.yml index ba12ad0d..257bec43 100644 --- a/.github/workflows/DeployOnSTG.yml +++ b/.github/workflows/DeployOnSTG.yml @@ -1,24 +1,39 @@ -name: Deploy on STG Server +name: Deploy on STG Server (Amazon ECS) on: pull_request: types: [closed] branches: [dev] +env: + AWS_REGION: ap-northeast-2 + ECR_REPOSITORY: gloddy-stg + ECS_SERVICE: gloddy-stg-ecs-service + ECS_CLUSTER: gloddy-ecs-stg + ECS_TASK_DEFINITION: .aws/task-definition-stg.json + + CONTAINER_NAME: springboot + +permissions: + contents: read + jobs: - build: + deploy: + name: Deploy runs-on: ubuntu-latest - if: github.event.pull_request.merged + environment: staging steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 + - name: Set up JDK 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' - - name: Gradle Caching - uses: actions/cache@v3 + + - uses: actions/cache@v3 with: path: | ~/.gradle/caches @@ -26,22 +41,46 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle- + - name: Grant execute permission for gradlew - run: chmod +x gradlew - ##Build Project + run: chmod +x ./gradlew + - name: Build with Gradle - run: ./gradlew build -x test - ## Deploy - - name: Make zip file - run: zip gloddy-server.zip -r ./build/libs/*.jar ./script ./Dockerfile && zip gloddy-server.zip -j ./appspec.yml - shell: bash + run: ./gradlew build + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: - aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY }} - aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_KEY }} - aws-region: ${{ secrets.AWS_S3_REGION }} - - name: Upload to S3 - run: aws s3 cp ./gloddy-server.zip s3://${{ secrets.AWS_BUCKET }}/stg-deploy/ - - name: Code Deploy - run: aws deploy create-deployment --application-name gloddy-codedeploy-app --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name stg --s3-location bucket=${{ secrets.AWS_BUCKET }},bundleType=zip,key=stg-deploy/gloddy-server.zip --region ${{ secrets.AWS_S3_REGION }} --file-exists-behavior OVERWRITE + aws-access-key-id: ${{ secrets.AWS_ECS_ACCESS }} + aws-secret-access-key: ${{ secrets.AWS_ECS_SECRET }} + aws-region: ${{ env.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build, tag, and push image to Amazon ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + IMAGE_TAG: latest + run: | + docker build -f Dockerfile_stg -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT + + - name: Fill in the new image ID in the Amazon ECS task definition + id: task-def + uses: aws-actions/amazon-ecs-render-task-definition@v1 + with: + task-definition: ${{ env.ECS_TASK_DEFINITION }} + container-name: ${{ env.CONTAINER_NAME }} + image: ${{ steps.build-image.outputs.image }} + + - name: Deploy Amazon ECS task definition + uses: aws-actions/amazon-ecs-deploy-task-definition@v1 + with: + task-definition: ${{ steps.task-def.outputs.task-definition }} + service: ${{ env.ECS_SERVICE }} + cluster: ${{ env.ECS_CLUSTER }} + wait-for-service-stability: true diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 53493a8f..00000000 --- a/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM openjdk:17.0-slim - -EXPOSE 8080 - -ARG PROJECT_DIRECTORY=/build - -WORKDIR $PROJECT_DIRECTORY - -ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/Dockerfile_stg b/Dockerfile_stg new file mode 100644 index 00000000..55b0fc98 --- /dev/null +++ b/Dockerfile_stg @@ -0,0 +1,16 @@ +FROM openjdk:17.0-slim + +EXPOSE 8080 + +ARG PROJECT_DIRECTORY=/build +WORKDIR $PROJECT_DIRECTORY + +ARG JAR_FILE_PATH=build/libs/server-0.0.1-SNAPSHOT.jar +COPY ${JAR_FILE_PATH} app.jar + +RUN apt-get update \ + && apt-get install -y wget \ + && rm -rf /var/lib/apt/lists/* +RUN wget -O dd-java-agent.jar 'https://dtdg.co/latest-java-tracer' + +ENTRYPOINT ["java", "-javaagent:dd-java-agent.jar", "-Ddd.profiling.enabled=true", "-XX:FlightRecorderOptions=stackdepth=256", "-Ddd.appsec.enabled=true", "-Ddd.iast.enabled=true", "-Ddd.logs.injection=true", "-Ddd.jmxfetch.enabled=true", "-Ddd.service=gloddy", "-Ddd.env=staging", "-jar", "app.jar"] \ No newline at end of file diff --git a/src/main/java/com/gloddy/server/auth/domain/dto/AuthResponse.java b/src/main/java/com/gloddy/server/auth/domain/dto/AuthResponse.java index 54e97335..4f29ce6b 100644 --- a/src/main/java/com/gloddy/server/auth/domain/dto/AuthResponse.java +++ b/src/main/java/com/gloddy/server/auth/domain/dto/AuthResponse.java @@ -27,7 +27,7 @@ public static class SignUp extends AuthResponse { public static SignUp from(User user, JwtTokenIssuer jwtTokenIssuer) { return new SignUp(user.getId(), user.getAuthority().getRole(), - jwtTokenIssuer.issueToken(user.getPhone().getPhoneNumber())); + jwtTokenIssuer.issueToken(user.getId().toString())); } } @@ -47,7 +47,7 @@ public static Login fail() { public static Login from(User user, JwtTokenIssuer jwtTokenIssuer) { return new Login(true, user.getId(), user.getAuthority().getRole(), - jwtTokenIssuer.issueToken(user.getPhone().getPhoneNumber())); + jwtTokenIssuer.issueToken(user.getId().toString())); } } diff --git a/src/main/java/com/gloddy/server/auth/jwt/JwtAuthentication.java b/src/main/java/com/gloddy/server/auth/jwt/JwtAuthentication.java index 69f960e6..9db5daab 100644 --- a/src/main/java/com/gloddy/server/auth/jwt/JwtAuthentication.java +++ b/src/main/java/com/gloddy/server/auth/jwt/JwtAuthentication.java @@ -1,12 +1,9 @@ package com.gloddy.server.auth.jwt; -import lombok.AllArgsConstructor; -import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; import javax.security.auth.Subject; import java.util.Collection; @@ -15,10 +12,10 @@ public class JwtAuthentication implements Authentication { private final JwtUserAdapter userDetails; - private final String phoneNumber; + private final String userId; - public static Authentication of(JwtUserAdapter userDetails, String phoneNumber) { - return new JwtAuthentication(userDetails, phoneNumber); + public static Authentication of(JwtUserAdapter userDetails, String userId) { + return new JwtAuthentication(userDetails, userId); } @@ -54,7 +51,7 @@ public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentExce @Override public String getName() { - return phoneNumber; + return userId.toString(); } @Override diff --git a/src/main/java/com/gloddy/server/auth/jwt/JwtTokenExtractor.java b/src/main/java/com/gloddy/server/auth/jwt/JwtTokenExtractor.java index 2d20ac70..e8c67578 100644 --- a/src/main/java/com/gloddy/server/auth/jwt/JwtTokenExtractor.java +++ b/src/main/java/com/gloddy/server/auth/jwt/JwtTokenExtractor.java @@ -24,7 +24,7 @@ public String extractToken(HttpServletRequest request, String headerKey) { return request.getHeader(headerKey); } - public String extractPhoneNumberFromToken(String token, String key) { + public String extractSubjectFromToken(String token, String key) { Claims claims = getClaims(token, key); return claims.getSubject(); } diff --git a/src/main/java/com/gloddy/server/auth/jwt/JwtUserAdapter.java b/src/main/java/com/gloddy/server/auth/jwt/JwtUserAdapter.java index a50358fe..85297328 100644 --- a/src/main/java/com/gloddy/server/auth/jwt/JwtUserAdapter.java +++ b/src/main/java/com/gloddy/server/auth/jwt/JwtUserAdapter.java @@ -32,7 +32,7 @@ public String getPassword() { @Override public String getUsername() { - return user.getPhone().getPhoneNumber(); + return user.getId().toString(); } @Override diff --git a/src/main/java/com/gloddy/server/auth/jwt/filter/JwtAuthenticationFilter.java b/src/main/java/com/gloddy/server/auth/jwt/filter/JwtAuthenticationFilter.java index 7fb473a9..4c91f10d 100644 --- a/src/main/java/com/gloddy/server/auth/jwt/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/gloddy/server/auth/jwt/filter/JwtAuthenticationFilter.java @@ -51,8 +51,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse throw new UserBusinessException(TOKEN_BLANK); } - String phoneNumber = jwtTokenExtractor.extractPhoneNumberFromToken(token, KEY); - Authentication authentication = JwtAuthentication.of(null, phoneNumber); + String userId = jwtTokenExtractor.extractSubjectFromToken(token, KEY); + Authentication authentication = JwtAuthentication.of(null, userId); Authentication authenticated = authenticationProvider.authenticate(authentication); diff --git a/src/main/java/com/gloddy/server/auth/security/UserDetailsServiceImpl.java b/src/main/java/com/gloddy/server/auth/security/UserDetailsServiceImpl.java index 6f1866e7..3732dbbf 100644 --- a/src/main/java/com/gloddy/server/auth/security/UserDetailsServiceImpl.java +++ b/src/main/java/com/gloddy/server/auth/security/UserDetailsServiceImpl.java @@ -20,11 +20,8 @@ public class UserDetailsServiceImpl implements UserDetailsService { private final UserQueryHandler userQueryHandler; @Override - public UserDetails loadUserByUsername(String phoneNumber) throws UsernameNotFoundException { - - User user = userQueryHandler.findByPhone(new Phone(phoneNumber)) - .orElseThrow(() -> new UserBusinessException(ErrorCode.USER_NOT_FOUND)); - + public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { + User user = userQueryHandler.findById(Long.parseLong(userId)); return JwtUserAdapter.from(user); } } diff --git a/src/test/java/com/gloddy/server/common/BaseApiTest.java b/src/test/java/com/gloddy/server/common/BaseApiTest.java index 6b9a1e13..cb230276 100644 --- a/src/test/java/com/gloddy/server/common/BaseApiTest.java +++ b/src/test/java/com/gloddy/server/common/BaseApiTest.java @@ -109,7 +109,7 @@ protected User createUser() { } protected String getTokenAfterLogin(User user) { - AccessPayload accessPayload = AccessPayload.of(user.getPhone().toString()); + AccessPayload accessPayload = AccessPayload.of(user.getId().toString()); return jwtTokenBuilder.createToken(accessPayload); }