- 공통 API 호출 함수인 getAjax()의 함수명 수정 -> callAjax() - 소스코드 구조 개선 필요 (단일 책임의 원칙:SRP) - 의도에 맞는 변수명 개선 (이름 지정 규칙: JavaScript Naming Conventions) - 특정 상황에 사용할 수 있는 정규표현식이 아닌 포괄적으로 사용할 수 있도록 하기
시연 영상
- 기본적으로 예약하기, 예약확인하기 화면이 영상에 보여야 함. - 예약하기시 -, + 버튼을 클릭해서 숫자가 변경되는 부분이 영상에 보여야 함. - 예매자 정보를 입력하고 총매수가 변경되는 것이 영상에 보여야 함. - 연락처 정보에 숫자와 숫자가 아닌 문자를 입력하는 과정이 영상에 보여야 함. - 약관의 접기/보기를 클릭해서 변경되는 화면이 영상에 보여야 함. - 동의버튼을 클릭해서 변경되는 화면이 영상에 보여야함. - 예약내용을 모두 올바르게 입력해서 '예약하기' 버튼이 선택가능한 상태로 활성화 되는과정이 영상에 보여야함. - 이메일을 유효하지 않은 정보를 입력해봄. - 취소를 눌러서 취소된 예약이 그부분이 노출되는지가영상에 보여야 함.
* 코드 - DB에 들어갈 date 필드 처리방식 - Setter 메서드로 도배된 Entity 클래스들 - @Autowired로 도배된 Spring DI 코드 - System.out.println()으로 이루어진 테스트 코드
* 운영 환경 - 배포된 서버와의 DB연결 - 배포 서버의 리눅스 기본 설정 - DB의 여러 설정들 - 직접 CI/CI 환경을 구축하는 방법 - 무중단 서비스를 위한 배포 방법 - Nginx의 설치 및 설정 - AWS RDS 필수 설정 - AWS EC2의 Security Group, EIP 등 기본설정 - Travis CI의 기본 설정
따로 알아봐야 할 내용들
Eclipse와 intelliJ 중 Java 개발에 더 좋은 것에 대한 의견
IntelliJ 사용방법 및 단축키
mavenCentral, jcenter
빌드 도구, Gradle, maven 차이점
TDD, DDD
lombok
assertJ
ORM, SQL Mapper 구분
JPA dirty Checking
JPA Auditing, JDK 8 이전의 Date와 Calendar 클래스의 문제점, 그리고 개선된 LocalDate
요약: 현재 프로젝트의 Terminal을 열어 아래 명령어를 복사해서 붙이면 Gradle 다운그레이드할 수 있음
gradlew wrapper --gradle-version 4.10.2
p.100 PostsApiController.save() Test Issue
save메서드를 보면 @putMapping(...)라고 되어 있는데 내용을 보면 Post 내용이기 때문에 @PostMapping으로 변경
p.111 PostsApiController.update() 취소 기능 Issue
PostsUpdateRequestDto 클래스 작성
Posts 클래스 내에 update() 작성
p.176 .ignore 파일에 application-oauth.properties 제외 했는데도 commit 할 때 계속 뜨는 경우
application-oauth.properties 파일이 이미 tracked 되고 있는 상태에서 .ignore 파일을 업데이트 할 경우 제대로 적용이 안되고 commit할 때 계속 나오는 경우가 존재한다. 해결책은 캐시를 비워 .ignore 파일이 제대로 적용되도록 한다.
p.194 권한 변경 후 글 등록 시
1. Application 실행 2. OAuth를 이용하여 구글 로그인 ( h2에 데이터가 들어가는 시점 ) 3. h2-console에서 권한 수정 udate usr set rold = "USER"; ( 이때 세션에는 아직 GUEST로 저장되어 있음 ) 4. 세션 정보를 최신화 시키기 위해서 로그아웃 후 다시 로그인해서 게시글 등록 시도
p.326 Travis CI .travis.yml 설정 후 build 이슈
./gradlew: Permission denied git에 permission을 업데이트 해줘야 travis가 실행할 수 있다.
.travis.yml에 before_install을 추가하여 permission을 바꾸는 방법
Git update를 통해 직접 permission을 바꾸는 방법
p. 338 S3 region 확인
AWS S3 대시보드 -> 생성한 bucket 클릭 -> 속성 -> 정적 웹 사이트 호스팅 클릭 시 엔드 포인트에서 확인 가능
p. 394 무중단 배포 테스트 후 게시물 등록 테스트
오류가 당연한 것이 security에서 처음 로그인한 상태가 GUEST이기 때문이다. USER로 변경 해줘야 게시물 등록을 할 수 있다.
바쁘다는 핑계로 프로젝트를 뒤로 미루다가 다시 하려니 생각이 잘 안나고.. 리펙토링 해야 할 부분도 많고, 답도 안나오고... 몇 개월전에 『테스트 주도 개발(Test-Driven Development: By Example)』이란 책을 읽고, 내게 부족한 부분을 채워줄 수 있을 것 같아서 흉내내 보았다.
이 글을 쓰는 시점은 PJT 4까지 완료하고 5개월이 지나고 PJT 5를 다시 시작하려한다.
- 목표 1. src/test/java 폴더에 class 파일 만들기 2. 테스트 클래스에 Annotation 적용하기 3. @Test Annotation을 적용한 테스트 메서드 만들기 4. Controller에 @Mockito 적용하여 API 테스트 작성
- 기존 테스트 코드
기존에도 소스 내에 print()만 안찍었지 비슷한 수준의 테스트 클래스를 작성하여 흉내만 냈었다.
- 카테고리 (/api/categories) 결과 값
위와 같은 자바 클래스를 Repository, Service까지는 대충 적용 되는 것처럼 보인다. 물론 테스트 코드에 대한 개념과 깊이가 없어 데이터를 출력해보는 것 이상의 정보는 보이지 않는다.
여기서부터가 문제인데 웹 프로젝트에서 request 값이 정상적으로 요청이 들어와 Service Layer, Repository Layer의 함수를 호출하는 것은
단순하게 함수를 호출하여 결과 값이 내가 만든 결과 값이 나오는지 확인이 가능하다.
Controller도 기존에 만들었던 똑같은 테스트 방식으로 파라미터 넣고 호출하도록 했었다.
하지만 Controller의 목적은 Model과 View간에 상호 동작을 관리 하는 것이다.
즉, View에서 request한 값을 받아 Model에 전해주고, Model의 결과 값을 View에 전달해주는 것
지금처럼 테스트 하면 View에서 request한 값을 받을 수 있는 방법이 없다.
그래서 적용한 것이 Mockito이다.
- dependency 추가
spring-test, junit은 기존에 쓰고 있었고, mockito-all만 새로추가
- Controller 테스트 코드
- Mockito 적용 전 참고해야할 설정
web.xml에 설정되어 있는 servlet 설정
AnnotationConfigWebApplicationContext - DispatcherServlet에게 annotation 기반의 자바 설정 로드 WebMvcContextConfiguration - 자바 베이스 스프링 설정
- 원격 시스템으로부터 파일을 효율적으로 복사하거나 동기화 가능 - Linux, device, 파일의 소유자와 그룹 권한(Permissions)등 파일의 부가정보도 복사 가능 - scp보다 빠름, rsync는 remote-update 프로토콜을 이용해서 차이가 있는 파일만 복사 (처음에는 모든 파일과 디렉토리를 복사 그 후부터는 차이가 있는 파일만 복사하기 때문에 더 빠르고 효율적) - 데이터를 압축해서 송/수신하기 때문에 더 적은 대역폭을 사용
Rsync의 동기화 알고리즘
1. 파일 전송 결정 1) 파일의 크기와 수정시간(modification)을 비교하는 것으로 파일을 전송 할지 말지를 결정 (일반적으로 파일의 내용을 변경하면 크기와 수정시간이 변하지만 항상 그렇다고 단정할 수는 없다는 예외가 있다.)
2) "--checksum" 의 옵션을 통해 비교 방법을 개선 (크기 / 시간을 이용한 비교 방법보다 안전하지만 더 느리고 더 많은 자원을 사용)
2. 전송할 파일 부분의 결정 1) 파일을 고정 크기를 가지는 청크(chunk)로 나누어 checksum을 계산
2) checksum을 서로 계산하여, 다를 경우 해당 부분의 청크만을 복사 (만일 파일의 앞 부분의 정보가 수정되어 정보가 밀릴 경우, 모든 chunk의 checksum이 어긋남)
- Rsync는 -e 옵션을 이용해서 ssh, rsh와 같은 remote shell 프로그램을 선택 가능 - -e 옵션이 없다면 ssh 사용 (default)
Rsync server 모드
Rsyn 데몬 프로그램 설정 - "--darmon" 옵션을 이용하여 서버 모드로 작동 - xinetd를 이용해서 시스템 서비스로 등록
[ xinetd 패키지 설치 ] 1. /etc/xinetd.d/rsync 설정 파일 만들기 2. rsync 설정파일은 /etc/rsyncd.conf (설정파일이 없는 경우 직접 만들어야 함) 1) 복사(동기화) 디렉토리로 /home/share를 선택 2) 읽기/쓰기 모두 가능 설정 3) 디렉토리에 대한 소유자는 nobody.nogroup, /home/share 소유자를 nobody.nogroup로 변경 4) 접속 허용 유저로 user을 추가 5) auth users에 대한 설정파일은 /etc/rsyncd.secrets에 저장 * /etc/rsyncd.serets 파일에 접속유저이름과 패스워드를 지정할 수 있다. (패스워드는 plain/text) 3. 읽기 테스트 4. 쓰기 테스트
# (*)를 사용하여 .bak 확장자를 포함하는 파일만 제외
rsync -avz --exclude '*.bak' {domain}@{targetIP}:{targetPath} {localPath}
Rsync delete 옵션
# "--delete" 옵션을 사용하여 삭제 후 복사
rsync -avz --delete {domain}@{targetIP}:{targetPath} {localPath}
Rsync 전송할 파일의 최대 크기 정하기
# "--max-size" 옵션을 이용해서 전송할 파일의 최대 크기를 정함
rsync -avz --max-size='10k' {doamin}@{targetIP}:{targetPath} {localPath}
Rsync 성공적으로 전송 후 원본파일 지우기
#"--remove-source-files"이용하여 전송이 끝난 후 원본 파일 삭제
rsync --remove-source-files -zvh {file} {경로}
Rsync Bandwidth 제한 설정
# "--bwlimit" 옵션을 이용하여 파일전송에 사용할 네트워크 대역폭을 제한
# 인터넷 서비스중인 서버에서, 다른 서비스에 영향을 주지 않는 범위내에서 파일 복사를 원할 경우 유용하게 사용
rsync --bwlimit=100 -avzhe ssh {localPath} {domain}@{targetIP}:{targetPath}