投稿者:國藤 篤規(エヌアイシーソフト)

こんにちは。
今回から、こちらで作ったKotlinアプリを、Google Cloud Platform で動かしてみます。まずは Google App Engine(Standard)で動かしてみます。

Firestore へ置き換え


まず、Cloudant を GCPで提供されているデータベースであるFirestoreに置き換えます。Java のクライアントライブラリを追加します。

build.gradle

dependencies {
    ...
    compile group: 'com.google.cloud', name: 'google-cloud-firestore', version: '0.72.0-beta'
}

Java からの接続方法は以下になります。

FirestoreOptions.getDefaultInstance().service

GCPではプロジェクトという単位でリソースを管理していきますが、同一プロジェクトにある Firestore の場合は、特に接続情報を指定することなく接続できます。

War生成


Google App Engine(Standard) の Javaの場合、war でデプロイする必要があります。つまり、アプリケーションサーバもPaaS側で提供されている形です。一方で、Ktor は Uber Jar の中にアプリケーションサーバ(Netty)が同梱されている形式がデフォルトです。そのため、War形式に変更するために、web.xmlを追加します。

web.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <!-- path to application.conf file, required -->
    <!-- note that this file is always loaded as an absolute path from the classpath -->
    <context-param>
        <param-name>io.ktor.ktor.config</param-name>
        <param-value>application.conf</param-value>
    </context-param>

    <servlet>
        <display-name>KtorServlet</display-name>
        <servlet-name>KtorServlet</servlet-name>
        <servlet-class>io.ktor.server.servlet.ServletApplicationEngine</servlet-class>

        <!-- required! -->
        <async-supported>true</async-supported>

    </servlet>

    <servlet-mapping>
        <servlet-name>KtorServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

build.gradle には、war の形式変更に必要なモノののほかに、GAE へのデプロイを行うプラグインもインストールします。

build.gradle

buildscript {
    ext.appengine_version = '1.9.60'
    ext.appengine_plugin_version = '1.3.4'

    dependencies {
        classpath 'com.google.cloud.tools:appengine-gradle-plugin:1.+'    // for GAE
    }
}

apply plugin: 'war'                               // for GAE
apply plugin: 'com.google.cloud.tools.appengine'  // for GAE

dependencies {
    compile group: 'com.google.cloud', name: 'google-cloud-firestore', version: '0.72.0-beta'
    compile "io.ktor:ktor-server-servlet:$ktor_version"
    providedCompile "com.google.appengine:appengine:$appengine_version"

    testCompile "io.ktor:ktor-server-tests:$ktor_version"
}

appengine {  // App Engine tasks configuration
    deploy {   // deploy configuration

    }
}

group   = "com.example.appenginej8"        // Generated output GroupId
version = "1.0-SNAPSHOT"       // Version in generated output

sourceCompatibility = 1.8     // App Engine Flexible uses Java 8
targetCompatibility = 1.8     // App Engine Flexible uses Java 8

kotlin.experimental.coroutines = 'enable'

最後に、web.xml と同じディレクトリに、App Engine のための設定ファイルを追加します。

appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application>alert-tiger-999999</application><!-- unused for Cloud SDK based tooling -->
    <version>alpha-001</version><!-- unused for Cloud SDK based tooling -->
    <runtime>java8</runtime>
    <threadsafe>true</threadsafe>
</appengine-web-app>

デプロイ


まず、warプラグインを起動して、war を生成します。

war 作成

Google Cloud SDK をローカルマシンにインストールし、以下のコマンドを実行します。

gcloud init
gcloud auth application-default login
gcloud components install app-engine-java
gcloud components update

デプロイそのものは、gradleプラグインで実行します。

デプロイ

これで、Google App Engine(Standard) でKotlinアプリを動かすことが出来ました。

おわりに


今回はもともと jar 形態のものをあとから war 形式に変更しているため、多少手順が複雑になっています。当初からGAEで動かす場合は、各種雛形から作れるので、もう少しラクになると思います。