Skip to content

Desplegando ms-emails: El Centro de Notificaciones del Ecosistema

Con nuestros servicios base ya desplegados, es hora de añadir una de las funcionalidades más críticas de cualquier aplicación: la comunicación por correo electrónico. Para esta tarea, desplegaremos ms-emails, un microservicio altamente especializado que actúa como el centro de notificaciones centralizado de todo nuestro ecosistema.

ms-emails es un ejemplo perfecto de un microservicio complejo, ya que expone tres puntos de entrada diferentes (REST, gRPC y un Worker asíncrono) para manejar diversos escenarios de comunicación.

Un Vistazo a la Arquitectura y Casos de Uso de ms-emails

Section titled “Un Vistazo a la Arquitectura y Casos de Uso de ms-emails”

Este diagrama muestra la rica funcionalidad de ms-emails y cómo interactúa con el resto del sistema.

Diagrama de Flujo de ms-emails
  • REST: Expone endpoints para la gestión de Plantillas (Template) y Plantillas por Defecto (DefaultTemplate).
  • gRPC: Proporciona un método de alto rendimiento para que otros microservicios envíen correos de forma síncrona.
  • Async Worker: Escucha eventos de dominio en RabbitMQ (como UserCreated) y dispara acciones, como enviar un correo de bienvenida.

El dominio de ms-emails está compuesto por varios Agregados clave.

Diagrama de Agregados de Dominio de ms-emails
  • EmailsAggregate: Representa un correo electrónico individual.
  • TemplateAggregate: Modela una plantilla de correo personalizable.
  • DefaultTemplateAggregate: Modela las plantillas de correo que son parte del sistema (ej. bienvenida, reseteo de contraseña).

Parte 1: Configuración del Proveedor de Correo

Section titled “Parte 1: Configuración del Proveedor de Correo”

El microservicio ms-emails está diseñado para ser flexible y soportar múltiples proveedores de envío de correo. Antes de desplegarlo, debemos configurar al menos un proveedor.

Para nuestro entorno, usaremos Microsoft Graph como proveedor. Esto nos permite enviar correos a través de la infraestructura de Microsoft 365. Para que ms-emails pueda autenticarse y enviar correos, necesita su propia identidad en Microsoft Entra ID. A continuación, crearemos un “App Registration” con los permisos necesarios.

  1. Navegar a App Registrations En el Microsoft Entra admin center, ve a Identity > Applications > App registrations y haz clic en + New registration.

    Navegando a App Registrations Creando un nuevo registro de aplicación
  2. Registrar la Aplicación InventorySendMail Dale un nombre descriptivo a la aplicación, como InventorySendMail, y haz clic en “Register”. No necesitamos una Redirect URI ya que esta aplicación no tendrá un inicio de sesión interactivo.

    Formulario de registro para la aplicación de envío de correos

    Una vez creada, anota el Application (client) ID y el Directory (tenant) ID. Los necesitaremos para nuestros secretos.

    Panel de control de la nueva aplicación InventorySendMail
  3. Añadir Permisos de API Ahora, debemos darle permiso a esta aplicación para enviar correos. Ve a la sección API permissions y haz clic en + Add a permission. Selecciona Microsoft Graph.

    Añadiendo permisos de Microsoft Graph

    Elegimos Application permissions, ya que nuestro microservicio enviará correos en segundo plano, sin un usuario conectado. Buscamos y seleccionamos el permiso Mail.Send, y hacemos clic en “Add permissions”.

    Seleccionando el permiso de aplicación Mail.Send
  4. Otorgar Consentimiento de Administrador El permiso Mail.Send requiere consentimiento del administrador. En el panel de API permissions, haz clic en el botón Grant admin consent for ... y confirma la acción.

    Permiso Mail.Send añadido pero pendiente de consentimiento Otorgando consentimiento de administrador

    El estado de los permisos cambiará a “Granted”. ¡Nuestra aplicación ahora tiene permiso para enviar correos!

    Permisos concedidos exitosamente
  5. Crear un Secreto de Cliente Para autenticarse, la aplicación necesita un secreto. Ve a Certificates & secrets, haz clic en + New client secret, dale una descripción y una duración.

    Creando un nuevo secreto de cliente Copiando el valor del secreto de cliente
  6. Obtener el ID del Usuario Remitente Cuando se usan permisos de aplicación, Microsoft Graph necesita saber “desde qué buzón” se enviarán los correos. Necesitamos el Object ID de un usuario con licencia que actuará como remitente.

    • Ve a la sección Users en Entra ID.
    • Selecciona el usuario que actuará como remitente.
    • Copia su Object ID. Este será nuestro secreto UserIdWithLicense.
    Obteniendo el Object ID de un usuario

Parte 2: Almacenando los Secretos en Vault

Section titled “Parte 2: Almacenando los Secretos en Vault”

Con todas las credenciales de Microsoft Graph recolectadas, ahora las almacenaremos de forma segura en Vault, junto con los secretos de los otros servicios.

Comando para guardar los secretos de `ms-emails` en Vault

El comando vault kv put para ms-emails incluirá:

  • Credenciales de RabbitMQ, Redis y Mongo.
  • Email:TenantId: El Directory (tenant) ID de nuestro tenant de Entra ID.
  • Email:ClientId: El Application (client) ID de nuestra app InventorySendMail.
  • Email:ClientSecret: El valor del secreto que generamos y copiamos.
  • Email:UserIdWithLicense: El Object ID del usuario que actuará como remitente.
  • Vault:Transit:SecretContexts: Configuración para el motor de cifrado de Vault.

Con la configuración del proveedor de correo lista en Entra ID y los secretos recolectados, es hora de desplegar los tres entrypoints de ms-emails.

  1. Actualizar los Secretos en Vault

    Además de las credenciales de los servicios base, ms-emails utiliza el Motor de Tránsito de Vault para operaciones de cifrado. Debemos añadir la contraseña para este contexto de cifrado a nuestros secretos.

    Terminal window
    vault kv put -mount=inventory-keyvalue ms-emails `
    "RabbitMQ:UserName=<USERNAME_FROM_RABBITMQ_SECRET>" `
    "RabbitMQ:Password=<PASSWORD_FROM_RABBITMQ_SECRET>" `
    "Redis:Instances:Core:ConnectionString=<CONNECTION_STRING_FROM_REDIS>" `
    "Mongo:ConnectionString=<CONNECTION_STRING_FROM_MONGO_ATLAS>"
    "Email:TenantId=<TENANT_ID>" `
    "Email:ClientId=<CLIENT_ID>" `
    "Email:ClientSecret=<CLIENT_SECRET>" `
    "Email:UserIdWithLicense=<USER_ID_WITH_LICENSE>" `
    "Vault:Transit:SecretContexts:vault_transit_password_temp=<VAULT_TRANSIT_PASSWORD>"
    Comando para guardar los secretos de ms-emails en Vault

    Podemos verificar que los secretos se han guardado correctamente en la interfaz web de Vault.

    Verificando los secretos de ms-emails en la UI de Vault
  2. Preparar los Archivos values.yaml

    Cada entrypoint tiene su propio archivo de configuración, que define sus variables de entorno y, en el caso de REST, su exposición a través de Istio.

    ms-base:
    env:
    - name: RESOURCES__ENABLE
    value: "false"
    - name: SECURITY__VALIDISSUER
    value: "https://devcodedesignplus.ciamlogin.com/dfee7752-2c8a-4171-ad95-62ddc82d6ed8/v2.0/"
    - name: SECURITY__CLIENTID
    value: "305f759d-d1d2-467b-9eab-4a61389c7329"
    - name: SECURITY__VALIDAUDIENCES__0
    value: "305f759d-d1d2-467b-9eab-4a61389c7329"
    - name: RABBITMQ__HOST
    value: "rabbitmq-cluster.srv-rabbitmq.svc"
    - name: LOGGER__OTELENDPOINT
    value: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"
    - name: OBSERVABILITY__SERVEROTEL
    value: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"
    vault:
    server: http://vault.vault.svc.cluster.local:8200
    solution: inventory
    token: ANGq0*B2acD1n5%F
    virtualService:
    create: true
    namespace: istio-ingress
    hosts:
    - services.codedesignplus.app
    gateways:
    - istio-ingress/istio-inventory-gateway
    http:
    - name: ms-emails
    match:
    - uri:
    prefix: /ms-emails/
    rewrite:
    uri: /
    route:
    - destination:
    host: ms-emails-rest.inventory.svc.cluster.local
    port:
    number: 5000
  3. Desplegar los Entrypoints con Helm Ejecutamos los comandos de despliegue para cada uno de los entrypoints en el namespace inventory.

    • Desplegando el Entrypoint REST:
    Terminal window
    helm upgrade --install ms-emails-rest codedesignplus/ms-emails-rest -f ./values-rest.yaml --namespace inventory
    Instalando el Helm chart de ms-emails-rest
    • Desplegando el Entrypoint gRPC:
    Terminal window
    helm upgrade --install ms-emails-grpc codedesignplus/ms-emails-grpc -f ./values-grpc.yaml --namespace inventory
    Instalando el Helm chart de ms-emails-grpc
    • Desplegando el Entrypoint Async Worker:
    Terminal window
    helm upgrade --install ms-emails-worker codedesignplus/ms-emails-worker -f ./values-worker.yaml --namespace inventory
    Instalando el Helm chart de ms-emails-worker
  4. Verificar el Despliegue en Lens

    • Verificar los Pods: En Lens, si filtramos por el namespace inventory, ahora deberíamos ver los tres nuevos pods para ms-emails-rest, ms-emails-grpc y ms-emails-worker, todos corriendo. /* Placeholder para la imagen de los pods de ms-emails en Lens. */

    • Verificar el VirtualService: El Helm chart de ms-emails-rest ha creado automáticamente el VirtualService que enruta el tráfico desde nuestro Gateway. /* Placeholder para la imagen del VirtualService de ms-emails en Lens. */

  5. Prueba End-to-End

    Verificando el endpoint de salud de ms-emails Accediendo a Swagger UI de ms-emails

Has desplegado ms-emails, uno de los microservicios más complejos y funcionales de nuestro ecosistema. Este ejercicio demuestra cómo nuestra arquitectura y el uso de Helm Charts modulares nos permiten gestionar servicios con múltiples responsabilidades y puntos de entrada de una manera limpia y organizada. Con ms-emails en su lugar, nuestra plataforma ahora puede comunicarse proactivamente con los usuarios, reaccionar a eventos de negocio y gestionar complejas plantillas de correo, todo a través de un servicio centralizado y robusto.