Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/nyh365 Step3: 사용자 전체 정보 조회 #11

Open
wants to merge 20 commits into
base: nyh365
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3a1ab91
feat: User, Account 엔티티 추가
nyh365 Nov 13, 2024
fee398a
feat: 에러 메세지 추가
nyh365 Nov 13, 2024
4e20539
feat: 회원 조회 기능 추가
nyh365 Nov 13, 2024
ff1a7b3
feat: 거래 내역 응답 dto 추가
nyh365 Nov 14, 2024
3fe6259
feat: 계좌 정보 응답 dto 추가
nyh365 Nov 14, 2024
77bc646
feat: 사용자 금융 활동 응답 dto 추가
nyh365 Nov 14, 2024
0e6c909
feat: 사용자의 모든 계좌 조회 기능 추가
nyh365 Nov 14, 2024
318e003
feat: 한번에 관련 트랜잭션 데이터를 조회하는 기능 추가
nyh365 Nov 14, 2024
5f16c8d
feat: 한번에 관련 트랜잭션 데이터를 조회하는 기능 추가
nyh365 Nov 14, 2024
686c9fd
feat: 사용자의 모든 계좌 정보와 모든 거래 내역을 제공하는 기능 추가
nyh365 Nov 14, 2024
8687e85
feat: 함수형 프로그래밍 템플릿 추가
nyh365 Nov 14, 2024
e715125
feat: limit 만큼 트랜잭션 데이터 조회하는 기능 추가
nyh365 Nov 14, 2024
8d640f8
feat: limit만큼 사용자의 모든 계좌 정보와 모든 거래 내역을 제공하는 기능으로 수정
nyh365 Nov 14, 2024
3f55107
feat: 안정적인 thread 사용을 위한 커스텀
nyh365 Nov 15, 2024
78e6dd3
feat: 커스텀 thread 사용으로 변경
nyh365 Nov 15, 2024
f657073
refactor: 미사용 코드 제거
nyh365 Nov 15, 2024
2430be2
style: 형식 수정
nyh365 Nov 15, 2024
f23c4d7
feat: 비교를 위해 병렬 처리 안하는 api 추가
nyh365 Nov 15, 2024
1ae2581
feat: 유저 아이디를 통한 조회로 변경
nyh365 Nov 15, 2024
130e434
refactor: 미사용 코드 제거
nyh365 Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.c4marathon.assignment.controller;

import org.c4marathon.assignment.dto.response.FinancialInfoRes;
import org.c4marathon.assignment.service.MarathonService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/marathon")
@RequiredArgsConstructor
public class MarathonController {
private final MarathonService marathonService;

@GetMapping("/all-info")
public FinancialInfoRes getAllInfoWithLimit(@RequestParam Integer id) {
return marathonService.getAllInfoWithLimit(id);
}

@GetMapping("/all-info-not-parallel")
public FinancialInfoRes getAllInfoNotParallel(@RequestParam Integer id) {
return marathonService.getAllInfoNotParallel(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.c4marathon.assignment.core;

import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@RequiredArgsConstructor
@Slf4j
public class C4ThreadPoolExecutor implements Executor {
private final int threadCount;
private final int queueSize;
private ThreadPoolExecutor threadPoolExecutor;
private RuntimeException exception = null;

public void init() {
if (threadPoolExecutor != null) {
return;
}

threadPoolExecutor = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(queueSize),
(r, executor) -> {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
log.error(e.toString(), e);
Thread.currentThread().interrupt();
}
});
}

@Override
public void execute(Runnable command) {
if (isInvalidState()) {
return;
}

threadPoolExecutor.execute(() -> {
try {
command.run();
} catch (RuntimeException e) {
log.error(e.toString(), e);
exception = e;
}
});
}

public void waitToEnd() {
if (isInvalidState()) {
return;
}

threadPoolExecutor.shutdown();
while (true) {
try {
if (threadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS)) {
break;
}
} catch (InterruptedException e) {
log.error(e.toString(), e);
Thread.currentThread().interrupt();
}
}

threadPoolExecutor = null;
if (exception != null) {
throw exception;
}
}

private boolean isInvalidState() {
return threadPoolExecutor == null || threadPoolExecutor.isTerminating() || threadPoolExecutor.isTerminated();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.c4marathon.assignment.dto.response;

import org.c4marathon.assignment.entity.Account;

public record AccountRes(
String accountNumber,
Long balance
) {
public AccountRes(Account account) {
this(
account.getAccountNumber(),
account.getBalance()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.c4marathon.assignment.dto.response;

import java.util.List;

public record FinancialInfoRes(
List<AccountRes> accountRes,
List<TransactionRes> transactionRes,
int accountTotal,
int transactionTotal
) {
public FinancialInfoRes(List<AccountRes> accountRes, List<TransactionRes> transactionRes) {
this(
accountRes,
transactionRes,
accountRes.size(),
transactionRes.size()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.c4marathon.assignment.dto.response;

import java.time.Instant;

import org.c4marathon.assignment.entity.Transaction;

public record TransactionRes(
String senderAccount,
String receiverAccount,
String senderSwiftCode,
String receiverSwiftCode,
String senderName,
String receiverName,
Long amount,
String memo,
Instant transactionDate
) {
public TransactionRes(Transaction transaction) {
this(
transaction.getSenderAccount(),
transaction.getReceiverAccount(),
transaction.getSenderSwiftCode(),
transaction.getReceiverSwiftCode(),
transaction.getSenderName(),
transaction.getReceiverName(),
transaction.getAmount(),
transaction.getMemo(),
transaction.getTransactionDate()
);
}
}
67 changes: 67 additions & 0 deletions src/main/java/org/c4marathon/assignment/entity/Account.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.c4marathon.assignment.entity;

import java.time.Instant;
import java.util.stream.IntStream;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.hibernate.annotations.ColumnDefault;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@Table(name = "account")
public class Account {
public static final String ACCOUNT_PREFIX = "3333";

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "account_id", nullable = false)
private Integer id;

@Size(max = 13)
@NotNull
@Column(name = "account_number", nullable = false, length = 13)
private String accountNumber;

@NotNull
@Column(name = "user_id", nullable = false)
private Integer userId;

@NotNull
@Column(name = "account_type", nullable = false)
private Character accountType;

@Size(max = 200)
@Column(name = "memo", length = 200)
private String memo;

@NotNull
@ColumnDefault("0")
@Column(name = "balance", nullable = false)
private Long balance;

@NotNull
@ColumnDefault("CURRENT_TIMESTAMP")
@Column(name = "create_date", nullable = false)
private Instant createDate;

@Column(name = "recent_transaction_date")
private Instant recentTransactionDate;

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
54 changes: 54 additions & 0 deletions src/main/java/org/c4marathon/assignment/entity/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.c4marathon.assignment.entity;

import java.time.Instant;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@Table(name = "user")
public class User {
@Id
@Column(name = "user_id", nullable = false)
private Integer id;

@Size(max = 30)
@NotNull
@Column(name = "username", nullable = false, length = 30)
private String username;

@Size(max = 30)
@NotNull
@Column(name = "email", nullable = false, length = 30)
private String email;

@Size(max = 10)
@NotNull
@Column(name = "nickname", nullable = false, length = 10)
private String nickname;

@NotNull
@Column(name = "group_id", nullable = false)
private Integer groupId;

@NotNull
@Column(name = "user_status", nullable = false)
private Character userStatus;

@NotNull
@Column(name = "create_date", nullable = false)
private Instant createDate;

@NotNull
@Column(name = "update_date", nullable = false)
private Instant updateDate;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.c4marathon.assignment.exception;

public class BadRequestException extends RuntimeException {
public BadRequestException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.c4marathon.assignment.handler;

import java.util.HashMap;
import java.util.Map;

import org.c4marathon.assignment.exception.BadRequestException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {
private static final String MESSAGE = "message";

@ExceptionHandler(BadRequestException.class)
public ResponseEntity<Map<String, Object>> handleBadRequestException(BadRequestException ex) {
Map<String, Object> resultMap = new HashMap<>();

resultMap.put(MESSAGE, ex.getMessage());

return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.c4marathon.assignment.repository;

import java.util.List;

import org.c4marathon.assignment.entity.Account;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface AccountJpaRepository extends JpaRepository<Account, Long> {
List<Account> findAllByUserId(Integer userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.c4marathon.assignment.repository;

import java.util.List;

import org.c4marathon.assignment.entity.Account;
import org.springframework.stereotype.Repository;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class AccountRepository {
private final AccountJpaRepository accountJpaRepository;

public List<Account> findAllAccountByUserId(Integer userId) {
return accountJpaRepository.findAllByUserId(userId);
}
}
Loading