Skip to content

Commit

Permalink
Merge pull request #270 from WE-ARE-RACCOONS/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ywj9811 authored May 22, 2024
2 parents af200b9 + 4815602 commit 8ca7e0c
Show file tree
Hide file tree
Showing 25 changed files with 180 additions and 115 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/CI-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ jobs:
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Create application.yml
run: |
echo "${{env.APPLICATION}}" > ./src/main/resources/application.yml
- name: Grant execute permission for gradlew
run: chmod +x gradlew
working-directory: ${{ env.working-directory }}
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-batch'
testImplementation 'org.springframework.batch:spring-batch-test'

// https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter
implementation 'org.redisson:redisson-spring-boot-starter:3.18.0'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.postgraduate.domain.user.domain.entity.User;
import com.postgraduate.domain.user.domain.service.UserUpdateService;
import com.postgraduate.global.config.security.util.EncryptorUtils;
import com.postgraduate.global.slack.SlackCertificationMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -55,10 +56,12 @@ public class SeniorManageUseCase {
private final EncryptorUtils encryptorUtils;
private final UserUtils userUtils;
private final SeniorUtils seniorUtils;
private final SlackCertificationMessage slackCertificationMessage;

public void updateCertification(User user, SeniorCertificationRequest certificationRequest) {
Senior senior = seniorGetService.byUser(user);
seniorUpdateService.updateCertification(senior, certificationRequest.certification());
slackCertificationMessage.sendCertification(senior);
}

public SeniorProfileUpdateResponse signUpProfile(User user, SeniorProfileRequest profileRequest) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.postgraduate.global.aop.lock;

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.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import static java.util.concurrent.TimeUnit.SECONDS;

@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
public class DistributeLockAspect {
private final RedissonClient redissonClient;
private static final String PREFIX = "mentoring";

@Around("com.postgraduate.global.aop.lock.DistributeLockPointCut.allMentoringService()")
public Object startDistributeLock(ProceedingJoinPoint joinPoint) throws Throwable {
String lockKey = null;
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
if (arg instanceof Long) {
lockKey = PREFIX + arg;
}
}
RLock lock = redissonClient.getLock(lockKey);

try {
boolean available = lock.tryLock(5, 5, SECONDS);
if (!available)
throw new LockException();
log.info("lock ํš๋“ {}", lockKey);
return joinPoint.proceed();
} catch (Exception e) {
log.error("์˜ˆ์™ธ ๋ฐœ์ƒ {}", e.getMessage());
throw e;
} finally {
lock.unlock();
log.info("lock ๋ฐ˜๋‚ฉ {}", lockKey);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.postgraduate.global.aop.lock;

import org.aspectj.lang.annotation.Pointcut;

public class DistributeLockPointCut {
@Pointcut("execution(* com.postgraduate.domain.mentoring.application.usecase.MentoringManageUseCase.*(..)) " +
"&& !execution(* com.postgraduate.domain.mentoring.application.usecase.MentoringManageUseCase.sendFinishMessage(..)) " +
"&& !execution(* com.postgraduate.domain.mentoring.application.usecase.MentoringManageUseCase.applyMentoring(..))"
)
public void allMentoringService() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.postgraduate.global.aop.lock;

import com.postgraduate.global.exception.ApplicationException;

public class LockException extends ApplicationException {
protected LockException() {
super("Lock ํš๋“์ค‘ ์˜ˆ์™ธ ๋ฐœ์ƒ" , "EX_LOCK");
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.postgraduate.global.logging.aop;
package com.postgraduate.global.aop.logging;

import com.postgraduate.global.aop.logging.dto.TraceStatus;
import com.postgraduate.global.exception.ApplicationException;
import com.postgraduate.global.logging.dto.LogRequest;
import com.postgraduate.global.logging.service.LogService;
import com.postgraduate.global.aop.logging.dto.LogRequest;
import com.postgraduate.global.aop.logging.service.LogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
Expand All @@ -11,8 +12,8 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import static com.postgraduate.global.logging.aop.LogUtils.clearLogId;
import static com.postgraduate.global.logging.aop.LogUtils.setLogId;
import static com.postgraduate.global.aop.logging.utils.LogUtils.clearLogId;
import static com.postgraduate.global.aop.logging.utils.LogUtils.setLogId;

@Aspect
@Slf4j
Expand All @@ -24,13 +25,13 @@ public class LogAspect {
private final LogTrace logTrace;
private final LogService logService;

@Around("com.postgraduate.global.logging.aop.PointCuts.allService()")
@Around("com.postgraduate.global.aop.logging.LogPointCuts.allService()")
public Object serviceLog(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("serviceLog: {}", joinPoint.getSignature().getName());
return getObject(joinPoint);
}

@Around("com.postgraduate.global.logging.aop.PointCuts.allController()")
@Around("com.postgraduate.global.aop.logging.LogPointCuts.allController()")
public Object controllerLog(ProceedingJoinPoint joinPoint) throws Throwable {
setLogId();
log.info("controllerLog: {}", joinPoint.getSignature().getName());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.postgraduate.global.logging.aop;
package com.postgraduate.global.aop.logging;

import org.aspectj.lang.annotation.Pointcut;

//AOP์‚ฌ์šฉ
public class PointCuts {
public class LogPointCuts {

/**
* ์šฐ์„ ์€ ๋ชจ๋“  ์ปจํŠธ๋กค๋Ÿฌ, ๋ชจ๋“  ์„œ๋น„์Šค์—์„œ ๋™์ž‘ํ•˜๋„๋ก ํ•จ ์ด ๋˜ํ•œ ์ˆ˜์ • ๊ฐ€๋Šฅ
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.postgraduate.global.logging.aop;
package com.postgraduate.global.aop.logging;

import com.postgraduate.global.aop.logging.dto.TraceStatus;
import com.postgraduate.global.exception.ApplicationException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import static com.postgraduate.global.logging.aop.LogUtils.getLogId;
import static com.postgraduate.global.aop.logging.utils.LogUtils.getLogId;

@Component
@Slf4j
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.postgraduate.global.logging.dto;
package com.postgraduate.global.aop.logging.dto;

public record LogRequest(String env, String logId, Integer executeTime, String methodName, String exceptionMessage) {
public LogRequest(String env, String logId, Integer executeTime, String methodName) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.postgraduate.global.logging.aop;
package com.postgraduate.global.aop.logging.dto;

public record TraceStatus(String threadId, Long startTime, String methodName) {}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.postgraduate.global.logging.service;
package com.postgraduate.global.aop.logging.service;

import com.postgraduate.global.logging.dto.LogRequest;
import com.postgraduate.global.aop.logging.dto.LogRequest;
import com.postgraduate.global.slack.SlackLogErrorMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -11,8 +11,6 @@
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.io.IOException;

@Service
@Slf4j
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.postgraduate.global.logging.aop;
package com.postgraduate.global.aop.logging.utils;

import java.util.UUID;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.postgraduate.global.config.redis;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -18,16 +21,18 @@ public class RedisConfig {
private String host;

@Value("${spring.data.redis.port}")
private String port;
private int port;

@Value("${spring.data.redis.password}")
private String password;

private static final String REDISSON_HOST_PREFIX = "redis://";

@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(Integer.parseInt(port));
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(password);
return new LettuceConnectionFactory(redisStandaloneConfiguration);
}
Expand All @@ -45,6 +50,16 @@ public RedisTemplate<String, String> redisTemplate() {
public HashOperations<String, String, String> hashOperations(RedisTemplate<String, String> redisTemplate) {
return redisTemplate.opsForHash();
}

@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress(REDISSON_HOST_PREFIX + host + ":" + port)
.setPassword(password);

return Redisson.create(config);
}
}
/**
* CrudRepository ๋ฅผ ์ƒ์†ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๋˜ํ•œ ๊ฐ€๋Šฅํ•˜๋‹ˆ ์ƒ๊ฐ! ๊ธฐ๋Šฅ์ด ์กฐ๊ธˆ ์ค„์–ด๋“ค๊ธด ํ•จ
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.postgraduate.global.dto.ErrorResponse;
import com.postgraduate.global.logging.dto.LogRequest;
import com.postgraduate.global.logging.service.LogService;
import com.postgraduate.global.aop.logging.dto.LogRequest;
import com.postgraduate.global.aop.logging.service.LogService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.postgraduate.global.dto.ErrorResponse;
import com.postgraduate.global.logging.dto.LogRequest;
import com.postgraduate.global.logging.service.LogService;
import com.postgraduate.global.aop.logging.dto.LogRequest;
import com.postgraduate.global.aop.logging.service.LogService;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import com.postgraduate.global.exception.ApplicationException;
import com.postgraduate.global.config.security.jwt.exception.NoneRefreshTokenException;
import com.postgraduate.global.config.security.jwt.exception.TokenExpiredException;
import com.postgraduate.global.logging.dto.LogRequest;
import com.postgraduate.global.logging.service.LogService;
import com.postgraduate.global.aop.logging.dto.LogRequest;
import com.postgraduate.global.aop.logging.service.LogService;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ public class WebClientConfig {

@Bean
public ReactorResourceFactory resourceFactory() {
ReactorResourceFactory factory = new ReactorResourceFactory();
factory.setUseGlobalResources(false);
return factory;
return new ReactorResourceFactory();
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.postgraduate.global.dto.ErrorResponse;
import com.postgraduate.global.dto.ResponseDto;
import com.postgraduate.global.constant.ErrorCode;
import com.postgraduate.global.logging.dto.LogRequest;
import com.postgraduate.global.logging.service.LogService;
import com.postgraduate.global.aop.logging.dto.LogRequest;
import com.postgraduate.global.aop.logging.service.LogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.postgraduate.global.slack;

import com.postgraduate.domain.senior.domain.entity.Senior;
import com.postgraduate.domain.user.domain.entity.User;
import com.slack.api.Slack;
import com.slack.api.model.Attachment;
import com.slack.api.webhook.Payload;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

import static com.postgraduate.global.slack.SlackUtils.generateSlackField;

@Slf4j
@RequiredArgsConstructor
@Component
public class SlackCertificationMessage {
private final Slack slackClient = Slack.getInstance();

@Value("${slack.certification_url}")
private String certificationUrl;

public void sendCertification(Senior senior) {
try {
slackClient.send(certificationUrl, Payload.builder()
.text("์„ ๋ฐฐ ์ธ์ฆ ์š”์ฒญ์ด ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค!")
.attachments(
List.of(generateCertificationAttachment(senior))
)
.build());
} catch (IOException e) {
log.error("slack ์ „์†ก ์˜ค๋ฅ˜");
}
}

private Attachment generateCertificationAttachment(Senior senior) {
User user = senior.getUser();
return Attachment.builder()
.color("2FC4B2")
.title("์„ ๋ฐฐ ์ธ์ฆ ์š”์ฒญ")
.fields(List.of(
generateSlackField("์„ ๋ฐฐ ๋‹‰๋„ค์ž„ : ", user.getNickName()),
generateSlackField("์„ ๋ฐฐ ๋Œ€ํ•™์› : ", senior.getInfo().getPostgradu()),
generateSlackField("์„ ๋ฐฐ ์—ฐ๊ตฌ์‹ค : ", senior.getInfo().getLab()),
generateSlackField("์„ ๋ฐฐ ๊ต์ˆ˜ : " , senior.getInfo().getProfessor())
))
.build();
}
}
Loading

0 comments on commit 8ca7e0c

Please sign in to comment.