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”Flujo y Puntos de Entrada
Section titled “Flujo y Puntos de Entrada”Este diagrama muestra la rica funcionalidad de ms-emails
y cómo interactúa con el resto del sistema.
- 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 Modelo de Dominio
Section titled “El Modelo de Dominio”El dominio de ms-emails
está compuesto por varios Agregados clave.
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).
Casos de Uso Principales
Section titled “Casos de Uso Principales”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.
-
Navegar a App Registrations En el Microsoft Entra admin center, ve a
Identity > Applications > App registrations
y haz clic en+ New registration
. -
Registrar la Aplicación
InventorySendMail
Dale un nombre descriptivo a la aplicación, comoInventorySendMail
, y haz clic en “Register”. No necesitamos una Redirect URI ya que esta aplicación no tendrá un inicio de sesión interactivo.Una vez creada, anota el
Application (client) ID
y elDirectory (tenant) ID
. Los necesitaremos para nuestros secretos. -
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
. SeleccionaMicrosoft Graph
.Elegimos
Application permissions
, ya que nuestro microservicio enviará correos en segundo plano, sin un usuario conectado. Buscamos y seleccionamos el permisoMail.Send
, y hacemos clic en “Add permissions”. -
Otorgar Consentimiento de Administrador El permiso
Mail.Send
requiere consentimiento del administrador. En el panel deAPI permissions
, haz clic en el botónGrant admin consent for ...
y confirma la acción.El estado de los permisos cambiará a “Granted”. ¡Nuestra aplicación ahora tiene permiso para enviar correos!
-
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. -
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 secretoUserIdWithLicense
.
- Ve a la sección
La configuración para un proveedor SMTP genérico se detallará en un futuro artículo. Implicará almacenar el host, puerto, usuario y contraseña de SMTP en Vault.
La configuración para SendGrid se detallará en un futuro artículo. Implicará generar una clave de API en SendGrid y almacenarla de forma segura en Vault.
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.

El comando vault kv put
para ms-emails
incluirá:
- Credenciales de
RabbitMQ
,Redis
yMongo
. Email:TenantId
: ElDirectory (tenant) ID
de nuestro tenant de Entra ID.Email:ClientId
: ElApplication (client) ID
de nuestra appInventorySendMail
.Email:ClientSecret
: El valor del secreto que generamos y copiamos.Email:UserIdWithLicense
: ElObject ID
del usuario que actuará como remitente.Vault:Transit:SecretContexts
: Configuración para el motor de cifrado de Vault.
Parte 3: Despliegue y Verificación
Section titled “Parte 3: Despliegue y Verificación”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
.
-
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>"Podemos verificar que los secretos se han guardado correctamente en la interfaz web de Vault.
-
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__ENABLEvalue: "false"- name: SECURITY__VALIDISSUERvalue: "https://devcodedesignplus.ciamlogin.com/dfee7752-2c8a-4171-ad95-62ddc82d6ed8/v2.0/"- name: SECURITY__CLIENTIDvalue: "305f759d-d1d2-467b-9eab-4a61389c7329"- name: SECURITY__VALIDAUDIENCES__0value: "305f759d-d1d2-467b-9eab-4a61389c7329"- name: RABBITMQ__HOSTvalue: "rabbitmq-cluster.srv-rabbitmq.svc"- name: LOGGER__OTELENDPOINTvalue: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"- name: OBSERVABILITY__SERVEROTELvalue: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"vault:server: http://vault.vault.svc.cluster.local:8200solution: inventorytoken: ANGq0*B2acD1n5%FvirtualService:create: truenamespace: istio-ingresshosts:- services.codedesignplus.appgateways:- istio-ingress/istio-inventory-gatewayhttp:- name: ms-emailsmatch:- uri:prefix: /ms-emails/rewrite:uri: /route:- destination:host: ms-emails-rest.inventory.svc.cluster.localport:number: 5000ms-base:env:- name: RESOURCES__ENABLEvalue: "false"- name: SECURITY__VALIDISSUERvalue: "https://devcodedesignplus.ciamlogin.com/dfee7752-2c8a-4171-ad95-62ddc82d6ed8/v2.0/"- name: SECURITY__CLIENTIDvalue: "305f759d-d1d2-467b-9eab-4a61389c7329"- name: SECURITY__VALIDAUDIENCES__0value: "305f759d-d1d2-467b-9eab-4a61389c7329"- name: RABBITMQ__HOSTvalue: "rabbitmq-cluster.srv-rabbitmq.svc"- name: LOGGER__OTELENDPOINTvalue: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"- name: OBSERVABILITY__SERVEROTELvalue: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"vault:server: http://vault.vault.svc.cluster.local:8200solution: inventorytoken: ANGq0*B2acD1n5%Fms-base:env:- name: RESOURCES__ENABLEvalue: "false"- name: SECURITY__VALIDISSUERvalue: "https://devcodedesignplus.ciamlogin.com/dfee7752-2c8a-4171-ad95-62ddc82d6ed8/v2.0/"- name: SECURITY__CLIENTIDvalue: "305f759d-d1d2-467b-9eab-4a61389c7329"- name: SECURITY__VALIDAUDIENCES__0value: "305f759d-d1d2-467b-9eab-4a61389c7329"- name: RABBITMQ__HOSTvalue: "rabbitmq-cluster.srv-rabbitmq.svc"- name: LOGGER__OTELENDPOINTvalue: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"- name: OBSERVABILITY__SERVEROTELvalue: "http://inventory-opentelemetry-collector.otel-inventory.svc.cluster.local:4317"vault:server: http://vault.vault.svc.cluster.local:8200solution: inventorytoken: ANGq0*B2acD1n5%F -
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- Desplegando el Entrypoint gRPC:
Terminal window helm upgrade --install ms-emails-grpc codedesignplus/ms-emails-grpc -f ./values-grpc.yaml --namespace inventory- Desplegando el Entrypoint Async Worker:
Terminal window helm upgrade --install ms-emails-worker codedesignplus/ms-emails-worker -f ./values-worker.yaml --namespace inventory -
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
yms-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. */
-
-
Prueba End-to-End
- Endpoint de Salud: La forma más rápida de verificar que el servicio REST está vivo es acceder a su endpoint de salud. Abre un navegador y ve a: https://services.codedesignplus.app/ms-emails/health/ready
- Swagger UI: Para explorar la API de forma interactiva, podemos usar la interfaz de Swagger UI, que viene integrada. Navega a: https://services.codedesignplus.app/ms-emails/index.html
Conclusión
Section titled “Conclusión”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.