GCSへのファイル転送をVBScriptで実装してみた


はじめに

外部サービスとのデータ連携でGoogle Cloud Storage(以下GCS) を利用しました。
Cloud Client LibrariesでサポートされていないVBScriptで実装したため、その内容をまとめます。

前提

  • 処理形式・・・バッチ
  • アウトプット・・・TSVファイル
  • 言語・・・VBScript

今回は既存改修だったため、上記の前提となりました。
※ビジネスロジックの変更は必要なく、転送先の変更が必要だったため。

転送方式

GCSにファイル転送する方法としては大きく2つあると思います。

API(XML、JSON)を利用して転送する
gsutilをインストールしてコマンドラインで転送する

比較すると、

①の場合
 ・提供されているライブラリを利用するだけで良い
 ・また、認証周りがよりシームレスに行える
 ・実装例が豊富にある

②の場合
 ・サーバーへのインストールが必要になる
 ・故に、再セットアップ、あるいはリプレイスの際に再インストールが必要になる
 ・プログラムに組み込んだ前例が見当たらない

採用した方式

本来であれば①の方式が望ましいと思いますが、前提の通り、言語がVBScriptという制約のもと(ライブラリでサポートされていないため)②の一択となりました。

JSON APIの自前実装をトライしたのですが、認証のアカウントコード取得でうまくいきませんでした。トライした内容を紹介するにはボリュームがあるので割愛します。

gsutil(Google Cloud SDK)のインストール

まずはgsutilをインストールします。gsutilはGoogle Cloud SDKに内包されています。

1.Google Cloud SDK のインストーラをダウンロードする

2.ダウンロードしたインストーラを実行する

3.「Next」を押下する

4.「I Agree」を押下する

5.デフォルトのまま「Next」を押下する

6.デフォルトのまま「Next」を押下する

7.デフォルトのまま「Install」を押下する
※Python 2.7.9 以降が入っていればPythonのチェックを外して良い

8.Install完了後、「Next」を押下する

9.セットアップ完了画面でチェックを全て外し「Finish」を押下する
※キャプチャではチェックが入っているが必要ない

構成

ものすごくザックリ紹介しますが、構成はこんな感じです。送信コマンドをbatファイルで別にした理由としては、
 ・今後、複数の転送先が予想されるから
 ・それにともない複数のプログラムから利用できたら便利だし管理しやすいから
 ・また、リカバリーを行う際、batファイル単体実行でファイル送信が可能になるから
    ∟個人的な感覚ですが、AWSなんかと比べてGCPは管理画面が操作しにくいです
    ∟または、操作権限をもたないメンバーなどがリカバリーを行う際にも有効かと思います

という感じで少しだけ汎用的な作りにしています。

実装

1.GoogleCloudPlatformでサービスアカウントを作成する
  ・参考:Cloud Client Librariesの「認証のセットアップ」

2.作成したアカウントのサービスアカウントファイル(JSONファイル)をダウンロードする

service_account.json
{
  "type": "service_account",
  "project_id": "project_id",
  "private_key_id": "*************",
  "private_key": "-----BEGIN PRIVATE KEY-----\**********\n-----END PRIVATE KEY-----\n",
  "client_email": "*****@******.iam.gserviceaccount.com",
  "client_id": "*************",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/*************.iam.gserviceaccount.com"
}

3.バケット、またはフォルダーを作成する(転送先ディレクトリを作成する)

4.batファイルを作成する

SendFile.bat
@echo off
SETLOCAL
SET ACCOUNT_SERVICE=%1
SET PROJECT_ID=%2
SET CLIENT_EMAIL=%3
SET INPUT_FILE=%4
SET BUCKET_FOLDER=%5
SET DESTINATION=gs://%BUCKET_FOLDER%
@echo on

gcloud auth activate-service-account %CLIENT_EMAIL% --key-file %ACCOUNT_SERVICE% --project %PROJECT_ID% && gsutil cp %INPUT_FILE% %DESTINATION%
@echo return code%errorlevel%

@echo off
ENDLOCAL
if not %errorlevel% == 0 (
    exit /B 1
)
exit /B 0

5.VBScriptでbatファイルの実行処理を実装する

SendFile.wsf
Public Function SendFile()
    Dim Shell : Set Shell = CreateObject("WScript.Shell")
    Dim batPath : batPath = "SendFile.batパス"
    Dim batLogPath : batLogPath = "bat.logパス"
    Dim accountServicePath : accountServicePath = "アカウント名.jsonパス"
    Dim projectId : projectId = "projectId" 
    Dim clientEmail : clientEmail = 'clientEmail'
    Dim bucketName : bucketName = "bucketName"
    Dim folderName : folderName = "folderName"
    Dim filePath : filePath = "送信ファイルパス"

    Dim cmdLine : cmdLine = batPath & " " & _
                            accountServicePath & " " & _
                            projectId & " " & _
                            clientEmail & " " & _
                            filePath & " " & _
                            bucketName & g_GcsFolderName & _
                            " >>" & batLogPath

    Dim result : result = Shell.Run(cmdLine,0,true)
End Function

最後に

この方式でも動作に問題はありません。ただし、転送方式で記載した通り、どこかで再セットアップ作業が必要になります。その影響で「忘れていてトラブルを招いた」なんてことも懸念されますし、その辺りの管理の手間にも繋がります。外部APIはライブラリが提供されていることがほとんどなので、これを機に主流言語で構築し直すのが好ましいと感じました。

参考まとめ