package main import ( "errors" "fmt" "net/url" "strings" "git.ipao.vip/rogee/go-sip/internal/mq" amqp "github.com/rabbitmq/amqp091-go" ) // provisionMQ is SaaS-owned setup in a dedicated vhost. It never publishes, // consumes, purges, deletes, or resets an existing queue. func requireDedicatedVhost(brokerURL string) error { address, err := url.Parse(brokerURL) if err != nil || (address.Scheme != "amqp" && address.Scheme != "amqps") || address.Host == "" || !strings.HasPrefix(strings.TrimPrefix(address.Path, "/"), "saas-mock-") { return errors.New("SaaS test MQ requires a dedicated saas-mock-* vhost") } return nil } func provisionMQ(brokerURL string, data dataset) error { if err := requireDedicatedVhost(brokerURL); err != nil { return err } conn, err := amqp.Dial(brokerURL) if err != nil { return fmt.Errorf("connect SaaS test MQ: %T", err) } defer conn.Close() channel, err := conn.Channel() if err != nil { return fmt.Errorf("open SaaS test MQ channel: %T", err) } defer channel.Close() for _, name := range []string{mq.CommandsExchange, mq.ResultsExchange} { if err := channel.ExchangeDeclare(name, "topic", true, false, false, false, nil); err != nil { return fmt.Errorf("declare SaaS test exchange %s: %T", name, err) } } control := mq.ControlQueueName(data.dispatcherID) if _, err := channel.QueueDeclare(control, true, false, false, false, nil); err != nil { return fmt.Errorf("declare SaaS control queue: %T", err) } if err := channel.QueueBind(control, "d."+data.dispatcherID+".control.in", mq.CommandsExchange, false, nil); err != nil { return fmt.Errorf("bind SaaS control queue: %T", err) } for _, task := range data.discovery { queue := "agent-call.d." + data.dispatcherID + ".task." + task.TaskID + ".v1" if _, err := channel.QueueDeclare(queue, true, false, false, false, nil); err != nil { return fmt.Errorf("declare SaaS task queue: %T", err) } if err := channel.QueueBind(queue, "d."+data.dispatcherID+".task."+task.TaskID+".in", mq.CommandsExchange, false, nil); err != nil { return fmt.Errorf("bind SaaS task queue: %T", err) } } const resultQueue = "agent-call.saas.events.v1" if _, err := channel.QueueDeclare(resultQueue, true, false, false, false, nil); err != nil { return fmt.Errorf("declare SaaS result queue: %T", err) } if err := channel.QueueBind(resultQueue, "d."+data.dispatcherID+".out", mq.ResultsExchange, false, nil); err != nil { return fmt.Errorf("bind SaaS result queue: %T", err) } return nil }