- Standalone SQS-service repository - Multi-tenant message queue service, AWS SQS compatible - Based on GoAws, with mutable tenants, auth, WebUI, Redis persistence - Ready for independent development and deployment - See doc/ and README.md for architecture and usage
129 lines
4.5 KiB
Go
129 lines
4.5 KiB
Go
// app/cmd/seed.go
|
|
// Created: 2026-04-09
|
|
// Updated: 2026-04-09 — фиксированные credentials для demo-tenant (BYOC)
|
|
// Автосид демо-данных при старте через SHARED_SQS_SEED_DEMO=true.
|
|
// Создаёт тенанта demo-service с 5 очередями и демо-сообщениями.
|
|
//
|
|
// DEMO CREDENTIALS — только для тестового стенда.
|
|
// Тенант demo-service изолирован: видит только свои очереди, не имеет доступа к
|
|
// admin API и к очередям других тенантов. Credentials открыты намеренно — стенд публичный.
|
|
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"
|
|
)
|
|
|
|
// Фиксированные credentials демо-тенанта.
|
|
// Открыты намеренно — тестовый стенд.
|
|
// Тенант ограничен 10 очередями и не имеет прав admin API.
|
|
const (
|
|
demoTenantID = "t-demo-shared-sqs-ngcloud"
|
|
demoAccessKey = "SSAK-demo-shared-sqs"
|
|
demoSecretKey = "demo-secret-key-shared-sqs-ngcloud-2026"
|
|
demoTenantName = "demo-service"
|
|
demoMaxQueues = 10
|
|
)
|
|
|
|
// seedDemoData создаёт тенанта demo-service с очередями и сообщениями.
|
|
// Вызывается при SHARED_SQS_SEED_DEMO=true при старте сервера.
|
|
func seedDemoData(store *tenant.TenantStore) {
|
|
t, err := store.CreateFixed(demoTenantName, demoMaxQueues, demoTenantID, demoAccessKey, demoSecretKey)
|
|
if err != nil {
|
|
log.Warnf("seed: не удалось создать demo-tenant: %v", err)
|
|
return
|
|
}
|
|
log.Infof("seed: создан тенант %s (AccessKey=%s)", t.ID, t.AccessKey)
|
|
|
|
// Демо-очереди с набором сообщений
|
|
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.Queues[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)
|
|
}
|