Files
SQS-service/app/cmd/seed.go
T
Repinoid 3a52960d5b P1.4: tenant-индекс очередей (O(1) подсчёт/список вместо скана)
Введён тип QueueStore с индексом accessKey→{queueName}. Мутации очередей идут через
AddQueue/RemoveQueue (create/delete/restore/config/seed/admin), подсчёт и список —
через CountTenantQueues/TenantQueueNames. Устранены O(total) скан-по-префиксу в
countTenantQueues, deleteTenant, listTenantQueues, createTenantQueue. API SyncQueues
(Queues, Lock) сохранён — остальной код не затронут.
2026-10-06 18:36:03 +03:00

124 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// app/cmd/seed.go
// Автосид демо-данных при старте через SHARED_SQS_SEED_DEMO=true.
// Создаёт тенанта demo-service со случайными кредами (генерируются через
// tenant.Create → crypto/rand) с 5 очередями и демо-сообщениями.
//
// Тенант demo-service изолирован: видит только свои очереди, не имеет доступа к
// admin API и к очередям других тенантов. Креды генерируются случайно и печатаются
// в лог при старте (только при явном включении SHARED_SQS_SEED_DEMO).
package main
import (
"crypto/md5" //nolint:gosec — MD5 используется для SQS-совместимости, не для безопасности
"fmt"
"time"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"shared-sqs/app/models"
"shared-sqs/app/tenant"
)
const (
demoTenantName = "demo-service"
demoMaxQueues = 10
)
// seedDemoData создаёт тенанта demo-service с очередями и сообщениями.
// Вызывается при SHARED_SQS_SEED_DEMO=true при старте сервера.
// Креды генерируются случайно (tenant.Create) — никаких захардкоженных
// AccessKey/SecretKey в исходнике.
func seedDemoData(store *tenant.TenantStore) {
t, err := store.Create(demoTenantName, demoMaxQueues)
if err != nil {
log.Warnf("seed: не удалось создать demo-tenant: %v", err)
return
}
log.Infof("seed: создан тенант %s (AccessKey=%s, SecretKey=%s)", t.ID, t.AccessKey, t.SecretKey)
// Демо-очереди с набором сообщений
queues := []struct {
name string
msgs []string
}{
{
"orders",
[]string{
`{"order_id":"1001","amount":99.99,"status":"pending"}`,
`{"order_id":"1002","amount":14.50,"status":"completed"}`,
`{"order_id":"1003","amount":299.00,"status":"processing"}`,
},
},
{
"notifications",
[]string{
`{"to":"user@example.com","text":"Welcome to the service!"}`,
`{"to":"admin@example.com","text":"New user signed up"}`,
},
},
{
"emails",
[]string{
`{"subject":"Invoice #42","body":"See attachment","to":"billing@example.com"}`,
},
},
{
"uploads",
nil,
},
{
"user-events",
[]string{
`{"event":"login","user_id":"u-123","ts":1744000000}`,
`{"event":"logout","user_id":"u-123","ts":1744003600}`,
`{"event":"purchase","user_id":"u-456","item_id":"prod-7","ts":1744005000}`,
},
},
}
for _, q := range queues {
key := t.AccessKey + ":" + q.name
// URL и ARN формируем по тому же шаблону что gosqs/tenant_helpers.go:tenantQueueURL/tenantQueueARN
// Иначе AWS CLI получает пустой QueueUrl в ListQueues и не может работать с очередью.
env := models.CurrentEnvironment
var queueURL string
if env.Region != "" {
queueURL = "http://" + env.Region + "." + env.Host + ":" + env.Port + "/" + t.ID + "/" + q.name
} else {
queueURL = "http://" + env.Host + ":" + env.Port + "/" + t.ID + "/" + q.name
}
queueARN := "arn:aws:sqs:" + env.Region + ":" + t.ID + ":" + q.name
msgs := make([]models.SqsMessage, 0, len(q.msgs))
for _, body := range q.msgs {
//nolint:gosec — MD5 здесь для совместимости с AWS SQS протоколом
sum := md5.Sum([]byte(body)) //nolint:gosec
msgs = append(msgs, models.SqsMessage{
MessageBody: body,
Uuid: uuid.NewString(),
MD5OfMessageBody: fmt.Sprintf("%x", sum),
SentTime: time.Now(),
})
}
models.SyncQueues.Lock()
models.SyncQueues.AddQueue(key, &models.Queue{
Name: q.name,
URL: queueURL,
Arn: queueARN,
VisibilityTimeout: 30,
MaximumMessageSize: 262144,
MessageRetentionPeriod: 345600,
Messages: msgs,
Duplicates: make(map[string]time.Time),
})
models.SyncQueues.Unlock()
log.Infof("seed: очередь %s (%d сообщений)", q.name, len(q.msgs))
}
log.Infof("seed: демо-данные готовы — тенант %s, 5 очередей", t.Name)
}