24.06.14 금 TIL(Today I Learned)

신민금·2024년 6월 17일
0
post-thumbnail

TIL(Today I Learned)

: 매일 저녁, 하루를 마무리하며 작성 !
: ⭕ 지식 위주, 학습한 것을 노트 정리한다고 생각하고 작성하면서 머리 속 흩어져있는 지식들을 정리 !


알고리즘 코드카타

  • 문제 설명
    2016년 1월 1일은 금요일입니다. 2016년 a월 b일은 무슨 요일일까요? 두 수 a ,b를 입력받아 2016년 a월 b일이 무슨 요일인지 리턴하는 함수, solution을 완성하세요. 요일의 이름은 일요일부터 토요일까지 각각 SUN,MON,TUE,WED,THU,FRI,SAT
    입니다. 예를 들어 a=5, b=24라면 5월 24일은 화요일이므로 문자열 "TUE"를 반환하세요.
  • 제한사항
    2016년은 윤년입니다.
    2016년 a월 b일은 실제로 있는 날입니다. (13월 26일이나 2월 45일같은 날짜는 주어지지 않습니다)
class Solution {
    public String solution(int a, int b) {
        String[] days = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
        int[] months = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30};
        int total = 0;
        
        for(int i=0; i<a; i++) {
            total += months[i];
        }
        total += b;

        return days[(total + 4) % 7];
    }
}

심화주차 개인과제 진행

Goal: "Controller, Service, Entity, DTO 레이어에 맞는 단위 테스트 작성"

  • AOP 추가
// ApiRequestLogAop

package com.sparta.wildcard_newsfeed.aop;

import com.sparta.wildcard_newsfeed.domain.user.entity.User;
import com.sparta.wildcard_newsfeed.domain.user.repository.UserRepository;
import com.sparta.wildcard_newsfeed.security.AuthenticationUser;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Slf4j(topic = "ApiRequestLog")
@Aspect
@Component
@RequiredArgsConstructor
public class ApiRequestLogAop {

    private final ApiUseTimeRepository apiUseTimeRepository;
    private final UserRepository userRepository;

    @Pointcut("execution(* com.sparta.wildcard_newsfeed.domain.comment.controller.CommentController.*(..))")
    private void comment() {}
    @Pointcut("execution(* com.sparta.wildcard_newsfeed.domain.liked.controller.LikedController.*(..))")
    private void liked() {}
    @Pointcut("execution(* com.sparta.wildcard_newsfeed.domain.post.controller.PostController.*(..))")
    private void post() {}
    @Pointcut("execution(* com.sparta.wildcard_newsfeed.domain.token.controller.TokenController.*(..))")
    private void token() {}
    @Pointcut("execution(* com.sparta.wildcard_newsfeed.domain.user.controller.UserController.*(..))")
    private void user() {}
    @Pointcut("execution(* com.sparta.wildcard_newsfeed.domain.user.controller.EmailController.*(..))")
    private void email() {}

    @Around("comment() || liked() || post() || token() || user() || email()")
    public Object logRequestDetails(ProceedingJoinPoint joinPoint) throws Throwable {
        // 현재 요청의 HttpServletRequest를 가져옴
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        // 요청 URL과 HTTP 메서드 로그 출력
        String requestUrl = request.getRequestURL().toString();
        String httpMethod = request.getMethod();
        log.info("Request URL: {}, HTTP Method: {}", requestUrl, httpMethod);

        // 측정 시작 시간
        long startTime = System.currentTimeMillis();

        try {
            // 핵심기능 수행
            Object output = joinPoint.proceed();
            return output;
        } finally {
            // 측정 종료 시간
            long endTime = System.currentTimeMillis();
            // 수행시간 = 종료 시간 - 시작 시간
            long runTime = endTime - startTime;

            // 로그인 토큰이 없는 경우, 수행시간 기록하지 않음
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (auth != null && auth.getPrincipal().getClass() == AuthenticationUser.class) {
                // 로그인 회원 정보
                AuthenticationUser authenticationUser = (AuthenticationUser) auth.getPrincipal();
                User loginUser = userRepository.findByUsercode(authenticationUser.getUsername())
                        .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다."));

                // API 사용시간 및 DB에 기록
                ApiUseTime apiUseTime = apiUseTimeRepository.findByUser(loginUser).orElse(null);
                if (apiUseTime == null) {
                    // 로그인 회원의 기록이 없으면
                    apiUseTime = new ApiUseTime(loginUser, runTime);
                } else {
                    // 로그인 회원의 기록이 이미 있으면
                    apiUseTime.addUseTime(runTime);
                }

                log.info("[API Use Time] Username: " + loginUser.getName() + ", Total Time: " + apiUseTime.getTotalTime() + " ms");
                apiUseTimeRepository.save(apiUseTime);
            }
        }
    }
}






// ApiUseTime

package com.sparta.wildcard_newsfeed.aop;

import com.sparta.wildcard_newsfeed.domain.user.entity.User;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "api_use_time")
public class ApiUseTime {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @Column(nullable = false)
    private Long totalTime;

    public ApiUseTime(User user, Long totalTime) {
        this.user = user;
        this.totalTime = totalTime;
    }

    public void addUseTime(long useTime) {
        this.totalTime += useTime;
    }
}





// ApiUseTimeRepository

package com.sparta.wildcard_newsfeed.aop;

import com.sparta.wildcard_newsfeed.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface ApiUseTimeRepository extends JpaRepository<ApiUseTime, Long> {
    Optional<ApiUseTime> findByUser(User user);
}





profile
야옹

0개의 댓글