Vagrant - 기본

DevOps|2017. 6. 2. 19:10

윈도(Windows)를 주로 사용하지만 리눅스 환경이 필요한 경우가 많아서 Vagrant를 그간 꾸준히 사용해 왔다. 정리를 위해 Vagrant에 대한 개요와 기본 사용법을 정리해 본다.

설치

우선 Vagrant와 VirtualBox의 설치가 필요하다. 아래 주소에서 내려받아서 설치한다.

Vagrantfile 생성

vagrant init 명령을 실행하면 현재 폴더에 Vagrantfile을 생성한다. 아래와 같이 Box의 이름을 추가하면 해당 박스를 사용하는 Vagrantfile을 생성한다.

vagrant init bento/centos-7.3

이렇게 생성한 Vagrantfile에는 다량의 주석이 포함되어 있어서 이 주석만 잘 읽어봐도 기본적인 설정 방법을 아는데 무리가 없다.

Box 검색

원하는 리눅스 배포본과 버전의 Box를 아래 주소에서 검색할 수 있다.

각 리눅스 배포본 제공자의 오피셜 박스를 사용하는게 안전하다. 다만 CentOS의 경우는 Bento 프로젝트에서 제공하는 박스도 많이 사용하는 것 같다.

Vagrant machine 생성

vagrant up

위 명령을 Vagrantfile이 있는 폴더에서 실행하면 가상 머신이 생성된다.

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'bento/centos-7.3'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'bento/centos-7.3' is up to date...
==> default: Setting the name of the VM: Documents_default_1496384515554_86818
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Remote connection disconnect. Retrying...
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/daniel/vagrant-test

Vagrant machine에 SSH로 접속

vagrant ssh

위 명령을 Vagrantfile이 있는 폴더에서 실행하면 vagrant 사용자로 가상 머신에 SSH로 접속이 된다.
PuTTY 등의 SSH 클라이언트로 접속하려면 127.0.0.1:2222에 vagrant로 접속하면 된다. 암호 또한 vagrant다. 2222 포트로 접속하는 이유는 기본으로 가상 머신의 22 포트와 호스트 머신의 2222 포트가 port forwarding 방식으로 연결되어 있기 때문이다. 이미 다른 가상 머신이 2222 포트를 사용 중이면 다른 포트가 자동으로 할당되며, 이는 실행 로그를 통해 알아내면 된다.

Vagrant machine을 다루는 기본 명령

삭제(terminate)

vagrant destroy

정지(shutdown, poweroff)

vagrant halt

가상 머신을 끈다.

재시작(reboot, halt and up)

vagrant reload

가상 머신을 재시작한다. 정지 후 시작하는 것과 동일하다.

일시 중지(suspending)

vagrant suspend

현재의 동작 상태를 저장한 상태로 정지한다. 다시 시작하면 부팅 과정 없이 저장한 지점에서 바로 시작한다.

다시 시작(resume)

vagrant resume

일시 중지 상태의 가상 머신을 이전 지점에서 다시 시작한다.

상태 확인(status)

vagrant status

가상 머신의 상태를 확인한다. 정지 상태면 poweroff로 표시되고 정상 동작 중이면 running으로 표시된다.


EOF

댓글()

Vagrant 공유 폴더 문제(mount.vboxsf 관련) - vagrant-vbguest 플러그인

DevOps|2017. 5. 29. 19:43

Vagrant를 이용해 apache brooklyn을 학습하던 중에 갑자기 brooklyn 서버가 동작을 안하는 문제가 생겼습니다. 최초로 VM을 생성했을 때는 마운트에 문제가 없었는데 재부팅을 하면 문제가 생깁니다.

이런저런 방법으로 추적해 봤더니 결국 Vagrant 혹은 VirtualBox에서 발생한 오류 때문이더군요.

brooklyn 서버의 /vagrant로 마운트되는 VirtualBox 공유 폴더가 마운트 안되는 문제인데, 아래와 같은 오류 메시지가 출력됩니다.

==> brooklyn: Mounting shared folders...
    brooklyn: /vagrant => G:/workspace/apache-brooklyn-0.11.0-vagrant
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=1000,gid=1000 vagrant /vagrant

The error output from the command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

구글링을 해보니, VirtualBox Guest Additions 설치에 문제가 있어서 그런 것 같습니다. 여러 가지 시도를 해봤는데 결국 vagrant-vbguest 플러그인을 설치해서 해결했습니다.

vagrant-vbguest 플러그인은 guest machine과 VirtualBox host의 Guest Additions 버전이 다를 경우에 알맞은 버전을 설치해 주는 플러그인입니다.


   vagrant-vbguest 플러그인 설치

아래의 명령으로 설치합니다.

$ vagrant plugin install vagrant-vbguest
Installing the 'vagrant-vbguest' plugin. This can take a few minutes...
Installed the plugin 'vagrant-vbguest (0.14.2)'!

이미 생성한 box에 적용하려면 아래의 명령으로 수동으로 설치할 수 있습니다.

$ vagrant vbguest

Guest Additions가 설치된 후 vagrant reload 명령으로 vagrant machine 재시작하니까 공유 폴더가 제대로 마운트되는 것을 실행 로그에서 확인할 수 있었습니다.

지금까지 Vagrant를 사용하면서 Guest Additions 설치에 대해서 고민한 적이 없었는데, 관련 문제를 vagrant-vbguest를 통해 해결하면서 수행 로그를 보니, 꽤 수고스러운 작업을 대신 해 주는 고마운 플러그인이네요. 어쩌면 필수 플러그인이 아닐까 싶습니다.


EOF


댓글()

외부 Jenkins와 내부 네트워크 상의 GUITAR 테스트 환경 연동 2

DevOps|2017. 5. 26. 18:39

테스트 수행 VM을 Jenkins의 Slave Node로 등록

VM2를 Jenkins의 Slave Node로 추가합니다. 방법에 대해서는 아래 글을 참고하세요.

젠키스(Jenkins)에 노드(node) 추가하기

  Jenkins 대시보드에 테스트 리포트 주소 링크

Jenkins 메인 화면의 상세 내용 입력을 클릭한 후 이전 글에서 확인한 VM2의 GUITAR 리포트 주소 (http://<랩탑의 내부 아이피>:8080/report.htm)의 링크를 입력합니다.
이 링크를 통해서 Jenkins 사용자들이 테스트 리포트를 볼 수 있습니다.

만약 HTML 코드가 그대로 노출된다면 아래 글을 참고해서 진행하세요.

젠킨스(Jenkins)의 상세 내용 입력 방식을 HTML로 변경

  Jenkins에 GUITAR 테스트 프로젝트 추가

Jenkins의 새로운 Item 메뉴를 클릭하여 새로운 프로젝트를 생성합니다.

Item name에는 GUITAR_TEST를 입력하고 Freestyle project를 클릭하여 선택하고 저장합니다.


General → Restrict where this project can be run 항목을 체크하고 Label Expression에 위에서 생성한 Slave Node 이름을 입력합니다. 저의 Slave Node 이름은 GUITAR_TEST_NODE입니다.

Build → Add build step → Execute Windows batch command를 선택하고, Command 항목에는 아래의 명령을 입력합니다. 샘플 테스트 스크립트인 네이버 검색을 수행하는 명령입니다. <작업 폴더>/TESTCASE 폴더는 본인의 환경에 맞게 수정하세요.

cmd /c C:\GUITAR\BIN\guitar.exe E:\TESTCASE\SAMPLE\01_네이버검색\01_네이버검색.txt /TESTID:%BUILD_ID% /XMLPATH:%WORKSPACE% /REMOTE

빌드 후 조치 → 빌드 후 조치 추가 → Publish JUnit test result report를 선택하고, Test report XMLs 항목은 비워 두거나 report.xml을 입력합니다.

저장 버튼을 클릭하여 설정을 저장합니다.

  Jenkins에서 테스트 수행

GUITAR_TEST 프로젝트 화면에서 Build Now 버튼을 클릭하여 테스트를 수행합니다. VM2에서 Slave Node가 실행 중이고 이 Node에서 배치 명령이 실행되도록 프로젝트가 구성되었기 때문에, VM2에서 GUITAR 테스트가 수행됩니다.

수행결과는 테스트 서버와 공유한 VM2 리포트 폴더에 저장됩니다.

테스트 서버는 이 리포트 폴더를 웹으로 서비스하기 때문에 Jenkins 대시보드에 추가한 링크를 이용하면 테스트 결과 리포트를 볼 수 있습니다.


EOF


댓글()

외부 Jenkins와 내부 네트워크 상의 GUITAR 테스트 환경 연동 1

DevOps|2017. 5. 25. 18:30

이 글에서는 퍼블릭 IP를 가지고 외부에 설치된 Jenkins와 내부 네트워크의 Windows 랩탑에서 실행되는 GUITAR 테스트의 연동 방법에 대해서 다룹니다.
GUITAR 2.0.0.12 버전의 사용자 가이드에서 제시하는 내용을 실무에 적용한 경험을 정리했다고 보시면 됩니다. 따라서 부족한 부분은 GUITAR 사용자 가이드로 보충하면 되겠습니다.

  랩탑 설정

랩탑에는 톰캣과 VitualBox를 설치합니다.
톰캣은 Jenkins와 연동하여 각 테스트 환경(VM)의 테스트 리포트를 보여주기 위한 용도이며, VirtualBox는 실제 테스트를 수행하거나 테스트 스크립트를 작성할 VM을 운용하기 위해서 필요합니다.

  VirtualBox 설치 및 설정

VirtualBox를 다운로드 한 후 설치합니다. VirtualBox Extension Pack도 꼭 같이 설치해 주세요.
https://www.virtualbox.org/wiki/Downloads

GUITAR 테스트를 작성 및 수행할 OS를 기반으로 가상 머신(VM)을 2개 만듭니다. Windows 7을 추천합니다.

랩탑의 적당한 위치에 아래의 폴더를 만듭니다.

  • GUITAR_DATA - 모든 VM이 공유하는 GUITAR 작업 폴더
  • GUITAR_REPORT1 - VM1의 리포트 공유 폴더
  • GUITAR_REPORT2 - VM2의 리포트 공유 폴더

VM1은 테스트 작성용, 다른 하나(VM2)는 테스트 수행용이지만 테스트 서버에서 리포트를 보기 편하도록 각 VM의 REPORT 폴더를 테스트 서버(랩탑)와 공유하도록 설정하려고 합니다.

VirtualBox 관리자에서 VM2를 선택하고 설정(S) 메뉴를 클릭합니다.

공유 폴더를 클릭한 후 + 기호가 있는 공유 추가 버튼을 클릭하여 위에서 생성한 GUITAR_REPORT2의 경로를 폴더 경로에 입력하고 자동 마운트(A) 옵션을 체크하고 저장합니다.

마찬가지 요령으로 공유 작업 폴더를 추가하고, VM1에도 동일하게 공유 폴더를 추가합니다.

VM2에서 파일 탐색기를 띄워서 확인해 보면, 위에서 추가한 공유 폴더가 각각 E:\F:\ 드라이브로 매핑된 것을 볼 수 있습니다.


이제 각 VM에 GUITAR를 설치합니다.

VM2에는 Jenkins 연동을 위해서 추가로 Java SDK를 설치합니다.
랩탑에서 다운로드 한 후 공유 폴더를 이용해서 각 VM에서 설치토록 하면 편합니다.

각 VM에서 C:\GUITAR\BIN\guitar.ini을 편집기로 열고 리포트 폴더의 위치를 리포트 공유 폴더 위치로 변경합니다. Path = ..\Report 문자열을 검색한 후 공유 폴더 위치로 값(..\Report)을 변경하면 됩니다. 저는 F:\로 변경했습니다.

[REPORT]
AreaCaptureView = 세로
FullSizeImage = False
TestServerName =
OpenReport = True
OpenDashboardReport = False
LimitCount=100
;Path = ..\Report
Path = F:\
DashboardHost = http://localhost:8080
XMLReport = False

마찬가지로 작업 폴더의 위치도 랩탑과 공유한 작업 폴더 위치로 변경합니다. WorkPath = 문자열을 검색한 후 값을 변경하면 됩니다. 저는 E:\로 변경했습니다.

[SCRIPT]
;WorkPath = C:\GUITAR\DATA
WorkPath = E:\
;SVNPath = https://dev.naver.com/svn/guitar/xxxxx/branches/yyyyyy
PreLoadScript = 공용변수.txt
TemplateScript = 기본템플릿.txt
;PreRun ="%BINPATH%\gitpull.bat" %WorkPath%

마지막으로 VM1의 C:\GUITAR\DATA 폴더의 내용물을 공유 작업 폴더로 모두 옮겨 주고, 각 VM의 C:\GUITAR\Report 폴더의 내용물을 각각의 공유 폴더로 모두 옮겨줍니다.
작업 폴더는 모든 VM이 공유하기 때문에 VM1에서만 옮기면 모두가 공유합니다. 리포트 폴더에는 우리가 연동을 위해 사용할 스크립트와 실행 파일 등이 있기 때문에 옮겨줄 필요가 있습니다.

  Tomcat 설치

랩탑에 톰캣을 다운로드 한 후 적당한 곳에 설치합니다.
http://tomcat.apache.org/download-60.cgi

%TOMCAT_HOME%/conf/Catalina/localhost 폴더를 생성하고, 다시 ROOT.xml 파일을 아래 내용으로 생성합니다. docBase 속성의 값은 위에서 생성한 GUITAR_REPORT2 폴더의 경로입니다. 저는 F:/GUITAR_REPORT2로 넣었습니다.

<Context path="/" docBase="F:/GUITAR_REPORT2" reloadable="true"/>

URIEncoding 오류를 방지하기 위해서 아래와 같이 %TOMCAT_HOME%/conf/server.xml 파일의 8080 포트 커넥터 설정을 변경합니다.

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           edirectPort="8443" URIEncoding="UTF-8" useBodyEncodingForURI="true" />

톰캣을 실행한 후 VM2의 GUITAR 리포트 주소 (http://<랩탑의 내부 아이피>:8080/report.htm)로 접속하여 연동이 잘 됐는지 확인합니다.

너무 길어져서 다음 글에서 이어 가겠습니다.


EOF

댓글()

애플 무선 키보드를 윈도(Windows)에서 편리하게 사용하는 방법

기타|2017. 5. 20. 10:27

애플 무선 키보드를 윈도에서 조금이라도 편하게 사용하려면 uxsoft의 Apple Wireless Keyboard를 설치해 보세요.
몇 가지 좋은점이 있습니다.

  • 볼륨 조절, 음악 재생기 제어 등의 기능키를 사용할 수 있습니다
  • DELETE 키를 사용할 수 있습니다(fn + delete)
  • Page Up, Page Down, Home, End 키를 사용할 수 있습니다(추가 설정이 필요합니다)

Apple Wireless Keyboard 는 다음 링크에서 다운로드할 수 있습니다. 아래쪽에 있는 Download 버튼을 클릭하세요.
http://uxsoft.cz/Projects/AppleWirelessKeyboard

참고로 제 설정의 스크린샷을 남깁니다.

 

EOF

댓글()

젠킨스(Jenkins)의 상세 내용 입력 방식을 HTML로 변경

DevOps|2017. 5. 18. 19:30

젠킨스의 메인이나 작업(프로젝트) 페이지에는 상세 내용을 입력하는 기능이 있습니다.


기본 설정으로는 Plain text만 입력이 가능한데요. 링크 등을 제공하기 위해서 HTML을 사용하고 싶을 때가 있습니다.
이런 경우 설정 변경을 통해 HTML 입력이 가능합니다.


설정은 간단합니다. 의외의 장소에 있어서 찾기가 어렵긴 하지만요.
Jenkins 관리 → Configure Global Security 메뉴로 이동한 후 Markup Formatter 항목의 값을 Raw HTML로 변경하면 됩니다.




EOF

댓글()

젠키스(Jenkins)에 노드(node) 추가하기

DevOps|2017. 5. 16. 19:00

젠키스(Jenkins)에 노드(node) 추가하기

CI 서버(Jenkins)는 EC2 등의 퍼블릭 IP로 접근 가능한 외부에 있고 특정 작업(job)을 사내에서 수행하는 경우 보안 문제 때문에 사내망을 CI에서 접근하도록 허용하는 건 어렵습니다. 이런 경우에 대한 해결책으로 자바 웹스타트를 통해 사내에 젠킨스 노드를 추가 할 수 있습니다. 제 경우는 사내의 Windows 랩탑에서 GUITAR 테스트를 수행하기 위해서 이 방법을 택했습니다.

Jenkins 관리 → 노드 관리 → 신규 노드 메뉴를 이용해서 노드를 추가합니다.

노드명을 입력하고 Permanent Agent를 선택한 후 OK 버튼을 클릭합니다.

이어지는 화면에서 Remote root directory에는 c:\jenkins를 입력하고 Launch method는 Launch agent via Java Web Start를 선택합니다. 나머지 설정은 기본 값을 유지하고 저장합니다.

아직 새 노드와 연결이 안됐기 때문에 노드 목록에는 오프라인으로 나옵니다. 이제 연결을 해야 합니다.

사내망 안의 Windows 랩탑에서 위에서 생성한 노드 화면에 접속합니다. Launch 버튼을 클릭하면 jnlp 파일(slave-agent.jnlp)을 다운로드 혹은 바로 실행할 수 있습니다. 혹 보안 경고가 뜨더라도 무시하고 jnlp 파일을 실행하세요. Jenkins slave agent가 실행되고 젠킨스 서버에 접속 중이라는 내용이 나오다가 곧 Connected로 내용이 변경됩니다. 만약 접속이 안되면 접속 중인 젠킨스 서버의 포트를 확인하세요. 접속 중 화면에 나온 포트(42031)가 접속 가능한지 확인하면 됩니다.

JNLP 에이전트의 포트는 무작위로 할당됩니다. 포트 고정이 필요하면 Jenkins 관리 → Configure Global Security 메뉴에서 TCP port for JNLP agents를 Fixed로 변경하고 원하는 포트 번호를 넣으면 됩니다.

이제 노드 화면을 새로고침하면 JNLP로 연결된 것으로 내용이 변경된 것을 확인할 수 있습니다.

노드 관리 화면의 목록에도 새 노드의 정보가 나옵니다.

랩탑을 재부팅 했을 때에도 연결을 유지하려면 Jenkins slave agent의 File → Install as a service 메뉴를 이용해서 윈도 서비스로 등록하면 됩니다.


EOF

댓글()

Chrome DevTools - 네트워크 정보를 저장하고 나중에 보기

Developer Tools|2017. 5. 11. 22:52

웹 개발을 하다 보면 서버와의 통신을 기록하고 이를 나중에 참고해야 할 때가 있는데요. 이럴 때 유용한 기능이 Chrome DevTools에 있습니다.

Network 패널을 열고 통신을 기록한 행을 우클릭하면 "Save as HAR with content" 메뉴가 있습니다. 이를 클릭하면 HAR(HTTP Archive) 형식으로 패널 안의 전체 통신 내역을 저장할 수가 있습니다.


이렇게 저장한 HAR 파일은 크롬 확장인 HTTP Archive Viewer를 이용해서 나중에 다시 볼 수 있습니다. HTTP Acrhive Viewer의 Load 탭에서 HAR 파일을 열면 됩니다.

네트워크 패널의 활용법은 아래 링크를 참고하세요.

리소스 로드 시간 측정


EOF

댓글()

IntelliJ IDEA에서 Gradle 변경 반영하기

Developer Tools|2015. 5. 13. 19:56

IntelliJ IDEA에서 Gradle 변경 반영하기

IDEA에서 Gradle 프로젝트로 작업하다보면 dependencies 변경 같은 것이 반영이 안될 때가 있습니다.

라이브러리 버전을 바꾸던가 외부에서 git branch를 변경했다던가 등등의 이유인데요.

이럴 때는 Gradle tool window에 있는 새로고침 버튼을 클릭하면 됩니다.


참고 - Synchronizing Changes in Gradle Project and IntelliJ IDEA Project


EOF


댓글()

Spring Boot : auto-configuration 그리고 debug

Java|2015. 4. 17. 13:39

Spring Boot 애플리케이션의 auto-configuration 정보를 확인하거나 DEBUG 레벨의 로그를 확인하려면 아래와 같이 --debug-Ddebug 옵션을 주면 됩니다.

$ java -jar myapp.jar --debug

그리고 문서에서는 확인이 안되지만 applicaton.properties 파일에, 값 없이 debug 키를 선언해도 됩니다(debug: 혹은 debug=).

debug:
spring.datasource.url: jdbc:hsqldb:file:D:/tmp/hsqldb/scratchdb
spring.jpa.show-sql: true
spring.jpa.generate-ddl: true
spring.jpa.hibernate.ddl-auto: create

이렇게 debug 옵션을 주면 auto-configuration 정보와 사용 중인 framework, library 등의 DEBUG 레벨 로그를 확인할 수 있습니다.

아래는 --debug 옵션과 함께 Spring Data JPA 앱의 테스트케이스를 실행했을 때의 콘솔 로그입니다.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v1.3.0.BUILD-SNAPSHOT)

2015-04-17 13:17:28.927  INFO 5124 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Starting JUnitStarter on envy-i7 with PID 5124 (started by kyutae.park in D:\dev\repos\spring-boot-data-jpa-javaworld)
2015-04-17 13:17:28.928 DEBUG 5124 --- [           main] o.s.boot.SpringApplication               : Loading source class sample.data.jpa.SampleDataJpaApplication
2015-04-17 13:17:29.243 DEBUG 5124 --- [           main] o.s.b.c.c.ConfigFileApplicationListener  : Skipped config file 'file:./config/application.yaml' resource not found

    ..............
    .... 중략 ....
    ..............

Hibernate: alter table tb_person_02837_cars add constraint FK_enugsq5f3484moat7h2ggrf1a foreign key (tb_person_02837_id) references tb_person_02837
2015-04-17 13:17:43.191  INFO 5124 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2015-04-17 13:17:45.352 DEBUG 5124 --- [           main] utoConfigurationReportLoggingInitializer : 


=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:
-----------------

   AopAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.context.annotation.EnableAspectJAutoProxy,org.aspectj.lang.annotation.Aspect,org.aspectj.lang.reflect.Advice (OnClassCondition)
      - matched (OnPropertyCondition)

   AopAutoConfiguration.JdkDynamicAutoProxyConfiguration
      - matched (OnPropertyCondition)

   DataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)

   DataSourceAutoConfiguration.DataSourceInitializerConfiguration
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration
      - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration#jdbcTemplate
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.JdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.JdbcTemplateConfiguration#namedParameterJdbcTemplate
      - @ConditionalOnMissingBean (types: org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourceAutoConfiguration.NonEmbeddedConfiguration
      - supported DataSource class found (DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition)
      - @ConditionalOnMissingBean (types: javax.sql.DataSource,javax.sql.XADataSource; SearchStrategy: all) found no beans (OnBeanCondition)

   DataSourcePoolMetadataProvidersConfiguration.TomcatDataSourcePoolMetadataProviderConfiguration
      - @ConditionalOnClass classes found: org.apache.tomcat.jdbc.pool.DataSource (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration
      - @ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) found no beans (OnBeanCondition)

   GenericCacheConfiguration
      - Automatic cache type (CacheCondition)

   HibernateJpaAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager (OnClassCondition)
      - found HibernateEntityManager class (HibernateJpaAutoConfiguration.HibernateEntityManagerCondition)

   HttpEncodingAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.filter.CharacterEncodingFilter (OnClassCondition)
      - matched (OnPropertyCondition)

   HttpEncodingAutoConfiguration#characterEncodingFilter
      - @ConditionalOnMissingBean (types: org.springframework.web.filter.CharacterEncodingFilter; SearchStrategy: all) found no beans (OnBeanCondition)

   HttpMessageConvertersAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.http.converter.HttpMessageConverter (OnClassCondition)

   HttpMessageConvertersAutoConfiguration#messageConverters
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.HttpMessageConverters; SearchStrategy: all) found no beans (OnBeanCondition)

   HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration
      - @ConditionalOnClass classes found: org.springframework.http.converter.StringHttpMessageConverter (OnClassCondition)

   HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration#stringHttpMessageConverter
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.StringHttpMessageConverter; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonAutoConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper,org.springframework.http.converter.json.Jackson2ObjectMapperBuilder (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration#jacksonObjectMapperBuilder
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonAutoConfiguration.JacksonObjectMapperConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper,org.springframework.http.converter.json.Jackson2ObjectMapperBuilder (OnClassCondition)

   JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper
      - @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found no beans (OnBeanCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration
      - @ConditionalOnClass classes found: com.fasterxml.jackson.databind.ObjectMapper (OnClassCondition)
      - matched (OnPropertyCondition)
      - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found the following [jacksonObjectMapper] (OnBeanCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration#mappingJackson2HttpMessageConverter
      - @ConditionalOnMissingBean (types: org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#entityManagerFactory
      - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#entityManagerFactoryBuilder
      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilder; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#jpaVendorAdapter
      - @ConditionalOnMissingBean (types: org.springframework.orm.jpa.JpaVendorAdapter; SearchStrategy: all) found no beans (OnBeanCondition)

   JpaBaseConfiguration#transactionManager
      - @ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found no beans (OnBeanCondition)

   JtaAutoConfiguration
      - @ConditionalOnClass classes found: javax.transaction.Transaction (OnClassCondition)
      - matched (OnPropertyCondition)

   MultipartAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.multipart.support.StandardServletMultipartResolver,javax.servlet.MultipartConfigElement (OnClassCondition)
      - matched (OnPropertyCondition)

   MultipartAutoConfiguration#multipartConfigElement
      - @ConditionalOnMissingBean (types: javax.servlet.MultipartConfigElement; SearchStrategy: all) found no beans (OnBeanCondition)

   MultipartAutoConfiguration#multipartResolver
      - @ConditionalOnMissingBean (types: org.springframework.web.multipart.MultipartResolver; SearchStrategy: all) found no beans (OnBeanCondition)

   NoOpCacheConfiguration
      - Automatic cache type (CacheCondition)

   PersistenceExceptionTranslationAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor (OnClassCondition)

   PersistenceExceptionTranslationAutoConfiguration#persistenceExceptionTranslationPostProcessor
      - @ConditionalOnMissingBean (types: org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; SearchStrategy: all) found no beans (OnBeanCondition)
      - matched (OnPropertyCondition)

   PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer
      - @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) found no beans (OnBeanCondition)

   RedisCacheConfiguration
      - Automatic cache type (CacheCondition)

   SimpleCacheConfiguration
      - Automatic cache type (CacheCondition)

   TransactionAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.transaction.support.TransactionTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)
      - @ConditionalOnSingleCandidate (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) found a primary candidate amongst the following [transactionManager] (OnBeanCondition)

   TransactionAutoConfiguration#transactionTemplate
      - @ConditionalOnMissingBean (types: org.springframework.transaction.support.TransactionTemplate; SearchStrategy: all) found no beans (OnBeanCondition)

   WebSocketAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,javax.websocket.server.ServerContainer (OnClassCondition)

   WebSocketAutoConfiguration.TomcatWebSocketConfiguration
      - @ConditionalOnClass classes found: org.apache.catalina.startup.Tomcat,org.apache.tomcat.websocket.server.WsSci (OnClassCondition)

   WebSocketAutoConfiguration.TomcatWebSocketConfiguration#websocketContainerCustomizer
      - @ConditionalOnMissingBean (names: websocketContainerCustomizer; SearchStrategy: all) found no beans (OnBeanCondition)


Negative matches:
-----------------

   ActiveMQAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.jms.ConnectionFactory,org.apache.activemq.ActiveMQConnectionFactory (OnClassCondition)

   AopAutoConfiguration.CglibAutoProxyConfiguration
      - @ConditionalOnProperty missing required properties spring.aop.proxy-target-class  (OnPropertyCondition)

   AtomikosJtaConfiguration
      - required @ConditionalOnClass classes not found: com.atomikos.icatch.jta.UserTransactionManager (OnClassCondition)

   BatchAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.batch.core.launch.JobLauncher (OnClassCondition)

   BitronixJtaConfiguration
      - required @ConditionalOnClass classes not found: bitronix.tm.jndi.BitronixContext (OnClassCondition)

   CacheAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.cache.CacheManager (OnClassCondition)
      - @ConditionalOnBean (types: org.springframework.cache.interceptor.CacheAspectSupport; SearchStrategy: all) found no beans (OnBeanCondition)

   CloudAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.cloud.config.java.CloudScanConfiguration (OnClassCondition)

   DataSourceAutoConfiguration.EmbeddedConfiguration
      - existing non-embedded database detected (DataSourceAutoConfiguration.EmbeddedDataSourceCondition)

   DataSourceAutoConfiguration.TomcatDataSourceJmxConfiguration
      - @ConditionalOnClass classes found: org.apache.tomcat.jdbc.pool.DataSourceProxy (OnClassCondition)
      - existing auto database detected (DataSourceAutoConfiguration.DataSourceAvailableCondition)
      - @ConditionalOnProperty missing required properties spring.datasource.jmx-enabled  (OnPropertyCondition)

   DataSourcePoolMetadataProvidersConfiguration.CommonsDbcpPoolDataSourceMetadataProviderConfiguration
      - required @ConditionalOnClass classes not found: org.apache.commons.dbcp.BasicDataSource (OnClassCondition)

   DataSourcePoolMetadataProvidersConfiguration.HikariPoolDataSourceMetadataProviderConfiguration
      - required @ConditionalOnClass classes not found: com.zaxxer.hikari.HikariDataSource (OnClassCondition)

   DataSourceTransactionManagerAutoConfiguration#transactionManager
      - @ConditionalOnMissingBean (names: transactionManager; SearchStrategy: all) found the following [transactionManager] (OnBeanCondition)

   DeviceDelegatingViewResolverAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver (OnClassCondition)

   DeviceResolverAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.DeviceResolverHandlerInterceptor,org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver (OnClassCondition)

   DispatcherServletAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   EhCacheCacheConfiguration
      - required @ConditionalOnClass classes not found: net.sf.ehcache.Cache,org.springframework.cache.ehcache.EhCacheCacheManager (OnClassCondition)

   ElasticsearchAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.client.TransportClientFactoryBean,org.springframework.data.elasticsearch.client.NodeClientFactoryBean (OnClassCondition)

   ElasticsearchDataAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.core.ElasticsearchTemplate (OnClassCondition)

   ElasticsearchRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: org.elasticsearch.client.Client,org.springframework.data.elasticsearch.repository.ElasticsearchRepository (OnClassCondition)

   EmbeddedServletContainerAutoConfiguration
      - not a web application (OnWebApplicationCondition)

   ErrorMvcAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   FacebookAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.facebook.connect.FacebookConnectionFactory (OnClassCondition)

   FallbackWebSecurityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.security.config.annotation.web.configuration.EnableWebSecurity (OnClassCondition)

   FlywayAutoConfiguration
      - required @ConditionalOnClass classes not found: org.flywaydb.core.Flyway (OnClassCondition)

   FreeMarkerAutoConfiguration
      - required @ConditionalOnClass classes not found: freemarker.template.Configuration,org.springframework.ui.freemarker.FreeMarkerConfigurationFactory (OnClassCondition)

   GroovyTemplateAutoConfiguration
      - required @ConditionalOnClass classes not found: groovy.text.markup.MarkupTemplateEngine (OnClassCondition)

   GsonAutoConfiguration
      - required @ConditionalOnClass classes not found: com.google.gson.Gson (OnClassCondition)

   GsonHttpMessageConvertersConfiguration
      - required @ConditionalOnClass classes not found: com.google.gson.Gson (OnClassCondition)

   GuavaCacheConfiguration
      - required @ConditionalOnClass classes not found: com.google.common.cache.CacheBuilder,org.springframework.cache.guava.GuavaCacheManager (OnClassCondition)

   GzipFilterAutoConfiguration
      - required @ConditionalOnClass classes not found: org.eclipse.jetty.servlets.GzipFilter (OnClassCondition)

   HazelcastCacheConfiguration
      - required @ConditionalOnClass classes not found: com.hazelcast.core.HazelcastInstance,com.hazelcast.spring.cache.HazelcastCacheManager (OnClassCondition)

   HornetQAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.jms.ConnectionFactory,org.hornetq.api.jms.HornetQJMSClient (OnClassCondition)

   HypermediaAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.hateoas.Resource,org.springframework.plugin.core.Plugin (OnClassCondition)

   IntegrationAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.integration.config.EnableIntegration (OnClassCondition)

   JCacheCacheConfiguration
      - required @ConditionalOnClass classes not found: javax.cache.Caching,org.springframework.cache.jcache.JCacheCacheManager (OnClassCondition)

   JacksonAutoConfiguration.JodaDateTimeJacksonConfiguration
      - required @ConditionalOnClass classes not found: org.joda.time.DateTime,com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer,com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat (OnClassCondition)

   JacksonHttpMessageConvertersConfiguration.MappingJackson2XmlHttpMessageConverterConfiguration
      - required @ConditionalOnClass classes not found: com.fasterxml.jackson.dataformat.xml.XmlMapper (OnClassCondition)

   JerseyAutoConfiguration
      - required @ConditionalOnClass classes not found: org.glassfish.jersey.server.spring.SpringComponentProvider (OnClassCondition)

   JmsAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.jms.core.JmsTemplate (OnClassCondition)

   JmxAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.jmx.export.MBeanExporter (OnClassCondition)
      - @ConditionalOnProperty expected 'true' for properties spring.jmx.enabled (OnPropertyCondition)

   JndiConnectionFactoryAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.jms.core.JmsTemplate (OnClassCondition)

   JndiDataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
      - @ConditionalOnProperty missing required properties spring.datasource.jndi-name  (OnPropertyCondition)

   JndiJtaConfiguration
      - @ConditionalOnClass classes found: org.springframework.transaction.jta.JtaTransactionManager (OnClassCondition)
      - JNDI environment is not available (OnJndiCondition)

   JpaBaseConfiguration.JpaWebConfiguration
      - @ConditionalOnClass classes found: org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   JpaRepositoriesAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.data.jpa.repository.JpaRepository (OnClassCondition)
      - matched (OnPropertyCondition)
      - @ConditionalOnMissingBean (types: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean,org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension; SearchStrategy: all) found the following [&personRepository, &reviewRepository, &cityRepository, &hotelRepository, &carRepository, org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension#0] (OnBeanCondition)

   LinkedInAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.linkedin.connect.LinkedInConnectionFactory (OnClassCondition)

   LiquibaseAutoConfiguration
      - required @ConditionalOnClass classes not found: liquibase.integration.spring.SpringLiquibase (OnClassCondition)

   MailSenderAutoConfiguration
      - required @ConditionalOnClass classes not found: javax.mail.internet.MimeMessage (OnClassCondition)

   MessageSourceAutoConfiguration
      - No bundle found for spring.messages.basename: messages (MessageSourceAutoConfiguration.ResourceBundleCondition)

   MongoAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo (OnClassCondition)

   MongoDataAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo,org.springframework.data.mongodb.core.MongoTemplate (OnClassCondition)

   MongoRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: com.mongodb.Mongo,org.springframework.data.mongodb.repository.MongoRepository (OnClassCondition)

   MustacheAutoConfiguration
      - required @ConditionalOnClass classes not found: com.samskivert.mustache.Mustache (OnClassCondition)

   RabbitAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.amqp.rabbit.core.RabbitTemplate,com.rabbitmq.client.Channel (OnClassCondition)

   ReactorAutoConfiguration
      - required @ConditionalOnClass classes not found: reactor.spring.context.config.EnableReactor,reactor.core.Environment (OnClassCondition)

   RedisAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.data.redis.connection.jedis.JedisConnection,org.springframework.data.redis.core.RedisOperations,redis.clients.jedis.Jedis (OnClassCondition)

   RepositoryRestMvcAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration (OnClassCondition)

   SecurityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.security.authentication.AuthenticationManager,org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter (OnClassCondition)

   SendGridAutoConfiguration
      - required @ConditionalOnClass classes not found: com.sendgrid.SendGrid (OnClassCondition)

   ServerPropertiesAutoConfiguration
      - not a web application (OnWebApplicationCondition)

   SitePreferenceAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor,org.springframework.mobile.device.site.SitePreferenceHandlerMethodArgumentResolver (OnClassCondition)

   SocialWebAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.connect.web.ConnectController,org.springframework.social.config.annotation.SocialConfigurerAdapter (OnClassCondition)

   SolrAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.solr.client.solrj.impl.HttpSolrServer,org.apache.solr.client.solrj.impl.CloudSolrServer (OnClassCondition)

   SolrRepositoriesAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.solr.client.solrj.SolrServer,org.springframework.data.solr.repository.SolrRepository (OnClassCondition)

   SpringDataWebAutoConfiguration
      - @ConditionalOnClass classes found: org.springframework.data.web.PageableHandlerMethodArgumentResolver,org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   ThymeleafAutoConfiguration
      - required @ConditionalOnClass classes not found: org.thymeleaf.spring4.SpringTemplateEngine (OnClassCondition)

   TwitterAutoConfiguration
      - required @ConditionalOnClass classes not found: org.springframework.social.config.annotation.SocialConfigurerAdapter,org.springframework.social.twitter.connect.TwitterConnectionFactory (OnClassCondition)

   VelocityAutoConfiguration
      - required @ConditionalOnClass classes not found: org.apache.velocity.app.VelocityEngine,org.springframework.ui.velocity.VelocityEngineFactory (OnClassCondition)

   WebMvcAutoConfiguration
      - @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet,org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter (OnClassCondition)
      - not a web application (OnWebApplicationCondition)

   WebSocketAutoConfiguration.JettyWebSocketConfiguration
      - required @ConditionalOnClass classes not found: org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer (OnClassCondition)

   WebSocketAutoConfiguration.UndertowWebSocketConfiguration
      - required @ConditionalOnClass classes not found: io.undertow.websockets.jsr.Bootstrap (OnClassCondition)

   XADataSourceAutoConfiguration
      - @ConditionalOnClass classes found: javax.sql.DataSource,javax.transaction.TransactionManager,org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
      - @ConditionalOnBean (types: org.springframework.boot.jta.XADataSourceWrapper; SearchStrategy: all) found no beans (OnBeanCondition)


Exclusions:
-----------

    None



2015-04-17 13:17:45.388  INFO 5124 --- [           main] c.i.rt.execution.junit.JUnitStarter      : Started JUnitStarter in 23.914 seconds (JVM running for 45.382)
2015-04-17 13:17:45.461 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select count(city0_.id) as col_0_0_ from city city0_
Hibernate: select count(city0_.id) as col_0_0_ from city city0_
2015-04-17 13:17:45.468 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_, city0_.country as country2_0_, city0_.map as map3_0_, city0_.name as name4_0_, city0_.state as state5_0_ from city city0_ order by city0_.name asc limit ?
Hibernate: select city0_.id as id1_0_, city0_.country as country2_0_, city0_.map as map3_0_, city0_.name as name4_0_, city0_.state as state5_0_ from city city0_ order by city0_.name asc limit ?
2015-04-17 13:17:45.490 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select count(hotel0_.id) as col_0_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id where hotel0_.city_id=? group by hotel0_.id
Hibernate: select count(hotel0_.id) as col_0_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id where hotel0_.city_id=? group by hotel0_.id
2015-04-17 13:17:45.502 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select hotel0_.city_id as col_0_0_, hotel0_.name as col_1_0_, avg(cast(reviews1_.rating as double)) as col_2_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id inner join city city2_ on hotel0_.city_id=city2_.id where hotel0_.city_id=? group by hotel0_.id order by hotel0_.name asc limit ?
Hibernate: select hotel0_.city_id as col_0_0_, hotel0_.name as col_1_0_, avg(cast(reviews1_.rating as double)) as col_2_0_ from hotel hotel0_ left outer join review reviews1_ on hotel0_.id=reviews1_.hotel_id inner join city city2_ on hotel0_.city_id=city2_.id where hotel0_.city_id=? group by hotel0_.id order by hotel0_.name asc limit ?
2015-04-17 13:17:45.515 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
Hibernate: select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
2015-04-17 13:17:45.520  WARN 5124 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: -1003, SQLState: 01003
2015-04-17 13:17:45.520  WARN 5124 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : warning: null value eliminated in set function
2015-04-17 13:17:45.528 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select hotel0_.id as id1_1_, hotel0_.address as address2_1_, hotel0_.city_id as city_id5_1_, hotel0_.name as name3_1_, hotel0_.zip as zip4_1_ from hotel hotel0_ where hotel0_.city_id=? and hotel0_.name=?
Hibernate: select hotel0_.id as id1_1_, hotel0_.address as address2_1_, hotel0_.city_id as city_id5_1_, hotel0_.name as name3_1_, hotel0_.zip as zip4_1_ from hotel hotel0_ where hotel0_.city_id=? and hotel0_.name=?
2015-04-17 13:17:45.530 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
Hibernate: select city0_.id as id1_0_0_, city0_.country as country2_0_0_, city0_.map as map3_0_0_, city0_.name as name4_0_0_, city0_.state as state5_0_0_ from city city0_ where city0_.id=?
2015-04-17 13:17:45.537 DEBUG 5124 --- [           main] org.hibernate.SQL                        : select review0_.rating as col_0_0_, count(review0_.id) as col_1_0_ from review review0_ where review0_.hotel_id=? group by review0_.rating order by review0_.rating DESC
Hibernate: select review0_.rating as col_0_0_, count(review0_.id) as col_1_0_ from review review0_ where review0_.hotel_id=? group by review0_.rating order by review0_.rating DESC
2015-04-17 13:17:45.543  INFO 5124 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7050ad86: startup date [Fri Apr 17 13:17:29 GMT+09:00 2015]; root of context hierarchy
2015-04-17 13:17:45.548  INFO 5124 --- [       Thread-1] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'

Process finished with exit code 0

조금 길지만 auto-configuration에 관한 내용을 찬찬히 읽어 보면 어떻게 앱이 자동 설정되었는지 확인할 수 있습니다.

EOF

댓글()

Spring Data JPA - LazyInitializationException

Java|2015. 4. 14. 10:00

개요

요즘 Spring Boot 저장소에 있는 Spring Data JPA 샘플 프로젝트를 살펴 보고 있습니다.

테스트 코드를 작성하면서 하나하나 파악하고 있는데, OneToMany로 엮인 다른 엔티티의 목록을 가져오려고 하면 아래와 같은 오류가 발생합니다.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: kr.co.javaworld.jpa.domain.Person.cars, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
    at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:278)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:21)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:14)
    at org.hamcrest.FeatureMatcher.matchesSafely(FeatureMatcher.java:40)
    at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:12)
    at org.junit.Assert.assertThat(Assert.java:956)
    at org.junit.Assert.assertThat(Assert.java:923)
    at kr.co.javaworld.jpa.service.PersonRepositoryIntegrationTests.testFindCars(PersonRepositoryIntegrationTests.java:46)
    ..............
    .... 중략 ....
    ..............
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

늦은 초기화(Lazy initialization)에 관련된 예외 상황인데, 이에 대한 해결 방법을 정리해 봅니다.

예외가 발생하는 코드

아래의 테스트 코드를 실행하던 중 예외가 발생했습니다. testFindCars 메소드는 Person 객체를 하나 찾은 후, 다시 그 Person이 가진 Car 목록을 조회하는 테스트 코드입니다.

Person.getCars() 호출 후 목록(cars)의 크기를 얻으려고 하니까(assertThat(cars, hasSize(4))) 오류가 발생했습니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

Person 엔티티의 코드입니다.
cars@OneToMany annotation이 붙어있을 뿐 특별한 점은 없습니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

해결 방법

@OneToMany로 엮을 경우 JPA는 늦은 초기화를 통해 Personcars 목록을 가져오는게 기본 설정입니다. 즉, 위 코드의 @OneToMany annotation 선언은 @OneToMany(fetch = FetchType.LAZY)로 대체해도 동일합니다.

따라서 해결 방법은 간단합니다. 패치 타입을 FetchType.EAGER로 변경하여 늦은 초기화 대신 이른 초기화(Eager initialization)를 사용하면 됩니다.

아래 코드와 같이 @OneToMany(fetch = FetchType.EAGER)로 annotation 선언을 변경해 주면 오류가 사라집니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany(fetch = FetchType.EAGER)
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

다른 해결 방법

앞서의 해결 방법은 People 엔티티를 얻어 올 때는 언제나 Car 목록도 함께 가져오도록 강제합니다. 따라서 가끔씩만 Car 목록이 필요하다면 불필요한 메모리 낭비나 서버 성능 저하 등의 문제가 발생할 수 있습니다.

늦은 초기화를 사용하면서도 문제를 해결하려면 아래와 같이 트랜잭션을 Person.getCar() 호출 후 관련 동작을 완료할 때까지 유지하면 됩니다.

아래에서는 testFindCars 메소드에 @Transactional annotation을 붙여서 메소드 전체를 하나의 트랜잭션으로 감쌌습니다.

실무에서는 서비스 클래스의 메소드 단위로 트랜잭션을 잡아 주거나, 뷰 단의 서블릿 필터에서 UserTransaction을 이용하여 요청 단위로 트랜잭션을 처리하는 방법을 사용하면 됩니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    @Transactional
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

EOF

댓글()

PuTTY로 Amazon EC2 인스턴스 접속하기

Developer Tools|2015. 4. 2. 10:00

PuTTYgen 내려 받기

EC2 인스턴스에 PuTTY를 이용해 접속하려면, Key Pair 파일(.pem)을 .ppk 파일로 변환해야 합니다.

.ppk 파일은 PuTTYgen(PuTTY Key Generator)을 이용해서 생성 할 수 있습니다.
아래 링크에서 PuTTYgen을 내려받습니다.

PuTTY Download Page

바로 내려받기

설치 없이 바로 실행하여 사용할 수 있습니다.

Amazon Key Pair(.pem)를 PuTTY Private Key File(.ppk)로 변환

PuTTYgen을 실행한 후 상단 메뉴에서, Conversions > Import key를 클릭합니다.

Load private key 창이 열리면 .pem 파일을 찾아서 엽니다.


Key Pair에 대한 정보가 로딩되면 Save private key를 클릭합니다.


passphrase 없이 키를 저장할 것인지 물어봅니다. 예(Y)를 클릭하여 수락합니다.


Save private key as 창이 열리면, 원하는 경로와 이름을 지정한 후 ppk 파일을 저장합니다.
여기에서는 바탕화면에 aws_hbase.ppk로 저장했습니다.


PuTTY에서 ppk 파일 사용하기

PuTTY 설정창(PuTTY Configuration)의 Category에서 Connection > SSH > Auth로 이동한 후, Browse를 클릭합니다.


위에서 저장한 ppk 파일을 선택합니다.


ppk 파일 선택이 완료됐습니다.


이제 Session Category로 이동한 후 Host Name에 EC2 인스턴스의 주소를 입력한 후 Open을 클릭하여 접속하면 됩니다.


댓글()

Pinpoint 빨리 설치하기(QuickStart)

설치&설정|2015. 3. 30. 15:57

Pinpoint QuickStart

얼마 전에 Hadoop, Hbase 최근 버전을 설치한 후, 네이버 Pinpint 설치를 시도해 봤습니다. 하지만 Pinpoint가 Hadoop 최신 버전을 공식 지원하지 않아서인지 실패했습니다.

어쨌든 빨리 사용해 보고 싶어서 QuickStart 가이드를 따라서 설치해 봅니다.

Linux 환경에서 QuickStart 실행하기

Pinpoint QuickStart 가이드 문서는 아래 주소에서 볼 수 있습니다(영문).

https://github.com/naver/pinpoint/tree/master/quickstart

리눅스 환경에서의 설치를 가이드하고 있어서 저는 AWS에 설치한 CentOS 7에 설치했습니다.

아래 주소에 가면 윈도 환경에서 실행하는 방법을 볼 수 있습니다.
Windows 환경에서 QuickStart 실행하기

Install JDK 6

Pinpoint 실행을 위해서는 JDK 6JDK 7+, Maven 3.2x+ 버전을 먼저 설치해야 합니다.

우선 JDK 설치를 위해서 wget 부터 설치합니다.

[centos@ip-172-31-7-87 ~]$ sudo -i
[root@ip-172-31-7-87 ~]# yum install -y wget

wget으로 JDK 6 바이너리(jdk-6u45-linux-x64.bin)를 다운로드 받은 후, chmod 명령으로 실행권한을 부여한 후 설치합니다.

[root@ip-172-31-7-87 ~]# wget http://ghaffarian.net/downloads/Java/JDK/jdk-6u45-linux-x64.bin
--2015-03-25 11:03:07--  http://ghaffarian.net/downloads/Java/JDK/jdk-6u45-linux-x64.bin
Resolving ghaffarian.net (ghaffarian.net)... 178.32.91.18
Connecting to ghaffarian.net (ghaffarian.net)|178.32.91.18|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 72087592 (69M) [application/octet-stream]
Saving to: ‘jdk-6u45-linux-x64.bin’

100%[=================================================>] 72,087,592  5.52MB/s   in 25s

2015-03-25 11:03:33 (2.78 MB/s) - ‘jdk-6u45-linux-x64.bin’ saved [72087592/72087592]

[root@ip-172-31-7-87 ~]# 
[root@ip-172-31-7-87 ~]# chmod u+x jdk-6u45-linux-x64.bin
[root@ip-172-31-7-87 ~]# ./jdk-6u45-linux-x64.bin
Unpacking...
Checksumming...
Extracting...
UnZipSFX 5.50 of 17 February 2002, by Info-ZIP (Zip-Bugs@lists.wku.edu).
   creating: jdk1.6.0_45/
   creating: jdk1.6.0_45/db/
   creating: jdk1.6.0_45/db/bin/
  inflating: jdk1.6.0_45/db/bin/ij
  inflating: jdk1.6.0_45/db/bin/NetworkServerControl
  inflating: jdk1.6.0_45/db/bin/setNetworkClientCP.bat
  inflating: jdk1.6.0_45/db/bin/setEmbeddedCP.bat
....
....
....
  inflating: jdk1.6.0_45/include/classfile_constants.h
  inflating: jdk1.6.0_45/COPYRIGHT
Creating jdk1.6.0_45/jre/lib/rt.jar
Creating jdk1.6.0_45/jre/lib/jsse.jar
Creating jdk1.6.0_45/jre/lib/charsets.jar
Creating jdk1.6.0_45/lib/tools.jar
Creating jdk1.6.0_45/jre/lib/ext/localedata.jar
Creating jdk1.6.0_45/jre/lib/plugin.jar
Creating jdk1.6.0_45/jre/lib/javaws.jar
Creating jdk1.6.0_45/jre/lib/deploy.jar

Done.

설치 후 생성된 jdk1.6.0_45 디렉토리를 /opt 디렉토리로 이동합니다.

[root@ip-172-31-7-87 ~]# mv jdk1.6.0_45 /opt

Install JDK 8

wget으로 JDK 8 압축 파일(jdk-8u25-linux-x64.tar.gz)을 다운로드 받은 후, /opt에 압축을 해제합니다.

압축 해제가 완료되면 /opt/jdk1.8.0_25 디렉토리가 생성됩니다.

[root@ip-172-31-7-87 ~]# wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u25-b17/jdk-8u25-linux-x64.tar.gz"

[root@ip-172-31-7-87 ~]# tar -zxvf jdk-8u25-linux-x64.tar.gz -C /opt

alternatives 명령을 사용하여 어디에서나 java 명령을 사용할 수 있도록 설정합니다.

[root@ip-172-31-7-87 ~]#  /usr/sbin/alternatives --install /usr/bin/java java /opt/jdk1.8.0_25/bin/java 100

[root@ip-172-31-7-87 ~]# java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

/etc/profile 파일을 편집하여 JAVA_HOME, JAVA_7_HOME, JAVA_6_HOME 환경변수를 설정합니다.

JAVA_HOME, JAVA_7_HOME은 앞에서 설치한 JDK 8을 가리키도록 설정했습니다.

[root@ip-172-31-7-87 ~]# vi /etc/profile
export JAVA_HOME=/opt/jdk1.8.0_25
export JAVA_7_HOME=/opt/jdk1.8.0_25
export JAVA_6_HOME=/opt/jdk1.6.0_45

source 명령으로 방금 편집한 /etc/profile을 새로 읽어 들인 후, 환경변수 설정이 잘 됐는지 확인합니다.

[root@ip-172-31-7-87 ~]# source /etc/profile

[root@ip-172-31-7-87 ~]# echo $JAVA_7_HOME
/opt/jdk1.8.0_25

[root@ip-172-31-7-87 ~]# echo $JAVA_6_HOME
/opt/jdk1.6.0_45

Install Maven

지금까지는 JDK 설치를 위해서 root 계정을 사용했습니다만, Mavencentos 계정으로 설치합니다. Pinpoint 실행 또한 centos 계정을 사용합니다.

Maven 3.2.5 버전을 wget으로 다운로드 받은 후 압축을 해제합니다.

[root@ip-172-31-7-87 ~]# exit
[centos@ip-172-31-7-87 ~]# source /etc/profile
[centos@ip-172-31-7-87 ~]# wget http://apache.tt.co.kr/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz
--2015-03-25 11:16:07--  http://apache.tt.co.kr/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz
Resolving apache.tt.co.kr (apache.tt.co.kr)... 121.125.79.185
Connecting to apache.tt.co.kr (apache.tt.co.kr)|121.125.79.185|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7956528 (7.6M) [application/x-gzip]
Saving to: ‘apache-maven-3.2.5-bin.tar.gz’

100%[======================================>] 7,956,528    124KB/s   in 62s

2015-03-25 11:17:09 (125 KB/s) - ‘apache-maven-3.2.5-bin.tar.gz’ saved [7956528/7956528]

[centos@ip-172-31-7-87 ~]$ tar xfz apache-maven-3.2.5-bin.tar.gz

.bashrc 파일을 편집하여 MAVEN_HOME, PATH 환경변수를 추가합니다.

[centos@ip-172-31-7-87 ~]$ vi ~/.bashrc
export MAVEN_HOME=/home/centos/apache-maven-3.2.5
export PATH=$PATH:$MAVEN_HOME/bin

mvn -version 명령을 실행하여 설치가 잘 됐는지 확인합니다. mvn은 Maven 실행파일입니다.

[centos@ip-172-31-7-87 ~]$ mvn -version
mvn -version
Apache Maven 3.2.5 (12a6b3acb947671f09b81f49094c53f426d8cea1; 2014-12-14T17:29:23+00:00)
Maven home: /home/centos/apache-maven-3.2.5
Java version: 1.8.0_25, vendor: Oracle Corporation
Java home: /opt/jdk1.8.0_25/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-123.8.1.el7.x86_64", arch: "amd64", family: "unix"

Pinpoint 저장소 복제

Pinpoint 저장소를 복제(clone)하기 위해서 root 계정으로 Git을 설치합니다.

[centos@ip-172-31-7-87 ~]$ sudo -i
[root@ip-172-31-7-87 ~]# yum install -y git
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
Resolving Dependencies
--> Running transaction check
---> Package git.x86_64 0:1.8.3.1-4.el7 will be installed
--> Processing Dependency: perl-Git = 1.8.3.1-4.el7 for package: git-1.8.3.1-4.el7.x86_64
--> Processing Dependency: perl >= 5.008 for package: git-1.8.3.1-4.el7.x86_64
....
....
....
  perl-Time-Local.noarch 0:1.2300-2.el7    perl-constant.noarch 0:1.27-2.el7
  perl-libs.x86_64 4:5.16.3-283.el7        perl-macros.x86_64 4:5.16.3-283.el7
  perl-parent.noarch 1:0.225-244.el7       perl-podlators.noarch 0:2.5.1-3.el7
  perl-threads.x86_64 0:1.87-4.el7         perl-threads-shared.x86_64 0:1.43-6.el7

Complete!

git clone 명령으로 Pinpoint 저장소를 복제합니다.

[root@ip-172-31-7-87 ~]# exit
logout

[centos@ip-172-31-7-87 ~]$ git clone https://github.com/naver/pinpoint.git
Cloning into 'pinpoint'...
remote: Counting objects: 93939, done.
remote: Compressing objects: 100% (218/218), done.
remote: Total 93939 (delta 111), reused 0 (delta 0), pack-reused 93579
Receiving objects: 100% (93939/93939), 151.77 MiB | 7.53 MiB/s, done.
Resolving deltas: 100% (48776/48776), done.

mvn install -Dmaven.test.skip=true 명령으로 Pinpoint를 설치합니다.

maven.test.skip=true은 단위테스트를 건너뛰기 위한 옵션입니다

[centos@ip-172-31-7-87 ~]$ cd pinpoint
[centos@ip-172-31-7-87 pinpoint]$ mvn install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] pinpoint
[INFO] pinpoint-thrift
[INFO] pinpoint-commons
[INFO] pinpoint-bootstrap-core
[INFO] pinpoint-bootstrap
[INFO] pinpoint-rpc
[INFO] pinpoint-profiler
[INFO] pinpoint-profiler-optional
[INFO] pinpoint-jdk-http-plugin
[INFO] pinpoint-test
[INFO] pinpoint-redis-plugin
[INFO] pinpoint-servlet-plugin
[INFO] pinpoint-tomcat-plugin
[INFO] pinpoint-plugins
[INFO] pinpoint-agent-distribution
[INFO] pinpoint-collector
[INFO] pinpoint-web
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building pinpoint 1.1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: http://repository.codehaus.org/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom
....
....
....
[INFO] Installing /home/centos/pinpoint/web/target/pinpoint-web-1.1.0-SNAPSHOT-classes.jar to /home/centos/.m2/repository/com/navercorp/pinpoint/pinpoint-web/1.1.0-SNAPSHOT/pinpoint-web-1.1.0-SNAPSHOT-classes.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] pinpoint ........................................... SUCCESS [ 23.635 s]
[INFO] pinpoint-thrift .................................... SUCCESS [01:51 min]
[INFO] pinpoint-commons ................................... SUCCESS [01:56 min]
[INFO] pinpoint-bootstrap-core ............................ SUCCESS [  1.393 s]
[INFO] pinpoint-bootstrap ................................. SUCCESS [ 21.062 s]
[INFO] pinpoint-rpc ....................................... SUCCESS [  5.175 s]
[INFO] pinpoint-profiler .................................. SUCCESS [ 48.396 s]
[INFO] pinpoint-profiler-optional ......................... SUCCESS [  0.910 s]
[INFO] pinpoint-jdk-http-plugin ........................... SUCCESS [  0.990 s]
[INFO] pinpoint-test ...................................... SUCCESS [ 34.903 s]
[INFO] pinpoint-redis-plugin .............................. SUCCESS [  1.074 s]
[INFO] pinpoint-servlet-plugin ............................ SUCCESS [  0.887 s]
[INFO] pinpoint-tomcat-plugin ............................. SUCCESS [  1.096 s]
[INFO] pinpoint-plugins ................................... SUCCESS [  0.007 s]
[INFO] pinpoint-agent-distribution ........................ SUCCESS [ 55.523 s]
[INFO] pinpoint-collector ................................. SUCCESS [ 50.376 s]
[INFO] pinpoint-web ....................................... SUCCESS [ 42.698 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 08:37 min
[INFO] Finished at: 2015-03-25T11:38:15+00:00
[INFO] Final Memory: 33M/139M
[INFO] ------------------------------------------------------------------------

HBase 설치, 시작, 초기화

~/pinpoint/quickstart/bin/start-hbase.sh 스크립트를 이용해서 hbase를 다운로드하고 시작합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-hbase.sh
Hbase not detected.
Downloading hbase...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 56.5M  100 56.5M    0     0  4030k      0  0:00:14  0:00:14 --:--:-- 5817k
starting master, logging to /home/centos/pinpoint/quickstart/hbase/hbase-0.94.25/bin/../logs/hbase-centos-master-ip-172-31-7-87.out

~/pinpoint/quickstart/bin/init-hbase.sh 스크립트를 이용해서 hbase 테이블을 초기화(initialize)합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/init-hbase.sh
0 row(s) in 1.7520 seconds

0 row(s) in 1.0980 seconds

0 row(s) in 1.0580 seconds

0 row(s) in 2.7240 seconds

0 row(s) in 1.0700 seconds

0 row(s) in 1.0770 seconds

0 row(s) in 2.2110 seconds

0 row(s) in 1.0990 seconds

0 row(s) in 1.0650 seconds

0 row(s) in 1.0530 seconds

0 row(s) in 1.0590 seconds

0 row(s) in 1.0660 seconds

0 row(s) in 1.0470 seconds

0 row(s) in 1.0570 seconds

TABLE
AgentInfo
AgentStat
ApiMetaData
ApplicationIndex
ApplicationMapStatisticsCallee
ApplicationMapStatisticsCaller
ApplicationMapStatisticsSelf
ApplicationStatistics
ApplicationTraceIndex
HostApplicationMap
HostApplicationMap_Ver2
SqlMetaData
StringMetaData
Traces
14 row(s) in 0.0340 seconds

Collector 시작

~/pinpoint/quickstart/bin/start-collector.sh 스크립트를 이용해서 Pinpoint collector를 시작합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-collector.sh
---check pinpoint-quickstart-collector process status.---
---initialize pinpoint-quickstart-collector logs.---
mkdir /home/centos/pinpoint/quickstart/logs
mkdir /home/centos/pinpoint/quickstart/logs/pid
---pinpoint-quickstart-collector initialization started. pid=10526.---
starting pinpoint-quickstart-collector. 0 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 5 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 10 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 15 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 20 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 25 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 30 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 35 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 40 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 45 /180 sec(close wait limit).
---pinpoint-quickstart-collector initialization completed. pid=10526.---
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :230) Pinpoint-UDP-Stat start.
03-25 11:41:54 [WARN ](c.n.p.c.r.u.BaseUDPReceiver        :211) DatagramSocket.setReceiveBu fferSize() error. 4194304!=212992
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :236) UDP Packet reader:2 started .
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Span-Io(11-0)
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Stat-Io(13-0)
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Span-Io(11-1)
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Stat-Io(13-1)
03-25 11:41:54 [INFO ](o.s.w.c.ContextLoader              :313) Root WebApplicationContext:  initialization completed in 2246 ms
Mar 25, 2015 11:41:54 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-28082"]

Web UI 시작

~/pinpoint/quickstart/bin/start-web.sh 스크립트를 이용해서 Pinpoint Web UI를 시작합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-web.sh
---check pinpoint-quickstart-web process status.---
---initialize pinpoint-quickstart-web logs.---
---pinpoint-quickstart-web initialization started. pid=13397.---
starting pinpoint-quickstart-web. 0 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 5 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 10 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 15 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 20 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 25 /180 sec(close wait limit).
---pinpoint-quickstart-web initialization completed. pid=13397.---
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionInfo/] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionList] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionList.*] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionList/] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/lastTransactionList] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/lastTransactionList.*] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/lastTransactionList/] onto handler 'businessTransactionController'
11:44:08 INFO (o.s.w.s.DispatcherServlet          :473) FrameworkServlet 'pinpoint-web': initialization completed in 1265 ms
Mar 25, 2015 11:44:08 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-28080"]

TestApp 시작

~/pinpoint/quickstart/bin/start-testapp.sh 스크립트를 이용해서 Pinpoint TestApp을 시작합니다.

[centos@ip-172-31-7-87 ~]$ quickstart/bin/start-testapp.sh
-bash: quickstart/bin/start-testapp.sh: No such file or directory
[centos@ip-172-31-7-87 ~]$ cd pin
-bash: cd: pin: No such file or directory
[centos@ip-172-31-7-87 ~]$ cd pinpoint/
[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-testapp.sh
---check pinpoint-quickstart-testapp process status.---
---initialize pinpoint-quickstart-testapp logs.---
---initialize pinpoint-quickstart-testapp agent.---
---pinpoint-quickstart-testapp initialization started. pid=4048.---
starting pinpoint-quickstart-testapp. 0 /180 sec(close wait limit).
starting pinpoint-quickstart-testapp. 5 /180 sec(close wait limit).
starting pinpoint-quickstart-testapp. 10 /180 sec(close wait limit).
starting pinpoint-quickstart-testapp. 15 /180 sec(close wait limit).
---pinpoint-quickstart-testapp initialization completed. pid=4048.---
2015-03-25 11:48:29 [DEBUG](c.n.p.p.i.b.AspectWeaverClass      :149) JointPoint method __getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; -> invokeOriginal:$_=__getHeaders_$$pinpoint($$);
....
....
....
2015-03-25 11:49:05 [WARN ](c.n.p.r.c.PinpointClientSocketHandshaker:260) Handshake already completed.

확인

설치 및 실행이 완료되면 아래 주소에서 Pinpoint Web UI와 TestApp의 동작을 확인할 수 있습니다.

Web UI - http://localhost:28080

TestApp - http://localhost:28081

TestApp에 있는 여러 링크를 눌러본 후, Pinpoint가 어떻게 동작하는지 확인합니다.

종료

각각 아래의 스크립트로 종료합니다.

HBase - ~/pinpoint/quickstart/bin/stop-hbase.sh

Collector ~/pinpoint/quickstart/bin/stop-collector.sh

Web UI - ~/pinpoint/quickstart/bin/stop-web.sh

TestApp - ~/pinpoint/quickstart/bin/stop-testapp.sh


댓글()

Trello - 리스트 최상단에 카드 추가하기

DevOps|2015. 3. 16. 20:14

Trello 보드에 카드를 추가하려면 보통 리스트 하단의 Add a card를 클릭한 다음 내용을 입력하고 엔터를 치거나 Add를 클릭합니다.

위의 방식으로 한동안 잘 사용해 왔는데 리스트에 카드가 늘어나니까, 최근에 작성한 카드가 맨 아래에 추가되서 눈에 안띄게 됩니다.
카드가 눈에 띄도록 리스트 최상단에 추가해 보겠습니다.

Trello는 보드를 열면 모든 리스트의 스크롤이 최상단에 있기 때문에, 목록에 카드가 많으면 스크롤을 끝까지 내려야 최근에 추가한 카드를 볼 수 있습니다.

리스트 제목 오른쪽에 있는 메뉴를 클릭합니다. 리스트 메뉴는 작고 둥근 회색 버튼이라서 눈에 잘 띄지 않습니다.

Add Card 메뉴를 클릭합니다.

리스트 최상단에 카드 제목을 입력란이 생성됩니다. 내용을 입력하고 Add 버튼을 클릭하면 새 카드가 추가됩니다.

댓글()

Sublime Text 설정과 패키지 동기화 하기(with Dropbox)

Developer Tools|2015. 3. 16. 00:42

Sublime Text에 설치한 패키지와 설정을 여러 컴퓨터에서 동일하게 유지하려면 Packages/User/ 폴더를 공유 저장소에 두고 이를 동기화 해야 합니다. Dropbox를 공유 저장소로 사용하는 동기화 방식을 적용해 봅니다.

기준이 되는 컴퓨터

패키지 설치 및 설정이 완료된 기준 컴퓨터의 설정을 Dropbox로 옮깁니다.

먼저 Sublime Text를 완전히 종료한 후 Windows PowerShell관리자 권한으로 실행합니다.

아래와 같이 PowerShell을 통해 Sublime Text의 Packages/User/ 폴더를 D:\Dropbox\Sublime\User\ 폴더로 대체합니다. Sublime Text 폴더와 Dropbox 폴더는 각자의 설정에 따라 변경해서 적용해야 합니다. 저는 Sublime Text는 기본 위치에 설치했지만, Dropbox는 공유 폴더를 D:\Dropbox로 변경하여 사용 중입니다.

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Windows\system32> # Sublime Text의 Packages 폴더로 이동합니다
PS C:\Windows\system32> cd "$env:appdata\Sublime Text 3\Packages\"
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # Dropbox 공유 폴더에 Sublime 폴더를 생성합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> mkdir D:\Dropbox\Sublime
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # User 폴더를 D:\Dropbox\Sublime 디렉토리로 이동합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> mv User D:\Dropbox\Sublime
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # D:\Dropbox\Sublime\User 폴더에 대한 링크(User)를 생성합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> cmd /c mklink /D User D:\Dropbox\Sublime\User
User <<===>> D:\Dropbox\Sublime\User에 대한 기호화된 링크를 만들었습니다.
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages>

설정을 공유할 다른 컴퓨터

위에서 Dropbox로 옮긴 패키지/설정을 다른 컴퓨터에서도 똑같이 사용하려면 역시 PowerShell을 통해 작업을 해줘야 합니다. Sublime Text를 종료한 후 Windows PowerShell관리자 권한으로 실행합니다.

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Windows\system32> # Sublime Text의 Packages 폴더로 이동합니다
PS C:\Windows\system32> cd "$env:appdata\Sublime Text 3\Packages\"
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # User 폴더와 포함된 모든 폴더/파일을 삭제합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> rmdir -recurse User
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # D:\Dropbox\Sublime\User 폴더에 대한 링크(User)를 생성합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> cmd /c mklink /D User D:\Dropbox\Sublime\User
User <<===>> D:\Dropbox\Sublime\User에 대한 기호화된 링크를 만들었습니다.
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages>

이제 D:\Dropbox\Sublime\User 폴더에 공유된 설정을 통해서 Sublime Text가 실행되기 때문에 양쪽 컴퓨터에서 동일한 개발환경을 사용할 수 있습니다.


댓글()

CentOS 7에 Hadoop 설치

설치&설정|2015. 3. 9. 21:10

CentOS 7에 Hadoop 설치

이전 글에서 CentOS 7을 AWS에 설치 했었습니다.

AWS에 CentOS 7 설치

사실 Hadoop + HBase를 설치하기 위한 사전 작업이어서 오늘은 먼저 Hadoop을 설치해 봅니다.

먼저 JDK를 설치하는 등 기본 환경을 설정합니다.

[centos@ip-172-31-3-215 ~]$ sudo -i

# Oracle JDK 8을 다운로드합니다. 혹 아래 명령으로 다운로드가 안되면 직접 사이트에서 다운로드 해서 가져옵니다
[  root@ip-172-31-3-215 ~]# wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u25-b17/jdk-8u25-linux-x64.tar.gz"

# /opt 디렉토리에 압축을 해제합니다
[  root@ip-172-31-3-215 ~]# tar -zxvf jdk-8u25-linux-x64.tar.gz -C /opt

# 방금 설치한 Oracle JDK를 기본 JDK로 설정합니다
[  root@ip-172-31-3-215 ~]#  /usr/sbin/alternatives --install /usr/bin/java java /opt/jdk1.8.0_25/bin/java 100

# java 버전을 확인합니다
[  root@ip-172-31-3-215 ~]# java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

# /etc/profile 파일에 JAVA_HOME 환경 변수를 추가합니다
[  root@ip-172-31-3-215 ~]# vi /etc/profile
export JAVA_HOME=/opt/jdk1.8.0_25

JDK 설치가 완료됐으면 이제 hadoop 계정을 추가하고 SSH 키를 생성합니다.

# root 계정으로 전환한 후 hadoop 계정을 추가합니다
[centos@ip-172-31-3-215 ~]$ sudo -i
[  root@ip-172-31-3-215 ~]# useradd hadoop
[  root@ip-172-31-3-215 ~]# su - hadoop

# 생성한 hadoop 계정으로 전환한 후 ssh-keygen 명령으로 SSH 키를 생성합니다
[hadoop@ip-172-31-3-215 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hadoop/.ssh/id_rsa):
Created directory '/home/hadoop/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hadoop/.ssh/id_rsa.
Your public key has been saved in /home/hadoop/.ssh/id_rsa.pub.
The key fingerprint is:
92:14:bd:ff:f6:26:bd:4d:ad:39:99:c6:ce:2e:a4:73 hadoop@ip-172-31-3-215
The key's randomart image is:
+--[ RSA 2048]----+
|      ..         |
|       ..        |
|      .  .       |
|     . ..        |
|      o S.       |
|       .  . .   .|
|           + o oo|
|          o E.O= |
|           + OOo.|
+-----------------+

# 암호 없이 ssh 접속이 가능하도록 공개키를 authorized_keys 파일에 추가합니다
[hadoop@ip-172-31-3-215 ~]$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
[hadoop@ip-172-31-3-215 ~]$ chmod 0600 ~/.ssh/authorized_keys
[hadoop@ip-172-31-3-215 ~]$ ssh localhost
Last login: Sun Mar  8 07:01:41 2015

이제 hadoop을 내려받고 설치합니다.

[hadoop@ip-172-31-3-215 ~]$ wget http://apache.mirror.cdnetworks.com/hadoop/common/hadoop-2.5.2/hadoop-2.5.2.tar.gz
[hadoop@ip-172-31-3-215 ~]$ tar xvfz hadoop-2.5.2.tar.gz

.bashrc 파일에 관련 환경 변수를 추가합니다

[hadoop@ip-172-31-3-215 ~]$ cd hadoop-2.5.2
[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ vi ~/.bashrc
export HADOOP_HOME=/home/hadoop/hadoop-2.5.2
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export HADOOP_YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
export JAVA_LIBRARY_PATH=$HADOOP_HOME/lib/native:$JAVA_LIBRARY_PATH

source 명령을 이용해서 환경 변수를 현재 환경에 읽어 들입니다.

[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ source ~/.bashrc

$HADOOP_HOME/etc/hadoop/core-site.xml 파일을 열고

[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ vi etc/hadoop/core-site.xml

아래와 같이 내용을 추가합니다.

<configuration>
  <property>
    <name>fs.default.name</name>
    <value>hdfs://localhost:9000</value>
  </property>
</configuration>

$HADOOP_HOME/etc/hadoop/hdfs-site.xml 파일을 열고

[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ vi etc/hadoop/hdfs-site.xml

아래와 같이 내용을 추가합니다.

<configuration>

  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>

  <property>
    <name>dfs.name.dir</name>
    <value>file:///home/hadoop/hadoopdata/hdfs/namenode</value>
  </property>

  <property>
    <name>dfs.data.dir</name>
    <value>file:///home/hadoop/hadoopdata/hdfs/datanode</value>
  </property>

</configuration>

$HADOOP_HOME/etc/hadoop/mapred-site.xml 파일을 열고

아래와 같이 내용을 추가합니다.

<configuration>

  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>

</configuration>

namenode를 포맷합니다.

[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ hdfs namenode -format

Hadoop을 시작합니다.

# dfs daemon을 시작합니다
[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ start-dfs.sh
Starting namenodes on [localhost]
localhost: starting namenode, logging to /home/hadoop/hadoop-2.5.2/logs/hadoop-hadoop-namenode-ip-172-31-3-215.ap-northeast-1.compute.internal.out
localhost: starting datanode, logging to /home/hadoop/hadoop-2.5.2/logs/hadoop-hadoop-datanode-ip-172-31-3-215.ap-northeast-1.compute.internal.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /home/hadoop/hadoop-2.5.2/logs/hadoop-hadoop-secondarynamenode-ip-172-31-3-215.ap-northeast-1.compute.internal.out

# yarn daemon을 시작합니다
[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /home/hadoop/hadoop-2.5.2/logs/yarn-hadoop-resourcemanager-ip-172-31-3-215.ap-northeast-1.compute.internal.out
localhost: starting nodemanager, logging to /home/hadoop/hadoop-2.5.2/logs/yarn-hadoop-nodemanager-ip-172-31-3-215.ap-northeast-1.compute.internal.out

jps(Java Virtual Machine Process Status Tool)로 java 프로세스를 확인합니다.

[hadoop@ip-172-31-3-215 hadoop-2.5.2]$ $JAVA_HOME/bin/jps
4981 NodeManager
5400 Jps
4889 ResourceManager
4747 SecondaryNameNode
4494 NameNode


댓글()

GitHub 저장소 Fork 하기

Developer Tools|2015. 3. 5. 20:50

다른 사람의 저장소에 있는 코드를 수정하려면 그 저장소를 Fork한 후에 수정을 하고 pull request를 저장소 소유자에게 보내야합니다.

APM 툴인 Pinpoint 프로젝트를 마음껏 수정해 보려고 Fork를 해 봤습니다.

Fork

브라우저에서 Pinpoint 저장소 페이지로 이동한 후, Fork를 클릭하여 저장소를 나의 Repositories로 복사합니다.

Fork가 완료되면 복사된 저장소로 화면이 이동합니다.

Clone

저장소 페이지 우측에 있는 저장소 주소를 복사합니다.

명령 프롬프트를 실행하고 적당한 디렉토리로 이동한 후 git clone 명령으로 저장소를 clone합니다.

$ git clone git clone git@github.com:GITHUB-ID/pinpoint.git
Cloning into 'pinpoint'...
remote: Counting objects: 91067, done.
remote: Total 91067 (delta 0), reused 0 (delta 0), pack-reused 91067
Receiving objects: 100% (91067/91067), 151.06 MiB | 229.00 KiB/s, done.
Resolving deltas: 100% (47414/47414), done.
Checking connectivity... done.
Checking out files: 100% (4180/4180), done.

clone이 완료되면 생성된 pinpoint 디렉토리로 이동한 후 git remote add 명령을 사용하여 원본 저장소를 upstream이라는 이름으로 추가합니다.

추가한 후에는 git remote -v 명령으로 원격 저장소 목록을 확인할 수 있습니다.

$ git remote add upstream git@github.com:naver/pinpoint.git

$ git remote -v
origin  git@github.com:GITHUB-ID/pinpoint.git (fetch)
origin  git@github.com:GITHUB-ID/pinpoint.git (push)
upstream        git@github.com:naver/pinpoint.git (fetch)
upstream        git@github.com:naver/pinpoint.git (push)

댓글()

Trello 일정을 구글 캘린더와 연동하기

DevOps|2015. 2. 26. 11:16

Trello 보드에 있는 카드에 누군가 Due date를 설정하면 이게 하나의 일정이 됩니다.

그런데 저는 일정 관리를 모두 구글 캘린더를 통해 하고 있기 때문에 이 관리 안되는 Trello 일정이 꽤나 거슬렸습니다. Sunrise라는 Trello를 지원하는 캘린더 앱을 사용하고 있지만 캘린더 앱 두 개를 사용하는건 쉽지 않습니다.

찾아 보니 Trello는 iCal 형식의 캘린더 주소를 제공하고 있었습니다. 그것도 모르고 이래저래 괜한 시간낭비를 한 저 자신을 원망하면서 연동 방법을 남깁니다.

Trello 보드에서 iCalendar Feed URL 얻기

Trello 보드 우상단에 있는 Menu의 하위 메뉴 Power-Ups를 클릭합니다.

Power-Ups에서 Calendar를 클릭하고 Enable을 클릭하여 Calendar를 활성화합니다. 이렇게 하면 위 이미지 좌상단에 보이는 Calendar 메뉴가 생기며, 이 메뉴를 통해 달력 형식으로 보드에 있는 일정을 볼 수 있습니다.

Enable iCalendar Feed? 항목에 있는 Enable을 클릭하면 바로 아래에 있는 Your Personal iCalendar Feed에 Feed URL이 생성됩니다. 이 URL을 복사합니다.

구글 캘린더에 추가하기

이제 구글 캘린더로 이동한 후 화면 좌측 중간쯤에 있는 다른 캘린더 > URL로 추가를 클릭합니다.

URL란에 아까 복사한 Feed URL을 붙여넣기 한 후 캘린더 추가를 클릭하면 연동이 완료됩니다.

아쉽지만 캘린더를 추가한 후에 바로 Trello 일정이 구글 캘린더에 나타나지는 않습니다. 하루 한 번 정도 구글 마음대로 동기화를 한다고 합니다.


댓글()

angular-translate를 이용해서 Angular 앱에 국제화(i18n) 적용하기

JavaScript|2015. 2. 25. 00:48

개요

여러 언어를 지원하는 Angular 앱을 만들려면 i18n을 지원하는 모듈이 필요합니다. 찾아 보면 여러 가지가 있겠지만 여기에서는 angular-translate라는 모듈을 소개합니다.

angular-translate는 최소한의 기능만 간편하게 사용하거나, 따로 제공되는 여러 확장점을 이용해서 강력하고 복잡한 기능을 구현할 수 있는 유연한 모듈입니다.

angular-translate 홈페이지로 이동

설치

Bower를 이용해서 설치할 수 있습니다. Bower를 설치한 후 아래의 명령을 실행하면 됩니다.

$ bower install angular-translate

간단 사용법

먼저 angular-translate.js의 경로를 명시한 script 태그를 angular.js 에 넣어줍니다.

<script src="angular.js"></script>
<script src="angular-translate.js"></script>

pascalprecht.translate 모듈에 대한 의존성을 설정해 줍니다.

var app = angular.module('myApp', ['pascalprecht.translate']);

번역어 목록(translation table)을 작성하고 이를 language key en과 함께 $translateProvider의 translations 메소드로 전달합니다. 아래 예제에서는 영어(en)에 대한 번역어 목록만 전달했지만 여러번 호출하여 다른 언어에 대한 번역어 목록도 추가로 전달할 수 있습니다.

$translateProvider의 preferredLanguage 메소드에 language key en을 전달하여 영어를 기본 언어로 설정합니다.

var app = angular.module('myApp', ['pascalprecht.translate']);

var translations = {
    HEADLINE: 'What an awesome module!',
    PARAGRAPH: 'Srsly!',
    NAMESPACE: {
        PARAGRAPH: 'And it comes with awesome features!'
    },
    PASSED_AS_TEXT: 'Hey there! I\'m passed as text value!',
    PASSED_AS_ATTRIBUTE: 'I\'m passed as attribute value, cool ha?',
    PASSED_AS_INTERPOLATION: 'Beginners! I\'m interpolated!'
};

app.config(['$translateProvider', function ($translateProvider) {
    $translateProvider
        .translations('en', translations)
        .preferredLanguage('en');
}]);

이제 filter, directive, interpolation을 아래와 같이 사용하면 번역어가 출력됩니다.

<p>{{ 'HEADLINE' | translate }}</p>
<p>{{ 'PARAGRAPH' | translate }}</p>

<p translate>PASSED_AS_TEXT</p>
<p translate="PASSED_AS_ATTRIBUTE"></p>
<p translate>{{ 'PASSED_AS_INTERPOLATION' }}</p>
<p translate="{{ 'PASSED_AS_INTERPOLATION' }}"></p>

angular-translate 사이트의 Using translate directive 페이지로 이동한 후 하단에 있는 Source 부분 우측에 있는 Edit를 클릭 후 다시 In JsFiddle을 클릭하면 동작하는 예제를 볼 수 있습니다.

여기까지 간단한 angular-translate 사용법이었습니다.


'JavaScript' 카테고리의 다른 글

Enyo 기반 webOS TV 앱 개발 팁  (0) 2014.08.04
webOS TV SDK 설치 방법  (0) 2014.07.29

댓글()

XnConvert를 이용한 이미지 일괄 변환

기타|2015. 2. 22. 17:33

브로셔 등의 문서 자료를 카메라로 찍은 후 스마트폰으로 볼 때 가독성이 문제가 되는 경우가 많습니다.
이럴 때 저는 이미지 편집툴을 사용해서 아래와 같이 몇 가지 전처리를 한 후에 사용합니다.

  • 흑백(Greyscale)으로 변환
  • 선명하게 처리(Sharpen)
  • 대비(Contrast) 조정

이렇게 전처리를 하면 글자가 선명해져서 눈이 좀 더 편합니다.
지금까지는 Comic4Portable을 사용해서 위와 같은 전처리를 해왔습니다.

그런데 이미지의 양쪽을 일정 부분 잘라내어야 하는 일이 생겨서 오늘은 다른 툴을 찾아봤습니다.
그래서 찾아낸 툴이 XnConvert! 저에게 필요한 전처리와 잘라내기(Crop)을 모두 지원합니다.
아래 링크에서 내려받아서 무료로 사용할 수 있습니다.

XnConvert 내려받기

간단 사용법

XnConvert를 실행하면 Input 탭에서 시작합니다. 먼저 처리가 필요한 이미지를 끌어다 놓기 하거나 좌측 하단에 있는 Add files, Add folder를 클릭해서 가져옵니다.

Input

가져온 이미지를 일괄 변환하기 위해서 Actions 탭을 클릭하여 이동한 후, 다시 Add action을 클릭하여 Image, Map, Filter, Misc 등의 여러가지 전처리기를 적용합니다. 저는 Filter > Sharpen, Map > Automatic contrast, Image > Change color depth, Image > Crop을 추가하고 각각의 세부 옵션을 조정했습니다(세부 옵션은 아래 이미지를 참조하세요).

Actions

이제 Output 탭을 클릭하여 이동한 후, 변환된 파일을 저장할 위치나 파일명을 조정할 수 있습니다. 저는 D:\ImageOutput로 저장 위치를 지정하고 파일명 형식으로는 원본 파일명 뒤에 _result 문자열을 덧붙이는 {Filename}_result을 선택했습니다.

Output

마지막으로 우하단에 있는 Convert를 클릭하여 이미지 일괄 변환을 시작합니다. 변환이 완료되면 자동으로 Status 탭으로 이동하면서 변환 내역을 보여주며, 지정한 Output folder에는 변환된 이미지가 생성됩니다.

Status


댓글()