프로그래머들에게 코드 재사용이라는 것은 언제나 중요한 이슈이다. 많은 사람들이 자주 사용할 수 있을 만한 코드나, 개인 혹은 단체가 여러 프로젝트에서 공통적으로 사용할 만한 코드는 라이브러리화한다는 것은 익숙한 사실이다.
이번에 쿠팡 클론 코딩 프로젝트에서 spring Cloud를 이용해 MSA를 구축해보는 것을 프로젝트의 주된 목표 중 하나로 잡았다. MSA에서는 마이크로서비스 간의 호출이 빈번하게 일어나며, 보통 json으로 넘어오는 서비스의 응답을 deserializing해서 받을 DTO 객체를 모든 마이크로서비스에서 필요로 한다.
그래서 이런 경우에는 빈번하게 발생하는 요청의 본문과 응답 본문을 담은 라이브러리를 하나 만들어 마이크로서비스가 이를 공유할 수 있도록 하는 것이 좋겠다고 생각했다.
나는 kotlin과 spring을 이용해 프로젝트를 진행하고 있기 때문에, 구체적으로 내가 만든 artifact를 maven central 중앙 저장소에 publishing 하는 방법을 학습해보았다.
OSSRH는 sonatype nexus 라는 회사에서 지원하는 서비스로, 이 서비스를 통해 오픈 소스 코드를 레포지토리의 형태로 호스팅할 수 있다. 자세한 소개는 여기를 참고하자. 레포지토리를 정상적으로 호스팅하기 위해 필요한 절차는 크게 아래와 같다.
우선 나의 artifact를 배포하려면 group에 대응하는 project ticket이라는 것을 만들어야 한다. 여기서 group Id는 신뢰할 수 있는 도메인에 대응하게끔 적어야 하며, 나는 github 도메인을 이용해 com.github.BaekGeunYoung 으로 group Id를 작성했다.
SCM은 Source Control Management의 약자로, github이나 bitbucket, svn 등의 주소를 적어주면 된다.
ticket은 resolved 상태가 되어야 정상적으로 사용할 수 있게 되는데, 문제가 없다면 ticket을 생성하고 몇 분 후 resolved 상태가 된다. 나의 경우 아래와 같이 깃헙 계정에 대한 소유권 확인을 요청해서 특정 레포지토리를 생성하고 나서야 ticket이 resolved 상태로 바뀌었다.
gpg와 관련해서 해야 하는 세부 작업은 아래와 같다.
> gpg --gen-key
위 커맨드를 입력하고 real name과 user email, 그리고 서명 시에 사용할 passphrase를 적절히 입력하면 key pair가 잘 발급된다.
gpg는 public key를 관리하는 곳이 여러 군데 존재한다. 그 중 나는 keyserver.ubuntu.com이라는 곳에 나의 공개키를 보낼 것이다.
> gpg --keyserver http://keyserver.ubuntu.com --send-keys [my_public_key]
별 문제 없이 잘된다.
이 작업은 gradle 스크립트를 통해 해줄 것이다.
나는 gradle을 통해 작업을 진행했다. gradle 커맨드를 통해 artifact를 maven central에 업로드하기 위해서는 원하는 작업을 실행할 수 있도록 프로젝트의 build.gradle 파일에 내용을 추가해야 한다. 구체적인 내용은 여기를 참고하자.
build.gradle에서는 외부로부터 ossrh의 계정 정보, gpg key 정보 등을 받아오기 때문에, 이를 gradle.properties에 작성해주어야 한다. 이 파일이 들어갈 위치는 윈도우 기준 ~/.gradle/gradle.properties
이다.
gradle.properties
signing.keyId=[pubilc key id]
signing.password=[passphrase]
signing.secretKeyRingFile=[secret keyring file path]
ossrhUsername=[ossrh username]
ossrhPassword=[ossrh password]
각각의 변수에 값을 잘 넣어주면 되는데, secretKeyRingFile
의 경우 gpg 2.1 버전 이후로는 키페어 생성 시에 secret keyring file을 따로 만들어주지 않는다고 한다. 그래서 gpg --export-secret-keys -o secring.gpg
명령어를 입력해 직접 파일을 만들어주어야 한다.
업로드 성공 !
여기서 끝인줄 알았지만, 끝이 아니었다.. gradle을 이용해 artifact를 업로드하면 바로 release되는 것이 아니라 stagig repository로 올라가게 된다. 이 repository를 release 하려면 open되어 있는 repository를 close 상태로 만들고, release 버튼을 직접 클릭해야 한다.
위와 같이 nexus repostiory manager 페이지에 접속하면 staging repository를 확인할 수 있다.(현재는 release를 완료한 상태여서 보이지 않는다.) 아무튼 여기서 repository를 close하고, release하면 정상적으로 maven central에 내 라이브러리가 배포된다.
여기에 들어가면 maven central에 배포되어 있는 라이브러리들을 모두 확인할 수 있다.
배포가 잘 되어 있다.
release가 잘 완료되면 아까 만들어두었던 jira ticket에 위와 같은 코멘트가 달린다. central과의 synchronize가 잘 활성화되었고, 앞으로 release를 하면 10분 내로 maven central에 반영될 것이라는 기쁜 소식이다!
내가 배포한 라이브러리에는 아래와 같은 SpecialCharacterHandler 클래스가 존재한다. 이 클래스는 urlencode된 특수문자들을 원래의 문자로 변환해주는 역할을 한다.
class SpecialCharacterHandler {
companion object {
fun decode(str: String): String {
var returnStr = str
returnStr = returnStr.replace("<br>", "\n")
returnStr = returnStr.replace(">", ">")
returnStr = returnStr.replace("<", "<")
returnStr = returnStr.replace(""", "\"")
returnStr = returnStr.replace(" ", " ")
returnStr = returnStr.replace("&", "&")
return returnStr
}
}
}
이 라이브러리를 사용하고자 하는 프로젝트의 build.gradle
파일에서 dependencies 부분에 아래 한 줄을 추가한다.
implementation "com.github.BaekGeunYoung:example-application:1.4.7"
그러고 나면 아래처럼 라이브러리 안의 모듈을 자유롭게 사용할 수 있다.
fun testFun() {
println(SpecialCharacterHandler.decode("><" "))
}
개발자로 공부를 하면서 라이브러리도 기회가 된다면 직접 만들어봐야겠다는 생각을 줄곧 해왔는데, MSA 프로젝트를 하면서 좋은 경험을 할 수 있었다. 부가적으로 gradle과 maven 등 자바의 의존성 관리 모듈의 작동 방식에 대해서도 이전보다 깊이 이해할 수 있게 된 것 같다.
https://central.sonatype.org/pages/gradle.html
https://www.youtube.com/watch?v=bxP9IuJbcDQ
https://medium.com/@entzik/how-to-publish-open-source-java-libraries-to-maven-central-70f9232462f5