Pub/Sub メッセージの作成とレスポンス

Cloud Pub/Sub は、信頼できる多対多の非同期メッセージングをアプリケーション間で行います。パブリッシャー アプリケーションはメッセージを「トピック」に送信し、その他のアプリケーションはそのトピックをサブスクライブしてメッセージを受信できます。

このドキュメントでは、Google Cloud クライアント ライブラリを使用して、フレキシブル環境で動作中のアプリで Cloud Pub/Sub メッセージを送受信する方法を説明します。

前提条件

  • App Engine の Java 用「Hello, World!」の説明に従って環境とプロジェクトを設定し、App Engine での Java アプリの構造について理解します。
  • このドキュメントで説明しているサンプルアプリを実行する際に必要となるため、プロジェクト ID をメモして保存しておきます。

サンプルアプリのクローン作成

サンプルアプリをローカルマシンにコピーし、pubsub ディレクトリに移動します。

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/pubsub

トピックとサブスクリプションの作成

トピックとサブスクリプションを作成します。Pub/Sub サーバーがリクエストを送信するエンドポイントも指定します。

gcloud pubsub topics create YOUR_TOPIC_NAME
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic YOUR_TOPIC_NAME \
    --push-endpoint \
    https://YOUR_PROJECT_ID.appspot.com/pubsub/push?token=YOUR_TOKEN \
    --ack-deadline 10

YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

環境変数の設定

app.yaml ファイルを編集して、トピックと検証トークンの環境変数を設定します。

env_variables:
  PUBSUB_TOPIC: <your-topic-name>
  # This token is used to verify that requests originate from your
  # application. It can be any sufficiently random string.
  PUBSUB_VERIFICATION_TOKEN: <your-verification-token>

コードレビュー

サンプルアプリでは、Google Cloud Client ライブラリを使用しています。

このサンプルアプリでは、app.yaml ファイルに設定された値を使用して環境変数を構成します。push リクエスト ハンドラは、これらの値を使用して、Pub/Sub からのリクエストで、信頼できる送信元から送信されていることを確認します。

String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");

このサンプルアプリでは、メッセージを格納する Cloud Datastore データベース インスタンスを保守します。PubSubPush サーブレットはプッシュされたメッセージを受け取り、それらを messageRepository データベース インスタンスに追加します。

@WebServlet(value = "/pubsub/push")
public class PubSubPush extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");
    // Do not process message if request token does not match pubsubVerificationToken
    if (req.getParameter("token").compareTo(pubsubVerificationToken) != 0) {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      return;
    }
    // parse message object from "message" field in the request body json
    // decode message data from base64
    Message message = getMessage(req);
    try {
      messageRepository.save(message);
      // 200, 201, 204, 102 status codes are interpreted as success by the Pub/Sub system
      resp.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
  }

PubSubPublish サーブレットは App Engine ウェブアプリと連携して新しいメッセージを公開し、受信したメッセージを表示します。

@WebServlet(name = "Publish with PubSub", value = "/pubsub/publish")
public class PubSubPublish extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    Publisher publisher = this.publisher;
    try {
      String topicId = System.getenv("PUBSUB_TOPIC");
      // create a publisher on the topic
      if (publisher == null) {
        publisher = Publisher.newBuilder(
            ProjectTopicName.of(ServiceOptions.getDefaultProjectId(), topicId))
            .build();
      }
      // construct a pubsub message from the payload
      final String payload = req.getParameter("payload");
      PubsubMessage pubsubMessage =
          PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8(payload)).build();

      publisher.publish(pubsubMessage);
      // redirect to home page
      resp.sendRedirect("/");
    } catch (Exception e) {
      resp.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
    }
  }

サンプルをローカルで実行する

ローカルで実行する場合、Google Cloud API を使用するための認証を行うには、Cloud SDK を利用します。前提条件に記載されているとおりに環境を設定していれば、この認証を行う gcloud init コマンドはすでに実行されています。

mvn clean package

次に、アプリケーションを起動する前に環境変数を設定します。

export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
mvn jetty:run

プッシュ通知のシミュレート

アプリケーションは、ローカルでメッセージを送信できますが、push メッセージを受信することはできません。push メッセージをシミュレートするには、ローカルのプッシュ通知エンドポイントに HTTP リクエストを送信します。このサンプルには、sample_message.json というファイルが含まれています。

curl または httpie を使用して、HTTP POST リクエストを送信できます。

curl -H "Content-Type: application/json" -i --data @sample_message.json "localhost:8080/pubsub/push?token=[your-token]"

または

http POST ":8080/pubsub/push?token=[your-token]" < sample_message.json

レスポンス:

HTTP/1.1 200 OK
Date: Wed, 26 Apr 2017 00:03:28 GMT
Content-Length: 0
Server: Jetty(9.3.8.v20160314)

リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

App Engine で実行する

gcloud コマンドライン ツールを使用してデモアプリを App Engine にデプロイするには、app.yaml ファイルがあるディレクトリから次のコマンドを実行します。

mvn appengine:deploy

これで、https://[YOUR_PROJECT_ID].appspot.com のアプリケーションにアクセスできるようになります。フォームを使用してメッセージを送信できますが、アプリケーションのどのインスタンスが通知を受信するかはわかりません。複数のメッセージを送信してページを更新すると、受信メッセージを確認できます。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Java の App Engine フレキシブル環境に関するドキュメント