-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [feat] 종목 현재가 갱신 시스템 구현 (#462) * feat: Kis 웹소켓 서비스 구현 * feat: 웹소켓 접근키 저장소 구현 * test: 웹소켓 접근키 저장소의 테스트 추가 * feat: tr-id 프로퍼티 추가 * fix: 웹소켓 접속 문제 해결 * feat: approvalKey에 대한 null 처리 추가 * feat: 정적 팩토리 추가 * test: 테스트 검증문 수정 * test: KisWebSocketClient connect 테스트 추가 * test: onClose 테스트 추가 * test: add sendMessage test * feat: oauth SecurityFilterChain 순서 변경 - 변경 이유 : 테스트용 SecurityFilterChain이 순서상 앞에 두기 위해서 * test: 테스트용 웹소켓 서버 설정 추가 * feat: 웹소켓 클라이언트에 실시간 종목 체결가 핸들링 메서드 구현 * test: 웹소켓으로 실시간 체결가를 조회하여 레디스에 저장하는 테스트 구현 * style: 투두 추가 및 메인 애플리케이션 이름 변경 * test: 테스트 서포트 클래스 support 패키지로 이동 * feat: StockPrice push 서비스 구현 * feat: WebClientConfig global 패키지로 이동 * fix: api로 요청하는 방식이 아닌 price 모듈에서 가져오는 방식으로 변경 * feat: StockPriceWebSocketClient 구현 * feat: connect 예외 처리 * rename: 패키지명 변경 * style: 코드 정리 * feat: 웹소켓 현재가 조회 API 구현 * feat: StockPriceDispatcher 구현 * feat: add log * test: solve test fail * feat: StockPriceWebSocket 스케줄러 구현 - 오전 8시30분에 웹소켓 재연결 - 오후 16시에 웹소켓 연결 해제 * refactor: extract method * feat: add stream filter * style: 코드 정리 * style: 코드 정리 * test: 테스트 추가 * test: 테스트 검증 수정 * feat: 포트폴리오 캐시 기능 추가 * feat: 캐시 TTL 설정 추가 * feat: 포트폴리오 종목 서비스에 캐시 로직 추가 * test: 캐시 관련 검증문 추가 * test: mock 설정 추가 * feat: 스케줄러 삭제 * feat: cors 프로파일별 설정 클래스 추가 (#464) * fix: test 프로파일 설정값 추가 및 클래스명 변경 * feat: appkey, secretkey 변경 (#466) * [feat] 로깅 추가 (#468) * feat: appkey, secretkey 변경 * feat: 로깅 추가 * feat: ssl 갱신 * feat: ssl release 추가 * [feat] 더미 데이터 생성 기능 구현 (#471) * feat: local db username root로 변경 - bulk insert 수행시 권한 문제로 인하여 로컬 실행시 root 권한으로 실행 * feat: dummy csv 파일 생성 클래스 구현 * fix: MemberRole csv 파일 생성 메서드 삭제 * fix: 회원 샘플수 조정 * feat: 조건문 추가 * fix: 조건문 제거 * feat: 퐁 데이터 송신 구현 (#473) * feat: 종목 현재가 갱신 스케줄러 추가 웹소켓을 이용한 서버가 완성될때까지 임시로 추가
- Loading branch information
1 parent
c74cbd1
commit 6fbadd4
Showing
9 changed files
with
158 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ | |
/src/main/resources/secret/ | ||
/src/main/generated/ | ||
/htmlReport/ | ||
/src/main/resources/db/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule secret
updated
from af5c3d to 5f1a0a
33 changes: 33 additions & 0 deletions
33
src/main/java/co/fineants/api/domain/kis/scheduler/KisProductionScheduler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package co.fineants.api.domain.kis.scheduler; | ||
|
||
import java.time.LocalDate; | ||
|
||
import org.springframework.context.annotation.Profile; | ||
import org.springframework.scheduling.annotation.Scheduled; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import co.fineants.api.domain.kis.repository.HolidayRepository; | ||
import co.fineants.api.domain.kis.service.KisService; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Profile(value = "production") | ||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Service | ||
public class KisProductionScheduler { | ||
|
||
private final HolidayRepository holidayRepository; | ||
private final KisService kisService; | ||
|
||
@Scheduled(cron = "0/5 * 9-15 ? * MON,TUE,WED,THU,FRI") | ||
@Transactional | ||
public void refreshCurrentPrice() { | ||
// 휴장일인 경우 실행하지 않음 | ||
if (holidayRepository.isHoliday(LocalDate.now())) { | ||
return; | ||
} | ||
kisService.refreshAllStockCurrentPrice(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
src/test/java/co/fineants/data/DummyDataCsvGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package co.fineants.data; | ||
|
||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.time.LocalDateTime; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.apache.commons.csv.CSVFormat; | ||
import org.apache.commons.csv.CSVPrinter; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
public class DummyDataCsvGenerator { | ||
|
||
public static void main(String[] args) { | ||
DummyDataCsvGenerator dummyDataCsvGenerator = new DummyDataCsvGenerator(); | ||
dummyDataCsvGenerator.writeMemberFile(); | ||
dummyDataCsvGenerator.writePortfolioFile(); | ||
} | ||
|
||
public void writeMemberFile() { | ||
String fileName = "src/main/resources/db/mysql/member.csv"; | ||
CSVFormat csvFormat = CSVFormat.Builder.create() | ||
.setHeader("id", "email", "nickname", "provider", "password", "profileUrl", "create_at") | ||
.setSkipHeaderRecord(false) | ||
.build(); | ||
List<String[]> members = createMemberDummyData(); | ||
boolean result = writeCsvFile(fileName, csvFormat, members); | ||
if (result) { | ||
log.info("success writing the member csv file"); | ||
} else { | ||
log.info("fail writing the member csv file"); | ||
} | ||
} | ||
|
||
private List<String[]> createMemberDummyData() { | ||
int recordCount = 5_000; | ||
List<String[]> result = new ArrayList<>(); | ||
for (long i = 1; i <= recordCount; i++) { | ||
String id = String.valueOf(i); | ||
String email = String.format("antuser%d@gmail.com", i); | ||
String nickname = String.format("antuser%d", i); | ||
String provider = "local"; | ||
String password = "$2a$10$zT6g60wI9rup2EvGbDRKa.D9N3RB5wMoFTlIGAaoZMxqX7R80pPQq"; | ||
String profileUrl = null; | ||
String createAt = LocalDateTime.now().toString(); | ||
result.add(new String[] {id, email, nickname, provider, password, profileUrl, createAt}); | ||
} | ||
return result; | ||
} | ||
|
||
public boolean writeCsvFile(String fileName, CSVFormat csvFormat, List<String[]> data) { | ||
try (FileWriter out = new FileWriter(fileName)) { | ||
CSVPrinter printer = new CSVPrinter(out, csvFormat); | ||
printer.printRecords(data); | ||
} catch (IOException e) { | ||
log.error(e.getMessage()); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
private void writePortfolioFile() { | ||
String fileName = "src/main/resources/db/mysql/portfolio.csv"; | ||
CSVFormat csvFormat = CSVFormat.Builder.create() | ||
.setHeader("id", "name", "securitiesFirm", "budget", "targetGain", "maximumLoss", "targetGainIsActive", | ||
"maximumLossIsActive", "createAt", "member_id") | ||
.setSkipHeaderRecord(false) | ||
.build(); | ||
List<String[]> portfolios = createPortfolioDummyData(); | ||
boolean result = writeCsvFile(fileName, csvFormat, portfolios); | ||
if (result) { | ||
log.info("success writing the portfolio csv file"); | ||
} else { | ||
log.info("fail writing the portfolio csv file"); | ||
} | ||
} | ||
|
||
private List<String[]> createPortfolioDummyData() { | ||
int recordCount = 5_000; | ||
List<String[]> result = new ArrayList<>(); | ||
for (long i = 1; i <= recordCount; i++) { | ||
String id = String.valueOf(i); | ||
String name = String.format("portfolio%d", i); | ||
String securitiesFirm = "토스증권"; | ||
String budget = "1000000"; | ||
String targetGain = "1500000"; | ||
String maximumLoss = "900000"; | ||
String targetGainIsActive = "true"; | ||
String maximumLossIsActive = "true"; | ||
String createAt = LocalDateTime.now().toString(); | ||
String memberIdString = "1"; | ||
result.add(new String[] {id, name, securitiesFirm, budget, targetGain, maximumLoss, targetGainIsActive, | ||
maximumLossIsActive, createAt, memberIdString}); | ||
} | ||
return result; | ||
} | ||
} |