Java で Google API との接続を確立する方法

1. 始める前に

前提条件

  • 実装プロセスのステップ 1 と 2 が完了しました。
  • 提供された Java サーバーを TLS 終端付きでホストするには、Google App Engine または Google で構成されたドメインで独自のソリューションを使用します。
  • Java を環境にインストールされている。

学習内容

  • Google echo API に有効なリクエストを送信して接続を検証する方法。
  • Google からパートナー ホスト型 echo API へのリクエストを受信、復号、解析する方法。

2. 設定と要件

アプリケーションをダウンロードする

Java サンプルコードをダウンロードします。

アプリケーション構造の概要

Java サンプルコードは Google の Standard Payments API と統合されています。サンプルコードのプロジェクト構造には、outbound ディレクトリと inbound ディレクトリが含まれており、Google からパートナーへのインバウンド エコー リクエストと、パートナーの実装から Google へのアウトバウンド リクエストを反映します。

どちらのディレクトリにも、レイヤごとのパッケージ化において同様の階層が含まれています。主なレイヤは、controllerservicedomain の 3 つです。

  • controller パッケージには API が含まれています。
  • service パッケージは、ビジネス ロジック、base64url エンコード、暗号化を担当します。
  • domain パッケージには POJO が含まれています。

依存関係のインストール

プロジェクト ディレクトリに移動し、次のコマンドを実行して Maven ラッパーを使用して必要な依存関係をインストールします。App Engine を使用している場合は、この手順を省略できます。

./mvnw install

3. 決済インテグレーター アカウント ID(PIAID)を構成する

決済インテグレーター アカウント ID(PIAIDは、統合を一意に識別するために使用される識別子です。このチュートリアルを開始する前に、前提条件を満たしていれば、Google から PIAID を受け取っているはずです。

  1. プロジェクト ディレクトリの src/main/resources/application.properties に移動します。
  2. プロパティ payment.integrator.account.id を、Google から発行された PIAID に設定します。
payment.integrator.account.id={YOUR_PAYMENT_INTEGRATOR_ACCOUNT_ID}

4. Google がホストするエコー URL を設定する

Google がホストする echo の URL は、統合する API によって異なります。該当する統合タイプの API リファレンス ドキュメントにアクセスし、診断エコー API の URL をコピーします。URL をコピーしたら、次の手順に進んで Java プロジェクトで URL を更新します。

  1. プロジェクト ディレクトリの src/main/resources/application.properties に移動します。
  2. プロパティ API_SERVICE_NAME は、デベロッパー向けドキュメントの内容と一致するように設定します。
google.hosted.echo.url=vgw.googleapis.com/gsp/{API_SERVICE_NAME}/echo/

5. PGP 鍵を追加する

以下に示すように、PGP 鍵を追加して PGP 暗号化を有効にします。

  • src/resources/publicKey1.gpg に移動し、ASCII Armor のある公開鍵をファイルに追加します。
  • src/resources/privateKey1.gpg に移動し、ASCII Armor の秘密鍵をファイルに追加します。
  • src/resources/passphrase1.txt に移動し、ファイルにシークレット パスフレーズを追加します。

PGP 鍵の追加

デュアルキー暗号化を有効にするには、2 つ目の公開鍵を publicKey2.gpg に追加し、2 つ目の秘密鍵を privateKey2.gpg に追加し、2 つ目のパスフレーズを passphrase.txt に追加します。2 番目のキーを追加した後、KeyConfig.addPrivateKeyAndPassphrase(...)KeyConfig.addPublicKeys(...) の 2 番目のキーペアを読み込む役割を担う、コメントアウトされた行のコメント化を解除します。

これで、アプリケーションを実行する準備が整いました。

6. アプリケーションを実行する

次のコマンドを実行して、アプリを起動します。

  $ ./mvnw spring-boot:run

事前構成済みの App Engine インスタンスを実行している場合は、代わりにこのコマンドを実行します。

$ gcloud app deploy

デフォルトでは、サーバーはポート 8080 をリッスンします。Open API Swagger UI を表示するには、以下の URL に移動します。

https://{APPLICATION_HOST}/swagger-ui.html

7. Google Standard Payments Outbound API 接続をテストする

アプリケーションを実行できるようになったので、次に Google echo API との接続をテストします。

Swagger UI または CLI を使用して次のコマンドを実行し、サンプル アプリケーションのインスタンスから Google のサーバーへの呼び出しを開始できます。サンプル アプリケーションの echo API は、平文の POST リクエストを受け入れます。リクエストを受信すると、後続のリクエストは Google がホストする API に送信されます。

コマンドラインでリクエストを送信する

コマンドを実行する前に、HOSTNAME をサーバーホストの名前に置き換えます。

  $ curl -X POST -H 'Content-Type: text/plain' -d 'Hello from Partner Bank!' https://{HOSTNAME}/echo

Swagger UI でリクエストを送信する

Swagger UI を使用してリクエストを送信するには、https://{APPLICATION_HOST}/swagger-ui に移動し、リクエスト本文にクライアント メッセージを設定します。Google にリクエストを送信する準備ができたら、[Execute] ボタンをクリックします。

Swagger を使用して GSP Echo リクエストを送信する

レスポンスを受け取る

API リクエストが成功すると、Google から次のようなレスポンスが返されます。

{
   "responseHeader":{
      "responseTimestamp":"1606710026723"
   },
   "clientMessage":"Hello from  Bank Little Bear!",
   "serverMessage":"Server message."
}

詳細なルート

サーバーによってリクエストが正常に送信されたので、その仕組みを確認しましょう。

リクエストを作成する

OutboundEchoServicecreateEchoRequestWithMessage は、Google の API に送信される echo リクエストを作成します。

String jsonEchoRequestMessage = objectMapper.writeValueAsString(createEchoRequestWithMessage(message));

生成されるリクエストには、clientMessage と複数のデフォルト値フィールドが含まれます。

{
   "requestHeader":{
      "protocolVersion":{
         "major":1,
         "minor":0,
         "revision":0
      },
      "requestId":"ddfe0fd0-ffdc-4fcf-991a-f0611ec83970",
      "requestTimestamp":"1606715389040"
   },
   "clientMessage":"Hello from Bank Little Bear!"
}

Base64url でのリクエストのエンコードと暗号化

すべてのリクエストは暗号化され、base64url でエンコードされます。このサンプルでは、PgpEncryptor.java には、暗号化と復号に加えて、base64url エンコードを行うヘルパー メソッドが含まれています。以下のメソッドでは、リクエストをエンコードし、Google の公開鍵を使用して暗号化を行います。

String encryptedMessage = pgpEncryptor.encrypt(jsonEchoRequestMessage);

POST リクエストを送信する

暗号化されたメッセージは POST リクエストを介して送信されます。

postStandardPaymentsEchoApi(encryptedMessage)

レスポンスを復号して base64url でデコードしてレスポンスを返す

Google からのレスポンスが base64url でエンコードされ、暗号化されているとします。したがって、これをデコードして復号しないと平文で返す必要があります。decrypt メソッドの base64url がレスポンスをデコードして復号します。

String decryptedData =
     pgpEncryptor.decrypt(postStandardPaymentsEchoApi(encryptedMessage).getBody());

レスポンスを返す

202 HTTP レスポンス ステータス コードとともにレスポンスが返されます。

return new ResponseEntity<>(decryptedData, HttpStatus.ACCEPTED);

8. インバウンド API 接続をテストする

受信エコー API 接続をテストするために、Google は Partner Hosted echo API にリクエストを送信します。準備が整ったら、Google の担当者と連携して、Google からのこのリクエストをトリガーしてください。

Google からの受信エコー リクエストを読み取り、有効なエコー レスポンスを返すことができれば、エコーテストは完了です。

詳細なルート

サーバーがリクエストを正常に受信して処理したので、次はその仕組みを確認しましょう。

Base64url でリクエストをデコードして復号する

リクエストを受信すると、PgpEncryptor.javadecrypt を呼び出して、リクエストを base64url でデコードして復号します。

String decryptedRequest = pgpEncryptor.decrypt(echoRequest);

リクエストを受け取る

デコードと復号が完了すると、Google が次のようなメッセージ ペイロードを送信しました。

{
  "requestHeader": {
    "protocolVersion": {
      "major": 1
    },
    "requestId": "G1MQ0YERJ0Q7LPM",
    "requestTimestamp": {
      "epochMillis":1481899949606
    },
    "paymentIntegratorAccountId": "abcdef123456"
  },
  "clientMessage": "echo Me"
}

レスポンスを作成する

インバウンド エコー リクエストが正常に読み取られたら、レスポンスを作成する準備は完了です。

private EchoResponse convertEchoRequestStringToEchoResponse(String decryptedRequest);

レスポンスには、Google からのメッセージに加えて、サーバーから送信されたタイムスタンプとメッセージが含まれます。

{
  "responseHeader": {
    "responseTimestamp": {
      "epochMillis":1481899950236
    }
  },
  "clientMessage": "echo Me",
  "serverMessage": "Debug ID 12345"
}

レスポンスを Base64url でエンコードして暗号化する

リクエストはすべて暗号化され、base64url がエンコードされるため、PgpEncryptor.javaencrypt を呼び出して、リクエストの base64url エンコードと暗号化を行います。

pgpEncryptor.encrypt(echoResponseString)

レスポンスを返す

202 HTTP レスポンス ステータス コードとともにレスポンスが返されます。

return new ResponseEntity<>(pgpEncryptor.encrypt(echoResponseString), HttpStatus.ACCEPTED);

9. お疲れさまでした

この Codelab では、Payments API との接続を正しく確立できました。