まず、公式で公開されているJavaのクライアントライブラリはこちらです.
GoogleCloudPlatform/google-cloud-java
サービスアカウントの認証を用いて実行する
GCPサービスを利用する場合, 認証周りはデフォルトでは gcloud auth application-default login
や GOOGLE_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を実装する際に,
ProjectId
と kind
の初期化を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()
}