728x90

async 처리를 할때 로그인된 정보를 가져 올 수 없는 문제를 부딪쳤다.

 

@async 처리가 아닌 경우에는 aspectj 에서 로그인 정보를 정상적으로 가져오지만 async 처리 시에는 해당 정보를 호출시 NPE 에러가 떨어졌다.

 

해당 문제를 해결하기 위해 구글링을 하던중에 아래와 같은 해결 방법을 보게 되었다.

아래는 stackoverflow 

 

https://stackoverflow.com/questions/5246428/spring-security-and-async-authenticated-users-mixed-up

 

Spring Security and @Async (Authenticated Users mixed up)

I asynchronously invoke a method with Spring, using @Async. This method invokes another method annotated with @PreAuthorize, the Spring Security Annotation. To make the authorization work I have to...

stackoverflow.com

 

2가지 방법을 확인하였는데 나는 아래의 방법을 참조하여 해결하였다.

 

첫 번째 해결방법

public void execute(final Runnable r) {
    final Authentication a = SecurityContextHolder.getContext().getAuthentication();

    super.execute(new Runnable() {
        public void run() {
            try {
                SecurityContext ctx = SecurityContextHolder.createEmptyContext();
                ctx.setAuthentication(a);
                SecurityContextHolder.setContext(ctx);
                r.run();
            } finally {
                SecurityContextHolder.clearContext();
            }
        }
    });
}

 

위와 같이 excute 실행 전 authentication을 변수에 담아 두었다가 실행시 재 설정해주는 방법이다 .

 

 

실제 적용 코드

 

두번째 방법

config 설정 시 아래와 같이 설정하는 방법이 있다.

@Bean("threadPoolTaskExecutor")
public TaskExecutor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(20);
    executor.setMaxPoolSize(1000);
    executor.setWaitForTasksToCompleteOnShutdown(true);
    executor.setThreadNamePrefix("Async-");
    executor.initialize(); // this is important, otherwise an error is thrown
    return new DelegatingSecurityContextAsyncTaskExecutor(executor);
}

 

다음에 같은 문제가 발생한다면 config 로 공통적으로 해결이 가능하게 수정하면 좋을것 같다는 생각이 작성중에 들어 전체 리소스 리팩토링을 진행해야 할듯 하다.

728x90

'코드 > dev' 카테고리의 다른 글

java dateTime 타임존  (2) 2023.11.22
Junit test filtering  (2) 2023.11.17
저장소에 올라간 브랜치 되돌리기  (2) 2023.11.15
spring AOP & AspectJ  (1) 2023.11.15
mariaDB Schedule  (3) 2023.11.14
728x90

간혹 작업을 하다보면 하나의 리소스에 여러 브랜치를 만들어 작업을 하게 되는 경우가 있다.

A 브랜치를 올려서 배포를 해야하는데 모르고 B 브랜치 를 리베이스하여 올리게되는 큰 실수를 하게되었다…(작업은 역시 순차적으로 하나씩 처리하고 배포는 신중히..)

일단 문제를 해결하여야 하니
현재 재직중인 회사에서는 git tag 를 생성하여 배포를 하고 있어서 배포를 이전 배포 버전으로 재배포를 진행 후

1.이전 태그로 리셋
git reset --hard {tagName}
- 해당 태크 상태로 돌아가기

2.저장소 이전 태크 버전으로 변경
git push origin master- 해당 브랜치 저장소 재 push


이전 태크로 push를 하게 되면 아래와 같은 error를 마주하게된다.

error: failed to push some refs to …
로컬 저장소의 커밋 히스토리가 원격 저장소의 커밋 히스토리보다 뒤쳐져 있는데 푸시를 하였으므로 발생하는 에러이다.


이떄 당황하지 않고 아래와 같은 옵션을 이용하면 해결된다.

git push -f origin master- f는 force의 약자

 

 

 

위와 같은 방법으로 해결 이후 짧게 회고를 해보자면 항상 조심 또 조심해야 겠다는 생각이들고

뭔가 잘못되었을 때도 항상 침착함을 유지하고 빠르게 대처하는게 중요하다는걸 새삼 느낀다..

728x90

'코드 > dev' 카테고리의 다른 글

Junit test filtering  (2) 2023.11.17
비동기처리 시 Spring security 문제  (1) 2023.11.16
spring AOP & AspectJ  (1) 2023.11.15
mariaDB Schedule  (3) 2023.11.14
RestTemplate Get RequestBody 전송  (0) 2023.11.14
728x90

회사에서 데이터가 update가 이루어 질 시 이력 로그를 쌓아달라는 요청을 받아 어떤 방법으로 작업을 진행할까 하다가 
AOP와 ASpectJ 복습 겸 정리를 진행하게되었다.

 

  • AOP 란?
점 지향 프로그래밍(Aspect Oriented Progamming) 기법은 객체지향을 보완하는 수단으로, 흩어진 관점(Aspect)를 모듈화 하여 비즈니스 로직을 헤치지 않고 재사용하는 프로그래밍 기법이다.

 

 

 

스프링에서는 AOP를 쉽게 사용 할 수 있도록 어노테이션을 지원한다.

아래는 참고 코드와 컨테이너에서 어떻게 동작하는지를 보여주는 참고 이미지

 

 

 

  • AOP 용어
Aspect - 애플리케이션 내 여러 군데에 흩어져있는 코드/기능이며, 실제 비즈니스 로직과는 다릅니다.(예를 들면, 트랜잭션관리). 각 Aspect는 고유한 Cross-Cutting 기능에 초점을 맞추고 있습니다. 쉽게 말하면, 여러 객체에 공통적으로 적용되는 관심 사항을 Aspect라고 합니다.

쉽게 말하면, 여러 객체에 공통적으로 적영되는 관심 사항을 Aspect라고 합니다.

Joinpoint - 프로그램이 실행 중일 때 발생하는 메서드 실행, 생성자 호출, 필드 값 변경과 같은 특수한 지점을 의미

Advice - 특정 Joinpoint의 Aspect에 의한 동작을 의미합니다. 대상 객체의 Joinpoint에 Weaving되어 동작할 수 있는 코드를 의미합니다.

Pointcut - Joinpoint의 정규표현식, Joinpoint가 Pointcut에 일치할 때마다 해당Pointcut에 관련된 Advice가 실행됩니다.

Weaving - Aspect를 대상 객체에 연결시키 관점지향 객체로 만드는 과저을 의미합니다. Advice를 비즈니스 로직 코드에 삽입하는것을 의미합니다.

 

 

  • AspectJ란?
AspectJ 는 자바에서 완벽한 솔루션 제공을 목표로하는 기술

[ .aj 파일]을 이용한 assertj 컴파일러를 추가로 사용하여 컴파일 시점이나 JVM 클래스 로드시점에 조작한다.

런타임 시점에는 영향끼치지 않는다.

. 즉 컴파일이 완료된 이후에는 앱 성능에 영향이 없다.

밑에서 몸으로 느끼겠지만, Spring AOP에 비해 사용방법이 다양하고 내부 구조가 굉장히 복잡하다.

 

 

 

  • AspectJ와 Spring Aop 비교하기
1.기능과 목표가 다르다
Spring AOP는 프로그래머가 직면하는 일반적인 문제 해결을 위해 Spring IoC에서 제공하는 간편한 AOP 기능이다. 어디에나 쓸 수 있는 완벽한 AOP 솔루션이 아니라, Spring 컨테이너가 관리하는 Bean 에만 사용하려고 만들었고, 실제로 여기에만 AOP를 적용 할 수 있다.

AspectJ는 자바코드에서 동작하는 모든 객체에 대한 완벽한 AOP 솔루션 제공을 목표로 하는 기술이다. 성능이 뛰어나고 기능이 매우 강력하지만 그만큼 Spring AOP에 비해 사용방법이나 내부 구조가 훨씬 더 복잡하다.

2. Weaving 방법이 다르다.
Weaving은 공통관심사항(Aspect)의 동작코드(Advice)를 대상 객체(Target)에 연결시켜 관점지향을 구현한 객체로 만드는 과정이다.

좀 더 쉽게 말하면 AOP를 구현하기 위한 바이트코드 조작 방법을 의미한다고 생각하면 된다.

소스코드로 위빙을 구현(Source-code Weaving)하는게 가장 좋긴 하겠지만, 현재까지 자바언어가 제공하는 기능으로 완벽한 AOP를 구현하기 어렵다.

728x90

'코드 > dev' 카테고리의 다른 글

Junit test filtering  (2) 2023.11.17
비동기처리 시 Spring security 문제  (1) 2023.11.16
저장소에 올라간 브랜치 되돌리기  (2) 2023.11.15
mariaDB Schedule  (3) 2023.11.14
RestTemplate Get RequestBody 전송  (0) 2023.11.14
728x90

새해에 1월1기점으로 배송 스케쥴 을 변경 을 해야하는 일이 발생 하였다. 당장 배치나 테이블을 수정이나 화면을 붙일 수 없는 상황이라 일회성으로 가능한 방법을 찾아보다 디비 자체에서 특정 시점부터 스케쥴을 돌 수 있는 방법을 찾았다.

 

이벤트 사용을 위한 설정

2가지 방법이 있다. 스케쥴을 사용 시 영구적으로 적용하는 방법과 디비 재시작 전까지 옵션을 적용하는 방법 나의 경우 1회성으로 진행을 위해 후자를 선택했다 .

 

영구적용 방법

50-server.cnf에 하단 코드를 추가하고 mariaDB를 다시 시작한다.

event_scheduler = ON

 

DB 재시작 전까지 적용 하는 방법

SET GLOBAL event_scheduler = ON;

 

옵션 정상 적용 되었는지 확인

SHOW variables LIKE 'event%';

 

 

 

이벤트 만들기

 

조건 2023년 1월 1일 부터 적용!

아래는 직접 만들었던 이벤트이다.

CREATE EVENT IF NOT EXISTS auto_logistics_event_dev
ON SCHEDULE
AT '2022-12-23 17:08:00' -- 특정 시간에 1회 실행
ON COMPLETION NOT PRESERVE -- 이벤트 수행 후 삭제여부 (삭제)
ENABLE
COMMENT '배송센터변경 이벤트 개발 테스트'
DO -- 경상남도, 부산, 울산 배송센터 부산으로 변경
UPDATE delivery_auto_logistics_center dalc
, (SELECT srl , group_srl , group_name , address_mgr_no FROM delivery_auto_logistics_center WHERE group_name = '북원주물류센터') dalc2
SET dalc.group_name = dalc2.group_name
, dalc.group_srl = dalc2.group_srl
, dalc.address_mgr_no = dalc2.address_mgr_no
WHERE dalc.group_name ='서원주물류센터';
COMMIT;
END;

 

CREATE EVENT IF NOT EXISTS delivery_dayofweek_info_dev
ON SCHEDULE
AT '2022-12-26 12:10:00' -- 특정 시간에 1회 실행
ON COMPLETION NOT PRESERVE -- 이벤트 수행 후 삭제여부 (삭제)
ENABLE
COMMENT '지역별 배송스케쥴 이벤트 개발 테스트'
DO -- 원주시 68, 춘천시 72 월 부터 토
UPDATE delivery_dayofweek_info
SET upd_date =NOW()
, mon=1
, tue=1
, wed=1
, thu=1
, fri=1
, sat=1
, rdc_load_sat=1
WHERE city_sn IN(68, 72); -- 화천군 76, 정선군 70 화
UPDATE delivery_dayofweek_info
SET
upd_date =NOW()
, mon=0
, tue=1
, wed=0
, thu=0
, fri=0,
sat=0
, rdc_load_sat=1
WHERE city_sn IN(76, 70); -- 양구군 65, 영월군 67 목
UPDATE delivery_dayofweek_info SET upd_date =NOW()
, mon=0
, tue=0
, wed=0
, thu=1
, fri=0,
sat=0
, rdc_load_sat=1
WHERE city_sn IN(65, 67); -- 평창군 74 화 금
UPDATE delivery_dayofweek_info
SET upd_date =NOW()
, mon=0
, tue=1
, wed=0
, thu=0
, fri=1
, sat=0
, rdc_load_sat=1
WHERE city_sn IN(74); -- 횡성군 77 홍천군 75 월 수 금
UPDATE delivery_dayofweek_info SET upd_date =NOW()
, mon=1
, tue=0
, wed=1
, thu=0
, fri=1, sat=0
, rdc_load_sat=1
WHERE city_sn IN(77,75); -- 상차일 변경 원주 월 -금 -> 월 -토 - 토요일만 추가 -- 서원주 물류센터 사용어부0
UPDATE delivery_center SET is_use = 0 WHERE center_name='서원주물류센터';
COMMIT;
END;

 

  • 수정방법
ALTER EVENT EVENT_TEST

ON SCHEDULE

— 스케쥴 시간

DO

—이벤트

INSERT INTO T_3 ( C_1 ) VALUES ( 'B' )

;
  • 삭제
DROP

EVENT
EVENT_TEST;
  • 이벤트 조회
SHOW

EVENTS
;

 

 

728x90

'코드 > dev' 카테고리의 다른 글

Junit test filtering  (2) 2023.11.17
비동기처리 시 Spring security 문제  (1) 2023.11.16
저장소에 올라간 브랜치 되돌리기  (2) 2023.11.15
spring AOP & AspectJ  (1) 2023.11.15
RestTemplate Get RequestBody 전송  (0) 2023.11.14
728x90

[org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

 

이직 후 회사에서 작업 을 진행하다 RestTemplate GET 방식에 body 를 넣는 코드를 작성 테스트중 특이한 점을 발견했다.

위와 같은 오류가 발생..

 

분명 postman 전송 테스트 시에는 잘 받았는데 실제 전송 을 호출하니 바디를 찾지 못해서 난감했다.

 

 

결론부터 말하자면

디폴트인 ClientHttpRequestFactory와 함께 RestTemplate를 사용하면,

JDK의 HttpURLConnection은 기본적인 HTTP client 이다.

HttpURLConnection은 GET요청과 함께 요청 바디를 보내지 않는다.

 

해결방안은 아래와 같다.

 

구글링으로 참조한 글

https://velog.io/@gkdud583/Spring-testrestTemplate-request-body-GET%EC%9A%94%EC%B2%AD

 

[Spring] testrestTemplate request body, GET요청

testrestTemplate를 이용해 코드를 작성하면서, 이상한 점을 발견했다.testrestTemplate.exchange()를 이용해, 요청 바디와 함께 GET요청을 보냈는데, 다음의 예외가 발생하면서 테스트에 실패했다. 그래서 tes

velog.io


아래는 stackoverflow 참조한 해결방안

https://stackoverflow.com/questions/62309635/resttemplate-get-with-body

 

RestTemplate get with body

How to make get with body using rest template? Based on question from: POST request via RestTemplate in JSON, I tried make GET with body via HttpEntity (just check if it is possible), but it failed

stackoverflow.com

 

해결방법으로 body factory 를 변경하는 방법도 확인했지만 적용을 하는게 좋을지는 판단이 되지 않아서,

기존에 Request Body로 받는 부분은 전송 시 queryString 과 엔드 포인트에서는 modelAttribute 로 받도록 처리를 변경하였다.

728x90

'코드 > dev' 카테고리의 다른 글

Junit test filtering  (2) 2023.11.17
비동기처리 시 Spring security 문제  (1) 2023.11.16
저장소에 올라간 브랜치 되돌리기  (2) 2023.11.15
spring AOP & AspectJ  (1) 2023.11.15
mariaDB Schedule  (3) 2023.11.14

+ Recent posts