Kotlin, AWS 그리고 레이니스트와 함께라면 육군훈련소에서도 외롭지 않아

올해 Google IO에서 KotlinAndroid 공식 언어로 선정되었는데요, 레이니스트에서는 작년부터 뱅크샐러드 Android 앱을 100% Kotlin으로 작성하고 있습니다.

It’s real

Kotlin의 특징 중 하나는 Java와 100% 호환된다는 점인데요, 이번 포스트에서는 AWSLambda FunctionKotlin으로 작성한 경험을 공유하고자 합니다.

들어가면서

레이니스트는 병무청에서 지정한 병역지정업체입니다. 아직 병역의 의무를 해결하지 못한 분이라면 레이니스트에서 산업기능요원으로 근무하면서 병역의 의무를 함께 할 수 있습니다. (현재는 보충역 대상자만 가능합니다)

저는 올해 초부터 레이니스트에서 산업기능요원으로 병역의 의무를 수행하고 있는데요. 열심히 뱅크샐러드 앱을 만들고 있는 도중 한 통의 편지를 받게 됩니다.

국방의 의무 축하해~♪

바로 군사교육 소집 통지서였습니다. 통지서를 받고 나서 (말로만) 훈련을 받거나 사회 소식을 못 듣는 건 별로 걱정이 되지 않았는데 회사 소식을 4주 동안 못 듣게 되면 나오고 나서 업무를 진행하는데 흐름을 못 탈 것 같아(?) 회사 동료분들께 편지 작성을 부탁드릴 간단한 Slack Bot을 만들기로 했습니다. Slack에서 기본적으로 제공하는 Reminder를 사용해도 되지만 AWS Lambda를 활용해보고 싶어 주말에 조금씩 시간을 내서 만들기로 했습니다.

사실 주말에 할게 없어서…

만들기 시작!

사실 처음 목표는 육군훈련소 홈페이지에 자동으로 편지를 쓰게 해주는 Lambda Function을 만들계획이었으나, 본인인증이라는 거대한 벽에 막혀 다음과 같은 흐름을 가지는 Lambda Function을 만들기로 했습니다.

간단하쥬?

가장 먼저, Slack API 사이트에서 Slack App을 만들고 Lambda Function에서 Slack 채널로 메시지를 보낼 때 사용할 Webhook URL을 발급받습니다. 생성된 Slack App을 관리 페이지 좌측의 Incoming Webhooks에서 다음 사진과 같이 Webhook URL을 발급받을 수 있습니다.

Lambda Function 작성하기

먼저 aws-lambda-java-coregradle dependency로 추가하고, Lambda FunctionEntry Point 역할을 할 RequestHandler를 구현합니다.

handleRequest를 구현하면 됩니다

handleRequest 메소드를 어떻게 작성할까 고민하다, 뱅크샐러드 안드로이드 앱의 UseCase처럼 코드를 작성하기로 했습니다. (자세한 내용은 Droid Knights 2017에서 저희 CTO님께서 발표하신 Clean Architecture in Android발표를 참고해주세요)

일단, 육군훈련소 홈페이지에서 제가 배치된 연대, 중대, 소대 정보를 가져올 KATCRepository, 편지 써줄 사람을 지목하고 채널에 메시지를 보낼 SlackRepository, 채널에 보낼 메시지를 만들 MessageRepository, 끝으로 지목당한 분이 편지에 쓸 내용이 없는 경우를 대비해 편지에 바깥 세상(?) 소식 요약본을 담기 위한 NaverNewsRepository, 총 4개를 만들었습니다.

Repository의 각 메소드들은 비동기 처리를 위해 Single, 혹은 Completablereturn하게 되어있는데, .blockingGet()을 사용하면 Stream이 종료될 때 Lambda Function이 종료될 수 있도록 blocking 처리 할 수 있습니다.

Slack Bot을 다 만들었으니, 이제 AWS에 업로드하는 일만 남았습니다. Gradle Scriptjar task를 추가해서 jar파일로 빌드합니다.

AWS Console을 통해 Lambda Function을 생성해주고, 생성된 jar파일을 업로드 하면 되는데요. trigger는 일단 비워둔 상태로, Lambda 함수 핸들러 및 역할 다음과 같이 런타임은 Java8, 핸들러는 package.classname::handlerMethodName형식으로 생성하면 됩니다.

Slack Bot의 전체 소스는 GitHub에서 확인하실 수 있습니다.

CloudWatch Event 만들기

이제 일정 주기마다 위에서 생성한 Lambda Function을 실행을 시켜야 하는데, 이 문제는 CloudWatch Event로 간단하게 해결할 수 있습니다. CloudWatch EventCron식을 지원하는데요. 저는 화요일, 금요일 아침 9시에만 메시지를 보내기로 했으므로 다음 식을 사용했습니다.

0 0 ? * TUE, FRI *

여기서 중요한 점은 시간대가 GMT +0으로 설정되어있기 때문에, 서울 시간 기준으로 -9시간을 해줘야 원하는 스케줄대로 작동합니다. Cron식을 입력하고 화면 우측의 호출할 대상을 위에서 생성한 Lambda 함수로 지정하면, 모든 준비가 끝납니다!

끝!

입소, 그리고 수료

입소하고 시간은 흐르고 흘러 CloudWatch Event가 발생하는, 그리고 슬랙봇이 작동할 수도 있는 첫 번째 화요일이 되었습니다. 제 입소 정보는 화요일 오후쯤에 육군훈련소 홈페이지에 올라가니 편지가 오지 않을 거라 예상 했으나…

다시봐도 감동

봇이 작동하지 않았음에도 첫날에 편지가 두 통이나 왔습니다 ㅠㅠ

가… 감동이야… (슬랙 봇 같은건 필요 없었어!)

동료 분들과 가족들에게 편지를 받고 나니, 봇이 정상적으로 동작하는지 안 동작하는지 확인할 수 있는 금요일이 손꼽아 기다려지기 시작했습니다. (사회소식이 궁금하지 않다고 했었지만 진짜 궁금해서 애가 탔었… 볼 수 있는 게 국방일보 밖에 없었습니다 ㅠㅠ)

그리고 손꼽아 기다리던 금요일 저녁, 편지가 도착했습니다!

기술부채 말고 편지부채!
편지 써준다던 친구들은 거의 안써주고…
레이니스트 더럽… the love…

수료하고 난 뒤 Slack을 켜서 봇이 동작한 모습을 보니 뿌듯한 마음 반, 편지 써주신 동료분들에 대한 감사의 마음 반으로 가득 찼습니다.

돌아와서 슬랙을 보니…

글을 맺으며

  1. KotlinJava와 100% 호환되기에 AWS Lambda FunctionKotlin으로도 작성할 수 있습니다.
  2. 레이니스트에서 금융정보의 비대칭성을 함께 해결해 나갈 개발자를 찾습니다. (산업기능요원 보충역 신규 편입 / 전직 가능)
  3. 군인에게 편지는 힘이 됩니다 (저희와 함께하시다 훈련소 가시게 되면 제가 1주일에 2번 편지써드릴께요 ㅠㅠ)

아, 마지막으로 다시 한번 편지를 써주신 분들께 감사의 말씀을 전합니다 ㅠㅠ

읽어주셔서 감사합니다 :D