84 lines
3.9 KiB
Go
84 lines
3.9 KiB
Go
package gosqs
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
|
||
log "github.com/sirupsen/logrus"
|
||
|
||
"shared-sqs/app/models"
|
||
)
|
||
|
||
// setQueueAttributesV1 — применяет атрибуты очереди с валидацией по AWS-спецификации.
|
||
//
|
||
// Логическая схема:
|
||
// 1. Whitelist имён: неизвестное имя атрибута → InvalidAttributeName.
|
||
// Список имён (provided) доступен для Query-протокола (form-параметры
|
||
// Attribute.N.Name); для JSON-протокола provided == nil и проверка пропускается
|
||
// (структура уже разобрана из тела, неизвестные поля отброшены).
|
||
// 2. Применяются ТОЛЬКО явно переданные атрибуты (значение != 0).
|
||
// ВАЖНО (фикс): раньше условие `attr.X >= 0` срабатывало и для НЕ переданных
|
||
// полей (zero-value = 0) — вызов SetQueueAttributes с одним атрибутом
|
||
// обнулял все остальные атрибуты очереди.
|
||
// 3. Значения вне диапазонов AWS → ошибка InvalidParameterValue
|
||
// (раньше значения молча клэмпились в допустимый диапазон).
|
||
// 4. RedrivePolicy: ARN DLQ разбирается, DLQ должна существовать, иначе
|
||
// InvalidAttributeValue.
|
||
func setQueueAttributesV1(q *models.Queue, attr models.QueueAttributes, provided map[string]string) error {
|
||
// Шаг 1: whitelist имён атрибутов (единый список — models.AttrNameWhitelist).
|
||
for name := range provided {
|
||
if !models.AttrNameWhitelist[name] {
|
||
return fmt.Errorf("InvalidAttributeName")
|
||
}
|
||
}
|
||
|
||
// Шаг 2: применяем только явно переданные атрибуты с проверкой диапазонов.
|
||
// Диапазоны AWS: DelaySeconds 0–900, MaximumMessageSize 1024–262144,
|
||
// MessageRetentionPeriod 60–1209600, ReceiveMessageWaitTimeSeconds 0–20,
|
||
// VisibilityTimeout 0–43200.
|
||
if attr.DelaySeconds != 0 {
|
||
if attr.DelaySeconds.Int() < 0 || attr.DelaySeconds.Int() > MaxDelaySeconds {
|
||
return fmt.Errorf("InvalidParameterValue")
|
||
}
|
||
q.DelaySeconds = attr.DelaySeconds.Int()
|
||
}
|
||
if attr.MaximumMessageSize != 0 {
|
||
if attr.MaximumMessageSize.Int() < MinMessageSizeLimit || attr.MaximumMessageSize.Int() > MaxMessageSizeLimit {
|
||
return fmt.Errorf("InvalidParameterValue")
|
||
}
|
||
q.MaximumMessageSize = attr.MaximumMessageSize.Int()
|
||
}
|
||
if attr.MessageRetentionPeriod != 0 {
|
||
if attr.MessageRetentionPeriod.Int() < MinMessageRetentionPeriod || attr.MessageRetentionPeriod.Int() > MaxMessageRetentionPeriod {
|
||
return fmt.Errorf("InvalidParameterValue")
|
||
}
|
||
q.MessageRetentionPeriod = attr.MessageRetentionPeriod.Int()
|
||
}
|
||
if attr.ReceiveMessageWaitTimeSeconds != 0 {
|
||
if attr.ReceiveMessageWaitTimeSeconds.Int() < 0 || attr.ReceiveMessageWaitTimeSeconds.Int() > MaxReceiveMessageWaitTimeSeconds {
|
||
return fmt.Errorf("InvalidParameterValue")
|
||
}
|
||
q.ReceiveMessageWaitTimeSeconds = attr.ReceiveMessageWaitTimeSeconds.Int()
|
||
}
|
||
if attr.VisibilityTimeout != 0 {
|
||
if attr.VisibilityTimeout.Int() < 0 || attr.VisibilityTimeout.Int() > MaxVisibilityTimeout {
|
||
return fmt.Errorf("InvalidParameterValue")
|
||
}
|
||
q.VisibilityTimeout = attr.VisibilityTimeout.Int()
|
||
}
|
||
|
||
// Шаг 3: RedrivePolicy (dead-letter queue).
|
||
if attr.RedrivePolicy != (models.RedrivePolicy{}) {
|
||
arnArray := strings.Split(attr.RedrivePolicy.DeadLetterTargetArn, ":")
|
||
queueName := arnArray[len(arnArray)-1]
|
||
deadLetterQueue, ok := models.SyncQueues.Queues[queueName]
|
||
if !ok {
|
||
log.Error("Invalid RedrivePolicy Attribute")
|
||
return fmt.Errorf("InvalidAttributeValue")
|
||
}
|
||
q.DeadLetterQueue = deadLetterQueue
|
||
q.MaxReceiveCount = attr.RedrivePolicy.MaxReceiveCount.Int()
|
||
}
|
||
return nil
|
||
}
|