Skip to content

Commit 3be5659

Browse files
authored
Merge pull request #19 from C4-ComeTrue/feature/hellozo0_step1
Feature/hellozo0 step1
2 parents bd31dc5 + 5dad000 commit 3be5659

32 files changed

+770
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ out/
3838

3939
### MAC ###
4040
.DS_Store
41+
42+
### Redis ###
43+
dump.rdb

build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dependencies {
2929
implementation 'org.springframework.boot:spring-boot-starter-web'
3030
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
3131
implementation 'org.springframework.boot:spring-boot-starter-validation'
32+
implementation 'org.springframework.boot:spring-boot-starter-cache'
3233

3334
//apache
3435
implementation 'org.apache.commons:commons-lang3:3.13.0'
@@ -41,6 +42,10 @@ dependencies {
4142
//mysql
4243
runtimeOnly 'com.mysql:mysql-connector-j'
4344

45+
//redis
46+
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
47+
implementation 'org.springframework.session:spring-session-data-redis'
48+
4449
//test
4550
testImplementation 'org.springframework.boot:spring-boot-starter-test'
4651
}

src/main/java/org/c4marathon/assignment/AssignmentApplication.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22

33
import org.springframework.boot.SpringApplication;
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.cache.annotation.EnableCaching;
6+
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
7+
import org.springframework.scheduling.annotation.EnableScheduling;
58

69
@SpringBootApplication
10+
@EnableScheduling
11+
@EnableJpaAuditing
12+
@EnableCaching
713
public class AssignmentApplication {
814

915
public static void main(String[] args) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.c4marathon.assignment.common.cache;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.data.redis.connection.RedisConnectionFactory;
6+
import org.springframework.data.redis.core.RedisTemplate;
7+
import org.springframework.data.redis.serializer.GenericToStringSerializer;
8+
import org.springframework.data.redis.serializer.StringRedisSerializer;
9+
10+
@Configuration
11+
public class CacheConfig {
12+
13+
@Bean
14+
public RedisTemplate<String, Long> redisStringLongTemplate(RedisConnectionFactory connectionFactory) {
15+
RedisTemplate<String, Long> template = new RedisTemplate<>();
16+
template.setConnectionFactory(connectionFactory);
17+
template.setKeySerializer(new StringRedisSerializer());
18+
template.setValueSerializer(new GenericToStringSerializer<>(Long.class));
19+
20+
return template;
21+
}
22+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.c4marathon.assignment.common.cache;
2+
3+
import java.time.Duration;
4+
5+
import org.springframework.data.redis.core.RedisTemplate;
6+
import org.springframework.scheduling.annotation.Scheduled;
7+
import org.springframework.stereotype.Component;
8+
9+
@Component
10+
public class CacheScheduler {
11+
private final RedisTemplate<String, Long> redisTemplate;
12+
13+
public CacheScheduler(RedisTemplate<String, Long> redisTemplate) {
14+
this.redisTemplate = redisTemplate;
15+
}
16+
17+
@Scheduled(cron = "0 0 0 * * *")
18+
public void resetDailyLimit() {
19+
/* 24시에 10분동안 은행 계좌 점검 => 10분동안 일일 한도 초기화 */
20+
String lockKey = "reset";
21+
redisTemplate.opsForValue().set(lockKey, 1L, Duration.ofMinutes(10));
22+
23+
/* 모든 dailyLimit 삭제 */
24+
try {
25+
redisTemplate.keys("dailyLimit:*").forEach(redisTemplate::delete);
26+
} finally {
27+
redisTemplate.delete(lockKey);
28+
}
29+
}
30+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.c4marathon.assignment.common.dto;
2+
3+
import org.c4marathon.assignment.common.exception.enums.ErrorCode;
4+
import org.springframework.http.HttpStatus;
5+
6+
import lombok.AccessLevel;
7+
import lombok.Getter;
8+
import lombok.RequiredArgsConstructor;
9+
import lombok.ToString;
10+
11+
@Getter
12+
@ToString
13+
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
14+
public class ErrorResponse {
15+
private final int code;
16+
private final String message;
17+
18+
public static ErrorResponse error(ErrorCode errorCode) {
19+
return new ErrorResponse(errorCode.getHttpStatus().value(), errorCode.getMessage());
20+
}
21+
22+
public static ErrorResponse badRequestError(final String errorMessage) {
23+
return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), errorMessage);
24+
}
25+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.c4marathon.assignment.common.dto;
2+
3+
import org.c4marathon.assignment.common.exception.enums.SuccessCode;
4+
5+
import lombok.AccessLevel;
6+
import lombok.AllArgsConstructor;
7+
import lombok.Getter;
8+
import lombok.ToString;
9+
10+
@Getter
11+
@ToString
12+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
13+
public class SuccessNonDataResponse {
14+
private final int code;
15+
private final String message;
16+
17+
public static SuccessNonDataResponse success(SuccessCode successCode) {
18+
return new SuccessNonDataResponse(successCode.getHttpStatus().value(), successCode.getMessage());
19+
}
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.c4marathon.assignment.common.dto;
2+
3+
import org.c4marathon.assignment.common.exception.enums.SuccessCode;
4+
5+
import lombok.AccessLevel;
6+
import lombok.AllArgsConstructor;
7+
import lombok.Getter;
8+
import lombok.ToString;
9+
10+
@Getter
11+
@ToString
12+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
13+
public class SuccessResponse<T> {
14+
private final int code;
15+
private final String message;
16+
private final T data;
17+
18+
public static <T> SuccessResponse<T> success(SuccessCode successCode, T data) {
19+
return new SuccessResponse<>(successCode.getHttpStatus().value(), successCode.getMessage(), data);
20+
}
21+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.c4marathon.assignment.common.exception;
2+
3+
import org.c4marathon.assignment.common.exception.enums.ErrorCode;
4+
5+
public class BalanceUpdateException extends BaseException {
6+
public BalanceUpdateException(ErrorCode errorCode) {
7+
super(errorCode);
8+
}
9+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.c4marathon.assignment.common.exception;
2+
3+
import org.c4marathon.assignment.common.exception.enums.ErrorCode;
4+
import lombok.Getter;
5+
6+
@Getter
7+
public class BaseException extends RuntimeException {
8+
private final ErrorCode errorCode;
9+
10+
public BaseException(final ErrorCode errorCode) {
11+
super(errorCode.getMessage());
12+
this.errorCode = errorCode;
13+
}
14+
}

0 commit comments

Comments
 (0)