Procesando eventos de Google Pub/Sub con Quarkus + Apache Camel

¿Qué es Google Pub/Sub?

Google Cloud Pub/Sub es un servicio de mensajería para el intercambio de datos de eventos entre aplicaciones y servicios. Al desacoplar emisores y receptores, permite una comunicación segura y de alta disponibilidad entre aplicaciones escritas de forma independiente. Google Cloud Pub/Sub ofrece una mensajería de baja latencia/durabilidad, y es comúnmente utilizado por los desarrolladores en la implementación de flujos de trabajo asíncronos, la distribución de notificaciones de eventos, y la transmisión de datos de varios procesos o dispositivos.

¿Qué es Google Cloud Run?

Cloud Run es una plataforma administrada de Google que permite ejecutar contenedores stateless directamente sobre la infraestructura escalable de Google. y que pueden ser ejecutados a través de peticiones HTTP o Eventos. Cloud Run es serverless: en este se abstrae de toda la gestión de la infraestructura, para que se pueda centrar en la construcción de sus aplicaciones

Antes de comenzar.

Es necesario tener una cuenta de Google Cloud para usar Google Pub/Sub y Google Cloud Run, puedes comenzar usando el Trial de 30 días.

Hagamos un ejemplo

En este artículo, haremos un despliegue paso a paso usando una aplicación con Quarkus +Apache Camel la cual sera desplegada en Google Cloud Run y sera ejecutada usando eventos en Google Pub/Sub.

Cada una de los siguientes comandos serán ejecutados en Google Cloud Shell entorno que tiene las herramientas para operar Google Cloud directamente en tu navegador.

  • Configura tus variables de gcloud
gcloud config set project $GOOGLE_CLOUD_PROJECT
gcloud config set run/region us-central1
  • Habilita las APIs de Google Cloud para ejecutar este ejercicio.
gcloud services enable run.googleapis.com containerregistry.googleapis.com

Este comando habilita las APIs de Google Cloud Run y el Container Registry

  • Crear un tópico de Pub/Sub
gcloud pubsub topics create myTopic

Empaquetando y ejecutando la aplicación

  • Descarga el código fuente
git clone https://github.com/mikeintoch/gcp-quarkus-samples.git
cd gcp-quarkus-samples/run/pubsub
  • Para desplegar la aplicacion en Google Cloud Run es necesario crear una imagen de contenedor, vamos a permitir al cli de docker conectarse a nuestro Container Registry.
gcloud auth configure-docker
  • Utilice el Plugin Jib para Quarkus para construir y empujar el contenedor a Container Registry

Jib Plugin está integrado como una libreria de Quarkus y puede ser configurado para construir y subir imágenes a un registro sin la necesidad de un Dockerfile. Todas las dependencias se almacenan en caché en una capa diferente a la de la aplicación, haciendo que las reconstrucciones sean rápidas y pequeñas.

mvn clean package \
-Dquarkus.container-image.push=true \
-Dquarkus.container-image.registry=gcr.io \
-Dquarkus.container-image.group=$GOOGLE_CLOUD_PROJECT \
-Dquarkus.container-image.name=hello-quarkus \
-Dquarkus.container-image.tag=latest \
-Dquarkus.jib.base-jvm-image=gcr.io/distroless/java:latest

Esto produce como resultado una imagen de contenedor con el siguiente formato gcr.io/PROJECT_ID/hello-quarkus:latest puede verificar en su consola de Google Cloud

  • Ejecute el servicio en Google Cloud Run
gcloud run deploy camel-pubsub-service --image gcr.io/$GOOGLE_CLOUD_PROJECT/hello-quarkus:latest --no-allow-unauthenticated

La bandera --no-allow-unauthenticated restringe el acceso no autenticado al servicio.

  • Puedes verificar que el servicio este desplegado en la consola de Google Cloud

Integración con Google Pub/Sub

  • Crear un cuenta de servicio para representar la suscripción al servicio de Pub/Sub
gcloud iam service-accounts create cloud-run-pubsub-invoker \
    --display-name "Cloud Run Pub/Sub Invoker"
  • Dar permiso a la cuenta del servicio para invocar su servicio de camel
gcloud run services add-iam-policy-binding camel-pubsub-service \
   --member=serviceAccount:cloud-run-pubsub-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
   --role=roles/run.invoker
  • Permitir a Pub/Sub crear tokens de autenticación en el proyecto, esto permitirá que pueda invocar el servicio en Cloud Run, es necesario primero obtener el numero del proyecto de Google Cloud
gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_NUMBER)"

Copie el valor de salida y reemplace el valor PROJECT_NUMBER en el siguiente comando

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
     --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
     --role=roles/iam.serviceAccountTokenCreator
  • Crear una suscripción al tópico de pub/sub hacia el servicio de Cloud Run

Obtener la url del servicio de Cloud run

gcloud run services describe camel-pubsub-service --platform managed --format 'value(status.url)'

Copie el valor de salida y reemplace el valor SERVICE_URL en el siguiente comando

gcloud pubsub subscriptions create myTopicSubscription --topic myTopic \
 --ack-deadline=600 \ 
 --push-endpoint=SERVICE_URL/ \ 
 --push-auth-service-account=cloud-run-pubsub-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com

Ahora Probemos.

Se ha creado las siguientes rutas de Apache Camel llamada Routes.java

package dev.mikeintoch;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.dataformat.JsonLibrary;
import org.apache.camel.model.rest.RestBindingMode;

public class Routes extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        restConfiguration().bindingMode(RestBindingMode.json);

        rest("/")
         .post()
         .to("direct:processMessage");

         onException(Exception.class)
         .handled(true)
         .log("Internal Server Error")
         .setBody(simple("Internal Server Error"));


        from("direct:processMessage")
         .marshal().json(JsonLibrary.Jackson)
        .choice()
          .when().jsonpath("$.message.data",true)
            .to("direct:printMessage")
          .otherwise() 
            .to("direct:printEmptyMessage");

        from("direct:printMessage")
         .transform().jsonpath("$.message.data")
         .unmarshal().base64()
         .log("Hello ${body}!")
         .setBody(simple("Information Received"));

         from("direct:printEmptyMessage")
          .log("Hello World!")
          .setBody(simple("Information Received was empty"));


    }
    
}

Es un servicio REST que consumirá el mensaje de Pub/Sub en formato JSON, dentro del mensaje podemos encontrar la información en el dato message.data en base64 y es necesario decodificar para usarla en nuestra ruta.

  • Enviemos un mensaje a Pub/Sub
gcloud pubsub topics publish myTopic --message "Human"
  • Verifique el funcionamiento en la consola de Google Cloud en los logs del servicio camel-pubsub-service

Los logs pueden tardar unos momentos en aparecer. Si no los ve inmediatamente, vuelva a comprobarlo después de unos momentos.

Conclusión

Con la ayuda de los servicios administrados de Google Cloud como lo es Google Cloud Run y Pub/Sub puede crear aplicaciones orientadas a Eventos sin la necesidad de preocuparse con administrar la infraestructura, si ya tienes contenedores esta es una gran opción para minimizar el consumo de tus cargas de trabajo

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *