fix(iot): replaceDSNDatabase (смешение тенантов) + guard namespace (Этап 4)

- replaceDSNDatabase: возвращает ОШИБКУ для key=value DSN (раньше молча отдавал
  исходный DSN → телеметрия всех тенантов ушла бы в management-БД). Query
  отделяется первым '?', поэтому sslrootcert=/path больше не ломает поиск БД.
- EnsureTenantDB: guard safeNamespaceRe (defense-in-depth, совпадает с API-валидацией);
  небезопасный namespace → ErrInvalidNamespace → в consumer классифицируется как
  постоянная ошибка (DLQ, не вечный ретрай).
This commit is contained in:
Repinoid
2026-10-10 19:13:35 +03:00
parent c3492cb0f1
commit faba28f824
2 changed files with 41 additions and 16 deletions
+5
View File
@@ -39,6 +39,11 @@ func processTelemetry(ctx context.Context, body string, store *iotpg.IoTPostgres
// EnsureTenantDB идемпотентен, кэшируется после первого вызова.
if err := store.EnsureTenantDB(ctx, envelope.Namespace); err != nil {
if errors.Is(err, iotpg.ErrInvalidNamespace) {
// Небезопасный namespace — постоянная ошибка → в DLQ (не ретраить).
log.Warn("consumer: invalid namespace, routing to DLQ", "namespace", envelope.Namespace)
return errInvalidEnvelope
}
return err
}
// Время приёма сохраняем в ts (порядок телеметрии). Битый/пустой received_at