[우아한테크코스] 8월 6일 TIL

2 minute read

[Spring] jackson 라이브러리

ObjectMapper API(MappingJacksonHttpMessageConverter)를 이용해 java의 객체를 json 구조로 매핑해준다.

getter, setter의 명명 규칙으로 정해진다.
getter없이 멤버변수로 데이터 매핑하고 싶다면 @JsonProperty("name")을 이용할 수 있다.

JsonAutoDetect

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)는 멤버변수 뿐 아니라 getter, setter의 데이터 매핑 정책도 정할 수 있다.

JsonInclude

@JsonInclude(Include.NON_NULL) 어노테이션으로 줄 수 있고,
this.objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);로도 줄 수 있다.

값이 null일 때 데이터를 출력하지 않도록 하는 설정이다.

  • ALWAYS
    기본값으로 모든 값을 출력한다.

  • NON_NULL
    null 제외

  • NON_ABSENT
    null 제외하고 Optional 값도 제외

  • NON_EMPTY
    null 제외, absent 제외, Collection이 empty면 제외, 배열이나 string 길이가 0이면 제외

  • NON_DEFAULT
    null 제외, absent 제외, Collection이 empty면 제외, 배열이나 string 길이가 0이면 제외, primitive default면 제외, timestamp 0이면 제외

해당 필드를 출력하고 싶지 않으면 @JsonIgnore로 필드에 어노테이션 부여할 수 있다.

@JsonIgnoreProperties({"id"})은 속성이나 속성 목록 무시

@JsonIgnoreType은 주석이 달린 형식의 모든 속성을 무시


[Infra] SonarQube 적용

정적 프로그램 분석이란? 실제 실행 없이 프로그램을 분석하는 것으로 소스 코드나 컴파일된 코드를 이용해 프로글램을 분석한다. 소스코드는 확인할 수 있지만 실행 환경에서의 상태는 정확히 알 수 없다.
정적 코드 분석 도구에는 pmd, findBugs, checkstyle, sonarqube 등이 있다.

정적 프로그램 분석을 통해 코드 점검, 품질 중앙화, devops 통합, 품질 요구사항 설정, 등의 이점을 얻을 수 있습니다.


docker에서

  1. docker pull sonarqube

  2. docker run -d --name sonarqube -p 8000:9000 sonarqube : d 옵션은 프로세스 끝나도 유지

  3. 서버:8000 으로 접속해 로그인 (초기는 admin, admin -> admin, zzimkkong1!)


jenkins 설정

  1. 젠킨스 관리

  2. 플러그인 관리

  3. available -> SonarQube Scanner 설치

  4. Manage Jenkins > Configure System > SonarQube Server 설정: add projects, environment variables 체크, 이름(아무거나), url(서버:8000) 등록

  5. Manage Jenkins > Global Tool Configuration > SonarQube servers 설정: 이름 SonarQube Scanner, maven Central 사용


build.gradle

buildscript {
    dependencies {
        classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
    }
}

apply plugin: "org.sonarqube"
sonarqube {
    properties {
        property "sonar.host.url", "http://zzimkkong-service.o-r.kr:8000"	// 설치 주소
        property "sonar.login", "admin"        // 로그인 id 또는 인증토큰
        property "sonar.password", "zzimmkkong1!"    // 인증토큰 사용시는 공백으로
        property 'sonar.sources', 'src'	//분석파일 경로
        property 'sonar.language', 'java'	//분석 코드 언어
        property 'sonar.projectVersion', '0.0.1-SNAPSHOT'	//분석 버전
        property 'sonar.sourceEncoding', 'UTF-8'
        property 'sonar.coverage.jacoco.xmlReportPaths', '${buildDir}/reports/jacoco/test/jacocoTestReport.xml'
        property 'sonar.java.binaries', '${buildDir}/classes'	//컴파일되면서 생성된 바이너리 파일 분석
        property 'sonar.test.inclusions', '**/*Test.java'	//분석에 사용할 테스트 코드 위치 지정
        property 'sonar.exclusions', '**/test/**, **/Q*.java, **/*Doc*.java, **/resources/**'	//제외 파일 위치 지정
    }
}
        property "sonar.host.url", "http://zzimkkong-service.o-r.kr:8000"
        property "sonar.login", "admin"
        property "sonar.password", "zzimmkkong1!"
        property 'sonar.sources', 'src'
        property 'sonar.language', 'java'
        property 'sonar.projectVersion', '0.0.1-SNAPSHOT'
        property 'sonar.sourceEncoding', 'UTF-8'
        property 'sonar.coverage.jacoco.xmlReportPaths', '${buildDir}/reports/jacoco/test/jacocoTestReport.xml'
        property 'sonar.java.binaries', '${buildDir}/classes'
        property 'sonar.test.inclusions', '**/*Test.java'
        property 'sonar.exclusions', '**/test/**, **/Q*.java, **/*Doc*.java, **/resources/**'
./gradlew sonarqube \
-Dsonar.projectKey=zzimkkong:test1 \
-Dsonar.host.url=http://zzimkkong-service.o-r.kr:8000 \
-Dsonar.login=5db700a3ce190fd7ed2913f3e068148d273dfac1 \
-Dsonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml

로 실행해서 url 들어가면 코드 분석된 것을 볼 수 있다.


jenkins stage에 SonarQube 분석 추가

빌드 시점에서 실행하려면 finalizedBy 로 실행 순서 부여 가능

Jenkinsfile build에 아래와 같이 설정

    stage('SonarQube analysis') {
      withSonarQubeEnv('SonarQube Scanner') {
        sh 'cd back && ./gradlew --info sonarqube' +
        ' -Dsonar.projectKey=Jikgorae-' + env.BRANCH_NAME +
        ' -Dsonar.projectName=Jikgorae-' + env.BRANCH_NAME
      }
    }


빌드 시점에 실행하기

build.gradle에 아래와 같이 설정

project.tasks["jacocoTestCoverageVerification"].finalizedBy "sonarqube"

sonarqube {
    properties {
        property "sonar.host.url", "http://zzimkkong-service.o-r.kr:8000"
        property "sonar.login", "5db700a3ce190fd7ed2913f3e068148d273dfac1"
        property 'sonar.sources', 'src'
        property 'sonar.language', 'java'
        property 'sonar.projectVersion', '0.0.1-SNAPSHOT'
        property 'sonar.sourceEncoding', 'UTF-8'
        property 'sonar.coverage.jacoco.xmlReportPaths', 'build/reports/jacoco/test/jacocoTestReport.xml'
        property 'sonar.java.binaries', 'build/classes'
        property 'sonar.test.inclusions', '**/*Test.java'
        property 'sonar.exclusions', '**/Q*.java, **/*Doc*.java, **/resources/**'
    }
}


분석에 대해서

  • Code Smell : 심각한 이슈는 아니지만 베스트 프렉티스에서 사소한 이슈들로 모듈성(modularity), 이해 가능성(understandability), 변경 가능성(changeability), 테스트 용의성(testability), 재사용성(reusability) 등이 포함
  • Bugs : 일반적으로 잠재적인 버그 혹은 실행시간에 예상되는 동작을 하지 않는 코드
  • Vulnerabilities : 해커들에게 잠재적인 약점이 될 수 있는 보안상의 이슈로 SQL 인젝션, 크로스 사이트 스크립팅과 같은 보안 취약성 발견
  • Duplications : 코드 중복
  • Unit Test : 단위테스트 커버리지를 통해 단위 테스트의 수행 정도와 수행한 테스트의 성공/실패 정보
  • Complexity : 코드의 순환 복잡도, 인지 복잡도
  • Size : 소스코드 사이즈

참고