본문 바로가기

전체 글139

자바 Function.andThen 과 apply 작동 순서 아래 코드에서 httpClient 를 생성하는 로직을 보다가 andThen 과 apply 실행 순서가 헷갈려서 정리했다. public class ReactorClientHttpConnector implements ClientHttpConnector { private final static Function defaultInitializer = client -> client.compress(true); public ReactorClientHttpConnector(ReactorResourceFactory factory, Function mapper) { ConnectionProvider provider = factory.getConnectionProvider(); this.httpClient = default.. 2022. 8. 30.
네이버 SW 인턴 리쿠르팅 경험기 블로그로 시작된 인연 내 블로그 유입경로는 대부분 www.google.com 이다. 그러다 우연히 github repository 주소를 발견했고 신기해서 구경했다. 대학생들로 보이는 3~4 명이 프로젝트를 진행하고 있었다. 그중 한분(이하 A)이 CORS 에러를 해결해야 했고, 방법을 설명하면서 내 블로그를 참조했다. 그런데 해결 방법에 대한 글을 읽어 보니 내 블로그에서 말한 방식과 달랐다. 그래서 해당 github issue 에다 글을 남겼다. 남의 프로젝트에 갑자기 껴들어 훈수를 두는 모양새라 조심스러웠지만 기술적 의견만 담담하게 개진하면 기분나쁘게 받아들이지 않을거라 생각했다. 두번정도 의견을 주고받았고 재밌는 경험이었다. 다음날 리더님과 점심먹으면서 가볍게 말씀드렸더니 관심을 보이면서 인턴 얘.. 2022. 7. 26.
HTTP keep-alive on/off 에 따라 다른 결과가 나오는 이슈 문제 발생 HTTP request 받는 서버를 변경하면서 에러가 발생했다. 정상적인 경우라면 response body 에 key 값만 있어야 하는데, key 값(123456) 뒤에 에러메세지가 append 되고 있었다. 에러메세지는 HTTP response 에 해당하는 모든 정보였다. 123456HTTP%2F1.1+408+Request+Time-out%0D%0AContent-length%3A+110%0D%0A Cache-Control%3A+no-cache%0D%0AConnection%3A+close%0D%0AContent-Type%3A+text%2F html%0D%0A%0D%0A%3Chtml%3E%3Cbody%3E%3Ch1%3E408+Request+Time-out%3C%2Fh1%3E%0D%0A Your+.. 2022. 5. 29.
프로그래머뇌 청킹연습/표식찾기연습 - 3 [표식찾기 연습] 1단계 코드베이스 선택 owasp-java-html-sanitizer 에서 HtmlLexer 를 이해하기 위해 필요한 코드들 interface TokenStream { HtmlToken next(); boolean hasNext(); } abstract class AbstractTokenStream implements TokenStream { private HtmlToken tok; public final boolean hasNext() { if (tok == null) { tok = produce(); } return tok != null; } public HtmlToken next() { if (this.tok == null) { this.tok = produce(); } HtmlT.. 2022. 5. 25.
프로그래머뇌 청킹연습/표식찾기연습 - 2 [표식찾기 연습] 1단계 코드베이스 선택 owasp-java-html-sanitizer 에서 HtmlSanitizer 클래스의 sanitize 메서드 public static void sanitize( @Nullable String html, final Policy policy, HtmlStreamEventProcessor preprocessor) { String htmlContent = html != null ? html : ""; HtmlStreamEventReceiver receiver = initializePolicy(policy, preprocessor); receiver.openDocument(); HtmlLexer lexer = new HtmlLexer(htmlContent); // Use .. 2022. 5. 15.
프로그래머뇌 청킹연습/표식찾기연습 - 1 [표식찾기 연습] 1단계 코드베이스 선택 owasp-java-html-sanitizer 에서 PolicyFactory 클래스의 sanitize 메서드 public final class PolicyFactory ... public String sanitize( @Nullable String html, @Nullable HtmlChangeListener listener, @Nullable CTX context) { if (html == null) { return ""; } StringBuilder out = new StringBuilder(html.length()); HtmlSanitizer.sanitize( html, apply( HtmlStreamRenderer.create(out, Handler.DO_.. 2022. 5. 11.
주문서 테스트코드 작성 이슈정리 주문서 비지니스 로직은 복잡하다. 수많은 외부 API 결과들을 조합해서 만들어야 하기 때문이다. 이 글에선 주문서 테스트코드 작성 시 겪었던 이슈에 대해 정리했다. 주문은 범용적인 도메인이다. 내가 속한 팀의 특수한 부분만 빼고 재구성해서 설명했다. 1. 개발 진행 방식 주문등록을 하고 주문서 페이지가 보여지기까지 flow 를 하나의 테스트코드로 만들었다. 전체를 관통하는 작은 단위의 feature 와 테스트코드를 먼저 만들어, 테스트를 계속 통과시키면서 feature 들을 추가하는 Walking Skeleton 방식으로 개발을 진행했다. A Walking Skeleton is a tiny implementation of the system that performs a small end-to-end fu.. 2022. 5. 7.
비트코인 블록체인 바이블 매일 웹 애플리케이션만 개발하고 공부하다보니 살짝 지겨워졌다. 그래서 리프레시 겸 블록체인을 공부했다. 순전히 기술적인 관심으로 블록체인 구조가 궁금했다. 분산DB, 분산 클러스터 등 확장성을 고려한 개발은 익숙했기에 블록체인도 결국 분산 데이터 저장소 아닌가라는 생각으로 책을 읽기 시작했다. 완전히 틀린말은 아니지만 미시적 관점에서 블록체인의 형태학적 구조만으로 해석한 답이다. 책에서는 왜 비트코인이 세상에 나오게 됐는지 화폐 역사를 보여주면서 설명한다. 거시적 관점에서 블록체인은 단순한 저장소 이상의 가치를 갖고 있다는것을 알게 됐다. 블록체인 동작방식을 약 250 페이지에 걸쳐 수백개의 그림으로 단계단계 자세히 설명하는데 내부적인 기술에 관심이 많은 나로써는 정말 좋았다. 특히 공개키/개인키를 계속.. 2022. 4. 28.
아웃퍼포머 계속된 재택근무로 지쳐갔고 업무를 효율적으로 더 잘 하고 싶었다. 그러다 승지니어 유튜브 방송에서 이책을 알게 됐고 구매해 읽었다. 기존 자기계발 서적들과 큰 차이는 없었지만 몇몇 새로운 얘기들은 있었다. 순환주기마다 완성도를 높이자 내가 읽었던 자기계발 서적들('1만시간의 재발견', '아주 작은 습관의 힘')에서는 운동선수나 체스선수를 예로 들면서 지속적인 습관과 올바른 노력으로 발전 할 수 있다는것을 보여준다. 하지만 일반 직장인인 나는 그들과 상황이 많이 다르다. 먼저 성과를 수치화하기 어려운 경우가 많다. 그리고 수치화된 데이터를 갖고 지속적인 피드백을 받아 수정하는 노력이 필요한데, 나는 1년에 한번 연말평가로 피드백 받는게 전부다. 그래서 책을 읽었어도 구체적으로 내 삶에 맞게 적용하기 어려웠.. 2022. 3. 17.
Kafka 이벤트 발행과 DB 저장(redis) 트랜잭션 EDA 환경에서 일반적으로 kafka 이벤트 발행과 db 저장은 한 transaction 으로 묶을 수 없다. 물론 RDB 를 사용한다면 뒤에 서술할 Transactional Outbox Pattern 을 활용할 수 있다. 하지만 내가 속한 프로젝트는 redis in-memory nosql db 를 사용했다. 그래서 다른 방식으로 transaction 문제를 해결했다. cf) kafka transaction 에 대해서 더 자세히 알고 싶다면 이전 글에서 자세히 설명했다. 계좌이체 준비 예제 핵심부분만 추려서 코드를 재구성해, 계좌이체 준비 예제로 설명하려 한다. 먼저 아래 prepareAccountTransfer 메서드는 전달받은 processId와 userNo 를 갖고 AccountTransfer 객체.. 2022. 3. 9.
WebClient 사용할때 주의 (7편) webClient 사용할 때 주의사항까진 아니지만 리스트 형태의 response body 를 받는 방법에 대해서 간단히 정리했다. 가끔 Mono 형태로 리턴 webClient 코드를 볼 때가 있다. flatMapIterable 메서드로 Flux 를 사용하는게 좋다. public Flux getData() { return this.webClient.get() .uri(uriBuilder -> uriBuilder .path("/data") .build() ) .retrieve() .bodyToMono(DataApiResponse.class) .flatMapIterable(DataApiResponse::getContent); } @Value public class DataApiResponse { List co.. 2022. 3. 7.
rewrite break 이슈 만약 http://ybs.com/hello/world 요청을 nginx 서버가 받고 뒷단 서버(proxied server 또는 downstream server) 에 /world 경로만 전달해주고 싶다면 2가지 방법이 있다. 방법1 : rewrite + proxy_pass location /hello/ { rewrite ^/hello(/.*)$ $1 break; proxy_pass http://server.com; } rewrite 끝에 break flag 를 추가함으로써, 현재 rewrite 규칙이 적용되기는 하지만 nginx 가 수정된 URI 로 새롭게 일치하는 location 을 찾지 않도록 한다. 이후의 모든 rewrite 지시어는 무시된다. 방법2 : location 끝에 /(slash) 를 추가.. 2022. 2. 17.