Écrire des messages Pub/Sub et y répondre

ID de la région

Le REGION_ID est un code abrégé que Google attribue en fonction de la région que vous sélectionnez lors de la création de votre application. Le code ne correspond pas à un pays ou une province, même si certains ID de région peuvent ressembler aux codes de pays et de province couramment utilisés. Pour les applications créées après février 2020, REGION_ID.r est inclus dans les URL App Engine. Pour les applications existantes créées avant cette date, l'ID de région est facultatif dans l'URL.

En savoir plus sur les ID de région

Pub/Sub fournit une messagerie asynchrone fiable de type "plusieurs à plusieurs" entre applications. Les applications de type "éditeur" peuvent envoyer des messages à un sujet et d'autres applications peuvent s'abonner à ce sujet pour recevoir les messages.

Ce document explique comment utiliser la bibliothèque cliente Cloud pour envoyer et recevoir des messages Pub/Sub dans une application Java.

Prérequis

  • Suivez les instructions de la section "Hello, World! pour Java sur App Engine pour configurer votre environnement et votre projet. Ces instructions vous permettront également de comprendre la structure des applications Java dans App Engine.
  • Notez et enregistrez l'ID de votre projet. Vous en aurez besoin pour exécuter l'exemple d'application décrit dans ce document.

    Cloner l'exemple d'application

    Copiez les exemples d'applications sur votre ordinateur local, puis accédez au répertoire pubsub :

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

    Créer un sujet et un abonnement

    Créez un sujet et un abonnement, pour lesquels vous devez spécifier le point de terminaison auquel le serveur Pub/Sub doit envoyer des requêtes :

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

    Remplacez YOUR_TOKEN par un jeton secret aléatoire. Le point de terminaison push l'utilise pour valider les requêtes.

    Définir des variables d'environnement

    Modifiez le fichier app.yaml afin de définir les variables d'environnement pour le sujet et le jeton de validation :

    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>

    Révision de code

    L'exemple d'application utilise la bibliothèque cliente Cloud.

    L'exemple d'application utilise les valeurs que vous avez définies dans le fichier app.yaml pour configurer les variables d'environnement. Le gestionnaire de demandes push utilise ces valeurs pour confirmer que la requête provient de Pub/Sub et d'une source fiable :

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

    L'exemple d'application utilise une instance de base de données Cloud Datastore pour stocker les messages. Le servlet PubSubPush reçoit les messages envoyés et les ajoute à l'instance de base de données 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);
        }
      }

    Le servlet PubSubPublish interagit avec l'application Web App Engine pour publier de nouveaux messages et afficher les messages reçus :

    @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());
        }
      }

    Exécuter l'exemple en local

    Lorsque vous exécutez l'exemple en local, vous pouvez utiliser Google Cloud CLI pour fournir l'authentification permettant d'utiliser les API Google Cloud. Si vous avez configuré votre environnement conformément à la procédure décrite dans la section Prérequis, vous avez d'ores et déjà exécuté la commande gcloud init, qui permet de fournir ce type d'authentification.

    mvn clean package
    

    Définissez ensuite les variables d'environnement avant de démarrer votre application :

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

    Simuler des notifications push

    L'application peut envoyer des messages en local, mais ne peut pas recevoir de messages push en local. Vous pouvez toutefois simuler un message push en adressant une requête HTTP au point de terminaison de notification push local. L'exemple inclut le fichier sample_message.json.

    Vous pouvez utiliser curl ou un client httpie pour envoyer une requête HTTP POST :

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

    Ou

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

    Réponse :

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

    Une fois la requête terminée, vous pouvez actualiser localhost:8080 et afficher le message dans la liste des messages reçus.

    Exécuter sur App Engine

    Pour déployer l'application de démonstration sur App Engine en utilisant l'outil de ligne de commande gcloud, exécutez la commande suivante à partir du répertoire où se trouve votre fichier app.yaml :

    mvn package appengine:deploy -Dapp.deploy.projectId=PROJECT_ID

    Remplacez PROJECT_ID par l'ID de votre projet Cloud. Si votre ID de projet est déjà spécifié dans le fichier pom.xml, vous n'avez pas besoin d'inclure la propriété -Dapp.deploy.projectId dans la commande que vous exécutez.

    Vous pouvez désormais accéder à l'application à l'adresse https://PROJECT_ID.REGION_ID.r.appspot.com. Vous pouvez utiliser le formulaire pour envoyer de messages (mais vous ne pourrez pas forcément savoir quelle instance de votre application recevra la notification). Vous pouvez envoyer plusieurs messages et actualiser la page pour afficher le message reçu.