64 lines
2.4 KiB
Go
64 lines
2.4 KiB
Go
package gosqs
|
||
|
||
import (
|
||
"net/http"
|
||
"strings"
|
||
|
||
"shared-sqs/app/interfaces"
|
||
"shared-sqs/app/models"
|
||
"shared-sqs/app/persistence"
|
||
"shared-sqs/app/utils"
|
||
|
||
log "github.com/sirupsen/logrus"
|
||
)
|
||
|
||
// DeleteQueueV1 — удаляет очередь тенанта по tenant-scoped ключу.
|
||
//
|
||
// Логическая схема:
|
||
// 1. Разбор тела запроса → DeleteQueueRequest.
|
||
// 2. Тенант из контекста (SigV4 → AccessKey).
|
||
// 3. Имя очереди из QueueUrl (последний сегмент) + tenant-scoped ключ.
|
||
// 4. Под Lock: проверка существования очереди → QueueNotFound (фикс: раньше
|
||
// удаление несуществующей очереди возвращало 200, как будто она удалена);
|
||
// удаление очереди из in-memory map.
|
||
// 5. Асинхронное удаление метаданных и всех сообщений очереди из Redis
|
||
// (persistence.DeleteQueue — защищено write-seq от гонки со SaveQueue).
|
||
func DeleteQueueV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
|
||
requestBody := models.NewDeleteQueueRequest()
|
||
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
|
||
if !ok {
|
||
log.Error("Invalid Request - DeleteQueueV1")
|
||
return utils.CreateErrorResponseV1("InvalidParameterValue", true)
|
||
}
|
||
|
||
t := getTenantFromContext(req)
|
||
if t == nil {
|
||
return utils.CreateErrorResponseV1("InvalidClientTokenId", true)
|
||
}
|
||
|
||
uriSegments := strings.Split(requestBody.QueueUrl, "/")
|
||
queueName := uriSegments[len(uriSegments)-1]
|
||
key := tenantQueueKey(t.AccessKey, queueName)
|
||
|
||
log.Infof("Deleting Queue: %s (tenant: %s)", queueName, t.ID)
|
||
|
||
models.SyncQueues.Lock()
|
||
defer models.SyncQueues.Unlock()
|
||
// Проверка существования: AWS возвращает NonExistentQueue, а не 200
|
||
// (раньше удаление несуществующей очереди молча «успевало»).
|
||
if _, ok := models.SyncQueues.Queues[key]; !ok {
|
||
log.Warnf("Delete Queue: %s does not exist (tenant: %s)", queueName, t.ID)
|
||
return utils.CreateErrorResponseV1("QueueNotFound", true)
|
||
}
|
||
delete(models.SyncQueues.Queues, key)
|
||
|
||
// Удаляем из Redis асинхронно
|
||
persistence.DeleteQueue(key)
|
||
|
||
respStruct := models.DeleteQueueResponse{
|
||
Xmlns: models.BaseXmlns,
|
||
Metadata: models.BaseResponseMetadata,
|
||
}
|
||
return http.StatusOK, respStruct
|
||
}
|