LoginSignup
2
2

More than 5 years have passed since last update.

Kotlinでgoogle-cloudライブラリを扱う

Last updated at Posted at 2018-02-18

まず、公式で公開されているJavaのクライアントライブラリはこちらです.

GoogleCloudPlatform/google-cloud-java

サービスアカウントの認証を用いて実行する

GCPサービスを利用する場合, 認証周りはデフォルトでは gcloud auth application-default loginGOOGLE_APPLICATION_CREDENTIALS をマシン側で設定する必要があります。

その場合のサービスの利用は例えばBigQueryサービスの場合, このようなAPIが提供されています。

import com.google.cloud.bigquery.BigQueryOptions

fun main() {
    val bigquery = BigQueryOptions.getDefaultInstance().getService()
}

ただ、プロジェクトメンバー内で共通のサービスアカウントで認証を通したいことがあります。

コード内からサービスアカウントのjson key fileを読み込む方法を共有します。

import com.google.auth.oauth2.GoogleCredentials
import com.google.auth.oauth2.ServiceAccountCredentials

object Misc {
    // サービスアカウントのCredentialsをロードする
    fun loadCredentials(account_path: String): GoogleCredentials {
        // Google認証ファイルの読み込み
        val credentials = FileInputStream(account_path).use {
            ServiceAccountCredentials
                .fromStream(it)
        }
        return credentials
    }
}

json key fileを読み込み GoogleCredencials クラスのオブジェクトとして保持できます。

Optionsに適用する書き方は,

import com.google.cloud.bigquery.BigQueryOptions

fun main() {
    val credentials = Misc.loadCredentials("<SERVICE_ACCOUNT_PATH>")
    val options = BigQueryOptions.newBuilder().setCredentials(credentials).build()
}

そして BigQueryOptions#getDefaultInstance() の代わりに生成したoptionsオブジェクトからそのまま getService() が実行できます.

fun main() {
  val bigqury = options.getService()
}

Builder Pattern

これらを踏まえて, サービスアカウントによる認証をOptional(任意)とし,

サービスアカウントによるサービスの利用もしくはそれをしない場合はDefaultによる利用といった操作が可能な設計をします.

import com.google.auth.oauth2.GoogleCredentials
import com.google.cloud.bigquery.BigQueryOptions
import com.google.cloud.bigquery.QueryJobConfiguration

class BigQueryIO(options: BigQueryOptions?) {
    val options = options

    private constructor(builder: Builder): this(builder.options)
    class Builder() {
        var options: BigQueryOptions? = null
            private set

        fun setCredentials(credentials: GoogleCredentials) = apply {
            this.options = BigQueryOptions.newBuilder().setCredentials(credentials).build()
        }
        fun build() = BigQueryIO(this)
    }

    fun runQuery(sql: String) {
        val bigquery = options?.getService() ?: BigQueryOptions.getDefaultInstance().getService()
        val queryConfig = QueryJobConfiguration.newBuilder(sql).build()
        // run Query
        val result = bigquery.query(queryConfig)
        // ...
    }
}

このクラスの使い方は以下です.

fun main() {
    // サービスアカウント認証による利用
    val credentials = Misc.loadCredentials("<SERVICE_ACCOUNT_PATH>")
    val bq = BigQueryIO.Builder().setCredentials(credentials).build()
    // default認証による利用
    val bq = BigQueryIO.Builder().build()

    // SQLを実行
    bq.runQuery(sql)
}

options をOptionalにすることで, Nullの場合に options?.getService() はエルビス演算子(?:)の左の式を評価します.

このBuilder patternだとあんまり意味ないですが, 例えばDatastoreIOを実装する際に,

ProjectIdkind の初期化をrequired(必須)とする場合はこうです.

import com.google.auth.oauth2.GoogleCredentials

import com.google.cloud.datastore.DatastoreOptions

class DatastoreIO(projectId: String, kind: String, options: DatastoreOptions?) {
    val projectId = projectId
    val kind = kind
    val options = options

    private constructor(builder: Builder): this(builder.projectId, builder.kind, builder.options) 
    class Builder(
        val projectId: String, val kind: String
    ) {
        val options: DatastoreOptions? = null
            private set

        fun setCredentials(credentials: GoogleCredentials) = apply {
            this.options = DatastoreOptions.newBuilder().setCredentials(credentials).build()
        }
        fun build() = DatastoreIO(this)
    }
}

使い方はこうです.

fun main() {
    // サービスアカウント認証による利用
    val projectId = "<PROJECT_ID>"
    val kind = "<KIND>"
    val credentials = Misc.loadCredentials("<SERVICE_ACCOUNT_PATH>")
    val bq = DatastoreIO.Builder(projectId, kind).setCredentials(credentials).build()
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2