Arhitectură
Acest conținut nu este încă disponibil în limba selectată.
JHipster 8.11 monolit: Spring Boot 3 + Angular 19 (standalone), PostgreSQL (prod) / H2 (dev), JWT (HS512) + Keycloak OIDC opțional, Liquibase, MapStruct, Ehcache, RabbitMQ (Spring AMQP, cablat manual). Package md.gov.gnotify, port 8090. i18n RO (nativ) + EN. Fără Elasticsearch.
Layering
Section titled “Layering”flowchart TD subgraph Clienti EXT[Sistem extern] -->|mTLS PFX| V1[/api/v1/**] UI[Admin SPA / Portal] -->|JWT / OIDC| ADM[/api/**] end V1 --> DISP[NotificationDispatchService] ADM --> DISP DISP --> DB[(PostgreSQL:<br/>Notificare + Livrare + Eveniment)] DISP -->|publish notify.{canal}.{tier}| MQ[[RabbitMQ]] MQ --> W[Workeri @RabbitListener] W --> CH[ChannelSender:<br/>EMAIL / SMS / PUSH / TELEGRAM] W --> DB W -.audit.-> GLOG[(GLog)] W -.forward.-> MN[(MNotify mTLS)]Două planuri de autentificare
Section titled “Două planuri de autentificare”flowchart LR subgraph "@Order(2) — mașină" A[Sistem extern] -->|X-SSL-Client-* de la nginx| PFX[PfxAuthenticationFilter] PFX -->|amprentă == certFingerprint| V1[/api/v1/**] end subgraph "@Order(1) — administrare" B[Operator/cetățean] --> JWT[JWT HS512] B --> OIDC[Keycloak OIDC realm gnotify] JWT --> ADM[/api/**, UI] OIDC --> ADM end- Plan mașină —
/api/v1/**: mTLS PFX (security/pfx/PfxAuthenticationFilter), lanț de securitate propriu@Order(2). Oglindește middleware-ul PHPPfxAuthenticate(headereX-SSL-Client-*puse de nginx la terminarea TLS). - Plan administrare — UI +
/api/**: JWT + Keycloak OIDC dual-auth (@Order(1), gated degnotify.oidc.enabled; realmgnotifypesso.gstack.esempla.systems).
Vezi Security-and-Auth pentru detalii.
Topologie RabbitMQ
Section titled “Topologie RabbitMQ”config/RabbitMqConfig + NotifyQueues: câte o coadă notify.{canal}.{tier} + .dlq pentru fiecare combinație — 6 cozi + 6 DLQ (email/push/telegram × priority/important; SMS adăugat ulterior).
- DLX prin
x-dead-letter-exchange="". - Retry
[10, 30, 60, 120, 300]s × 5încercări, apoi dead-letter. - Concurență worker: tier priority = 4, important = 2 (
DeliveryProperties, env-overridable). - Job-urile (
NotificationJob) sunt stateless — poartă conținutul deja randat, workerii nu citesc storage.
Secvență — o cerere notify
Section titled “Secvență — o cerere notify”sequenceDiagram participant S as Sistem extern participant V1 as NotifyV1Resource participant D as DispatchService participant DB as PostgreSQL participant MQ as RabbitMQ participant W as Worker participant P as Provider (SES/SNS/…) S->>V1: POST /api/v1/notify/{id} (mTLS) V1->>D: template + variabile + canale D->>DB: Notificare(trackingId) + N×Livrare(QUEUED) + Eveniment(CREATED) D->>MQ: publish notify.{canal}.{tier} MQ->>W: consumă job W->>P: trimite (randat) P-->>W: providerMessageId | eroare W->>DB: Livrare→SENT/FAILED + Eveniment; recalcul status agregat S->>V1: GET /api/v1/notify/{id} → statusSiguranță la regenerare
Section titled “Siguranță la regenerare”JDL este sursa de adevăr; toată logica scrisă de mână trăiește în clase separat denumite ca jhipster jdl să nu o suprascrie: web/rest/v1/*, security/pfx/*, security/oauth2/*, service/v1/*, service/delivery/*, service/channel/*, service/mnotify/*, service/registry/*, repository/lookup/*, config/RabbitMqConfig, audit/*.
Deployment (rezumat)
Section titled “Deployment (rezumat)”Două imagini (backend jar + frontend nginx) + docker-compose-server.yml (backend + frontend + postgres + rabbitmq) pe rețelele internal + gstack-web. Edge vhost gnotify.gstack.esempla.systems. Registrul Destinatarilor are un al doilea SPA (registry-ui/, Angular 20) livrat ca container distinct saas_gnotify:registry-* → portalgnotify.gstack.esempla.systems. Detalii: Deployment.