Messagerie avec l'intégration de Spring et Google Cloud Pub/Sub

1. Présentation

L'intégration de Spring vous fournit un mécanisme de messagerie permettant d'échanger Messages via MessageChannels. Il utilise des adaptateurs de canal pour communiquer avec les systèmes externes.

Dans cet exercice, nous allons créer deux applications qui communiquent à l'aide des adaptateurs de canaux d'intégration Spring fournis par Spring Cloud GCP. Grâce à ces adaptateurs, l'intégration de Spring utilise Google Cloud Pub/Sub comme backend d'échange de messages.

Vous découvrirez aussi comment utiliser Cloud Shell et la commande gcloud du SDK Cloud.

Ce tutoriel utilise l'exemple de code du guide de démarrage de Spring Boot.

Points abordés

  • Échanger des messages entre des applications avec Google Cloud Pub/Sub à l'aide de l'intégration de Spring et de Spring Cloud GCP

Prérequis

  • Un projet Google Cloud Platform
  • Un navigateur tel que Chrome ou Firefox
  • Bonne connaissance des éditeurs de texte Linux standards tels que Vim, EMACs ou Nano

Comment allez-vous utiliser ce tutoriel ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Comment évalueriez-vous votre expérience en matière de création d'applications Web HTML/CSS ?

Débutant Intermédiaire Expert

Quel est votre niveau d'expérience avec les services Google Cloud Platform ?

<ph type="x-smartling-placeholder"></ph> Débutant Intermédiaire Expert
.

2. Préparation

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Google Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères non utilisée par les API Google. Vous pourrez toujours le modifier.
  • L'ID du projet est unique parmi tous les projets Google Cloud et non modifiable une fois défini. La console Cloud génère automatiquement une chaîne unique (en général, vous n'y accordez d'importance particulière). Dans la plupart des ateliers de programmation, vous devrez indiquer l'ID de votre projet (généralement identifié par PROJECT_ID). Si l'ID généré ne vous convient pas, vous pouvez en générer un autre de manière aléatoire. Vous pouvez également en spécifier un et voir s'il est disponible. Après cette étape, l'ID n'est plus modifiable et restera donc le même pour toute la durée du projet.
  • Pour information, il existe une troisième valeur (le numéro de projet) que certaines API utilisent. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
  1. Vous devez ensuite activer la facturation dans la console Cloud pour utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire sans frais. Pour désactiver les ressources et éviter ainsi que des frais ne vous soient facturés après ce tutoriel, vous pouvez supprimer le projet ou les ressources que vous avez créées. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300 $.

Google Cloud Shell

Google Cloud peut être utilisé à distance depuis votre ordinateur portable. Toutefois, dans cet atelier de programmation, nous allons utiliser Google Cloud Shell, un environnement de ligne de commande exécuté dans le cloud.

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire vous explique de quoi il s'agit. Si un écran intermédiaire vous s'est présenté, cliquez sur Continue (Continuer).

9c92662c6a846a5c.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

9f0e51b578fecce5.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute dans Google Cloud, ce qui améliore considérablement les performances du réseau et l'authentification. Une grande partie, voire la totalité, de votre travail dans cet atelier de programmation peut être effectué dans un navigateur.

Une fois connecté à Cloud Shell, vous êtes authentifié et le projet est défini sur votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

3. Provisionner des ressources Pub/Sub

Accédez à la page des sujets Google Cloud Pub/Sub.

Cliquez sur Créer un sujet.

4c938409dc7169a6.png

Saisissez exampleTopic comme nom de sujet, puis cliquez sur Créer.

e2daeec91537f672.png

Une fois le sujet créé, restez sur la page "Sujets". Recherchez le sujet que vous venez de créer, appuyez sur les trois points verticaux au bout de la ligne, puis cliquez sur Nouvel abonnement.

975efa26e5054936.png

Saisissez exampleSubscription dans la zone de texte du nom de l'abonnement, puis cliquez sur Créer.

f7a91d9e1cb48009.png

4. Initialiser les applications Spring Boot

Une fois Cloud Shell lancé, vous pouvez utiliser la ligne de commande pour générer deux nouvelles applications Spring Boot avec Spring Initializr:

$ curl https://start.spring.io/starter.tgz \
  -d bootVersion=3.0.5 \
  -d dependencies=web,integration,cloud-gcp-pubsub \
  -d type=maven-project \
  -d baseDir=spring-integration-sender | tar -xzvf -

$ curl https://start.spring.io/starter.tgz \
  -d bootVersion=3.0.5 \
  -d dependencies=web,integration,cloud-gcp-pubsub \
  -d type=maven-project \
  -d baseDir=spring-integration-receiver | tar -xzvf -

5. Créer une application pour envoyer des messages

Créons maintenant notre application d'envoi de messages. Accédez au répertoire de l'application émettrice.

$ cd spring-integration-sender

Nous voulons que notre application écrive des messages sur un canal. Une fois qu'un message est dans le canal, il est récupéré par l'adaptateur du canal sortant, qui le convertit d'un message Spring générique en message Google Cloud Pub/Sub et le publie dans un sujet Google Cloud Pub/Sub.

Pour que notre application écrive sur un canal, nous pouvons utiliser une passerelle de messagerie Spring Integration. À l'aide d'un éditeur de texte de vim, emacs ou nano, déclarez une interface PubsubOutboundGateway dans la classe DemoApplication.

src/main/java/com/example/demo/DemoApplication.java

...
import org.springframework.integration.annotation.MessagingGateway;

@SpringBootApplication
public class DemoApplication {

  ...

  @MessagingGateway(defaultRequestChannel = "pubsubOutputChannel")
  public interface PubsubOutboundGateway {
    void sendToPubsub(String text);
  }
}

Nous disposons maintenant d'un mécanisme pour envoyer des messages à un canal, mais où sont-ils envoyés après leur arrivée dans le canal ?

Nous avons besoin d'un adaptateur de canal sortant pour consommer les nouveaux messages dans le canal et les publier dans un sujet Google Cloud Pub/Sub.

src/main/java/com/example/demo/DemoApplication.java

...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.outbound.PubSubMessageHandler;

import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.MessageHandler;

@SpringBootApplication
public class DemoApplication {

  ...

  @Bean
  @ServiceActivator(inputChannel = "pubsubOutputChannel")
  public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
    return new PubSubMessageHandler(pubsubTemplate, "exampleTopic");
  }
}

L'annotation @ServiceActivator entraîne l'application de ce MessageHandler à tous les nouveaux messages dans inputChannel. Dans ce cas, nous appelons notre adaptateur de canal sortant, PubSubMessageHandler, pour publier le message dans le sujet exampleTopic de Google Cloud Pub/Sub.

Une fois l'adaptateur de canal en place, nous pouvons désormais raccorder automatiquement un objet PubsubOutboundGateway et l'utiliser pour écrire un message sur un canal.

src/main/java/com/example/demo/DemoApplication.java

...
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;

@SpringBootApplication
public class DemoApplication {

  ...

  @Autowired
  private PubsubOutboundGateway messagingGateway;

  @PostMapping("/postMessage")
  public RedirectView postMessage(@RequestParam("message") String message) {
    this.messagingGateway.sendToPubsub(message);
    return new RedirectView("/");
  }
}

Grâce à l'annotation @PostMapping, nous disposons désormais d'un point de terminaison qui écoute les requêtes HTTP POST, mais pas sans ajouter une annotation @RestController à la classe DemoApplication pour la marquer comme contrôleur REST.

src/main/java/com/example/demo/DemoApplication.java

import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
  ...
}

Assurez-vous que JAVA_HOME est défini sur la bonne version.

export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Exécutez l'application émettrice.

# Set the Project ID in environmental variable
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`

$ ./mvnw spring-boot:run

L'application écoute les requêtes POST contenant un message sur le port 8080 et le point de terminaison /postMessage, mais nous y reviendrons plus tard.

6. Créer une application pour recevoir des messages

Nous venons de créer une application qui envoie des messages via Google Cloud Pub/Sub. Nous allons maintenant créer une autre application qui recevra ces messages et les traitera.

Cliquez sur + pour ouvrir une nouvelle session Cloud Shell.

9799bee5fea95aa6.png

Ensuite, dans la nouvelle session Cloud Shell, remplacez les répertoires par celui de l'application réceptrice:

$ cd spring-integration-receiver

Dans l'application précédente, la déclaration de passerelle de messagerie a créé le canal sortant pour nous. Étant donné que nous n'utilisons pas de passerelle de messagerie pour recevoir les messages, nous devons déclarer notre propre MessageChannel où arriveront les messages entrants.

src/main/java/com/example/demo/DemoApplication.java

...
import org.springframework.context.annotation.Bean;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;

@SpringBootApplication
public class DemoApplication {

  ...

  @Bean
  public MessageChannel pubsubInputChannel() {
    return new DirectChannel();
  }
}

Nous aurons besoin de l'adaptateur de canal entrant pour recevoir les messages de Google Cloud Pub/Sub et les transmettre à pubsubInputChannel.

src/main/java/com/example/demo/DemoApplication.java

...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter;

import org.springframework.beans.factory.annotation.Qualifier;

@SpringBootApplication
public class DemoApplication {

  ...

  @Bean
  public PubSubInboundChannelAdapter messageChannelAdapter(
      @Qualifier("pubsubInputChannel") MessageChannel inputChannel,
      PubSubTemplate pubSubTemplate) {
    PubSubInboundChannelAdapter adapter =
        new PubSubInboundChannelAdapter(pubSubTemplate, "exampleSubscription");
    adapter.setOutputChannel(inputChannel);

    return adapter;
  }
}

Cet adaptateur se lie au pubsubInputChannel et écoute les nouveaux messages de l'abonnement exampleSubscription de Google Cloud Pub/Sub.

Nous disposons d'un canal sur lequel les messages entrants sont publiés, mais que faire de ces messages ?

Nous allons les traiter avec un @ServiceActivator qui se déclenche lorsque de nouveaux messages arrivent sur pubsubInputChannel. Dans ce cas, nous allons simplement consigner la charge utile du message.

src/main/java/com/example/demo/DemoApplication.java

...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.annotation.ServiceActivator;

@SpringBootApplication
public class DemoApplication {

  ...

  private static final Log LOGGER = LogFactory.getLog(DemoApplication.class);

  @ServiceActivator(inputChannel = "pubsubInputChannel")
  public void messageReceiver(String payload) {
    LOGGER.info("Message arrived! Payload: " + payload);
  }
}

Assurez-vous que JAVA_HOME est défini sur la bonne version.

export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Exécutez l'application réceptrice.

$ ./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"

Désormais, tous les messages que vous envoyez à l'application de l'expéditeur sont enregistrés dans l'application réceptrice. Pour tester cela, ouvrez une nouvelle session Cloud Shell et envoyez une requête HTTP POST à l'application émettrice.

$ curl --data "message=Hello world!" localhost:8080/postMessage

Vérifiez ensuite que l'application du récepteur a enregistré le message que vous avez envoyé.

INFO: Message arrived! Payload: Hello world!

7. Nettoyage

Supprimez l'abonnement et le sujet créés dans cet exercice.

$ gcloud pubsub subscriptions delete exampleSubscription
$ gcloud pubsub topics delete exampleTopic

8. Résumé

Vous avez configuré deux applications Spring Boot qui utilisent les adaptateurs de canal d'intégration Spring pour Google Cloud Pub/Sub. Ils échangent des messages entre eux sans jamais interagir avec l'API Google Cloud Pub/Sub.

9. Félicitations !

Vous avez appris à utiliser les adaptateurs de canal d'intégration Spring pour Google Cloud Pub/Sub.

En savoir plus

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.