Aller au contenu
BackSpring BootJavaCloud

How-To: Émuler les services GCP

Découvrez comment émuler les services GCP dans une application Spring Boot pour garantir des tests fiables et proches de l'environnement de production. Pub/Sub, Firestore, Storage : apprenez à utiliser la Google Cloud CLI et une image Docker prête à l'emploi.

How-To Service GCP

Après avoir présenté comment émuler Kafka, je vous propose une suite de solutions pour émuler les services de la Google Cloud Platform 😃

Afin de garantir la compatibilité des APIs que nous utilisons pour communiquer avec ces services et augmenter la fiabilité de nos tests, il est important de mocker les services GCP en étant au plus proche de l'environnement de production.

Si votre application échange avec Pub/Sub, Firestore, Datastore, Bigtable ou encore Spanner, alors la Google Cloud CLI est là pour vous et Google fournit une image Docker prête à l'emploi. 🥳

📚 Firestore

Emuler Firestore est un jeu d'enfant ! La CLI Google Cloud embarque nativement plusieurs émulateurs vous permettant de rapidement tester vos API !

Exemple d'une configuration avec initialisation d'une collection :

services:
  firestore:
    image: gcr.io/google.com/cloudsdktool/google-cloud-cli:latest
    container_name: firestore
    ports:
      - "8085:8085"
    entrypoint: gcloud beta emulators firestore start --host-port="0.0.0.0:8085"
    healthcheck:
      test: curl --fail "http://localhost:8085/v1/projects/emulator/databases/(default)/documents/" || exit 1
      start_period: 0s
      interval: 5s
      timeout: 5s
      retries: 12  # 1 minute
   
  # Initialise la collection et un document Firestore
  init-firestore:
    image: alpine/curl
    container_name: init-firestore
    command:
      - /bin/sh
      - -c
      - |
        curl -X POST 'http://firestore:8085/v1/projects/emulator/databases/(default)/documents/filtrage?documentId=filtered-document' -H 'Content-Type: application/json' -d \
                        '{
                          "fields":{
                            "filtered": {
                              "arrayValue": {
                                "values": [
                                  {"stringValue": "toto"},
                                  {"stringValue": "tata"}
                                ]
                              }
                            }
                          }
                        }' && \
        sleep infinity
         
    depends_on:
      firestore:
        condition: service_healthy
    healthcheck:
      test: curl --fail "http://firestore:8085/v1/projects/emulator/databases/(default)/documents/" || exit 1
      start_period: 0s
      interval: 5s
      timeout: 5s
      retries: 12

compose.yaml

Quelques liens pour connaître les API Firestore

La configuration de l'application.yaml de l'application Spring Boot :

spring:
  cloud:
    gcp:
      firestore:
        emulator:
          enabled: true
        host-port: firestore:8085
        project-id: emulator

application.yaml

📬 PubSub

Dans la même logique, la CLI Google Cloud permet aussi d'émuler le service PubSub :

services:
  pubsub:
    image: gcr.io/google.com/cloudsdktool/google-cloud-cli:latest
    container_name: gcp-pubsub-emulator
    entrypoint: gcloud beta emulators pubsub start --project=emulator --host-port="0.0.0.0:38085"
    healthcheck:
      test: curl --output /dev/null --silent --head http://0.0.0.0:38085
      interval: 5s
      timeout: 5s
      retries: 100
    ports:
      - "38085:38085"
    environment:
      HOST_PORT: 38085
 
  # Initialise le topic pubsub et la subscription
  init-pubsub:
    image: alpine/curl
    container_name: init-pubsub
    command:
      - /bin/sh
      - -c
      - |
        curl -X PUT 'http://pubsub:38085/v1/projects/emulator/topics/input' -H 'Content-Type: application/json' && \
        curl -X PUT 'http://pubsub:38085/v1/projects/emulator/subscriptions/input-subscription' -H 'Content-Type: application/json' -d \
          '{
              "topic": "projects/emulator/topics/input"
           }' && \
        sleep infinity
 
    depends_on:
      pubsub:
        condition: service_healthy
    healthcheck:
      test: curl --fail "http://pubsub:38085/v1/projects/emulator/topics/input" || exit 1
      start_period: 0s
      interval: 5s
      timeout: 5s
      retries: 12

compose.yaml

Quelques liens utiles pour manipuler les API PubSub et les messages :

La configuration de l'application.yaml de l'application Spring Boot reste très proche de celle de Firestore :

spring:
  cloud:
    gcp:
      project-id: emulator
      pubsub:
        emulator-host: pubsub:38085

application.yaml

☁️ Storage

Malheureusement, mis à part une dépendance Java pour émuler un Storage GCP in memory, Google ne propose pas d'autre solution et il n'existe pas d'émulateur de Storage dans la GCloud CLI.

Cependant, une image docker existe pour émuler un Storage GCP et cette dernière est mise à jour à chaque évolution de l'API Google: https://github.com/fsouza/fake-gcs-server


services:
  avatar-bucket:
    image: fsouza/fake-gcs-server
    container_name: avatar-bucket
    command: ["-scheme", "both", "-data", "/data"]
    volumes:
      - ./storage:/storage # Le dossier contenu dans le répertoire storage sur l'environnement local sera le nom et le contenu du bucket
    ports:
      - "4443:4443"
      - "8000:8000"
    healthcheck:
      test: echo OK || exit 1
      start_period: 3s
      interval: 5s
      timeout: 10s
      retries: 3

compose.yaml

Avec cette image, il est possible de déclencher un évènement PubSub sur notre émulateur PubSub lorsqu'une écriture est effectuée sur notre storage 😍

storage:
    image: fsouza/fake-gcs-server:latest
    command: [ "-scheme", "http", "-event.pubsub-project-id", "emulator", "-event.pubsub-topic", "input", "-event.bucket", "input" ]
    volumes:
      - ./storage:/data # Le dossier contenu dans le répertoire storage sur l'environnement local sera le nom et le contenu du bucket
    ports:
      - "4443:4443"
    environment:
      - PUBSUB_EMULATOR_HOST=pubsub:38085
    depends_on:
      - pubsub
    healthcheck:
      test: echo OK || exit 1
      start_period: 3s
      interval: 5s
      timeout: 10s
      retries: 3

compose.yaml

Quelques liens utiles pour manipuler Cloud Storage :

📝 Conclusion

Quel que soit le service que vous tentez d'émuler, une solution est disponible pour vous permettre de développer et de tester dans de bonnes conditions.

Comme à mon habitude pour ce type d'article, je l'accompagne d'un repo Github disponible ici : https://github.com/gfourny-sfeir/spring-gcp

Il est aussi tout à fait possible d'émuler ces différents services avec Testcontainers : https://java.testcontainers.org/modules/gcloud/

Dernier