home.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package web
  2. import (
  3. "context"
  4. "log"
  5. "net/http"
  6. "time"
  7. "github.com/gin-contrib/sessions"
  8. "github.com/gin-gonic/gin"
  9. "code.osinet.fr/fgm/sqs_demo/back/services/redriver"
  10. )
  11. // classifyPolicies distributes queue policies across five bins:
  12. // - wild: policies describing a DLQ with an allowAll policy
  13. // - closed: policies describing a DLQ with an denyAll policy
  14. // - byQueue: policies describing a DLQ with an byQueue policy
  15. // - sources: policies describing a queue with a DLQ
  16. // - notSources: policies describing a queue without a DLQ
  17. //
  18. // Note that dead-letter queues may also by source queues, for multi-level processing, and vice-versa.
  19. //
  20. // For easier reading, DLQs are not listed as part of the non-source list.
  21. func classifyPolicies(policies map[string]*redriver.QueueRedrivePolicies) (byQueue, wild, closed, sources map[string]redriver.QueueRedrivePolicies, notSources []string) {
  22. DLQs := make(map[string]redriver.QueueRedrivePolicies)
  23. sources = make(map[string]redriver.QueueRedrivePolicies)
  24. wild = make(map[string]redriver.QueueRedrivePolicies)
  25. closed = make(map[string]redriver.QueueRedrivePolicies)
  26. byQueue = make(map[string]redriver.QueueRedrivePolicies)
  27. nsTemp := make([]string, 0, len(notSources))
  28. for qURL, qrp := range policies {
  29. if qrp.QueueInfoAttributesRedriveAllowPolicy != nil {
  30. DLQs[qURL] = *qrp
  31. }
  32. if qrp.QueueInfoAttributesRedrivePolicy != nil {
  33. sources[qURL] = *qrp
  34. } else {
  35. nsTemp = append(nsTemp, qURL)
  36. }
  37. }
  38. for _, qURL := range nsTemp {
  39. if _, ok := DLQs[qURL]; !ok {
  40. notSources = append(notSources, qURL)
  41. }
  42. }
  43. for qURL, qrp := range DLQs {
  44. rap := qrp.QueueInfoAttributesRedriveAllowPolicy
  45. switch rap.RedrivePermission {
  46. case "allowAll":
  47. wild[qURL] = qrp
  48. case "denyAll":
  49. closed[qURL] = qrp
  50. case "byQueue":
  51. byQueue[qURL] = qrp
  52. }
  53. }
  54. return
  55. }
  56. func policiesByURL(c *gin.Context, qURLs []string, rd redriver.Redriver, ctx context.Context) map[string]*redriver.QueueRedrivePolicies {
  57. qMap := make(map[string]*redriver.QueueRedrivePolicies, len(qURLs))
  58. for _, qURL := range qURLs {
  59. name, err := redriver.NameFromURL(qURL)
  60. if err != nil {
  61. log.Println(http.StatusInternalServerError)
  62. c.HTML(http.StatusInternalServerError, "500", nil)
  63. }
  64. qrp, err := rd.GetRedrivePolicies(ctx, name)
  65. if err != nil || qrp == nil {
  66. log.Println(err)
  67. c.HTML(http.StatusInternalServerError, "500", nil)
  68. }
  69. qMap[qURL] = qrp
  70. }
  71. return qMap
  72. }
  73. type link struct{ URL, Text string }
  74. // queueRow provides templates with a representation for all kinds of table cells
  75. type queueCell struct {
  76. Message string
  77. Link *link
  78. Links []link
  79. }
  80. type QueueRow [2]queueCell
  81. func makeHomeHandler(rd redriver.Redriver) gin.HandlerFunc {
  82. return func(c *gin.Context) {
  83. ctx := c.Request.Context()
  84. sess := sessions.Default(c)
  85. flashes := sess.Flashes()
  86. defer func() { _ = sess.Save() }()
  87. t0 := time.Now()
  88. qURLs, err := rd.ListQueues(ctx, "")
  89. latency := time.Since(t0)
  90. if err != nil {
  91. log.Printf("failed listing queues: %v", err)
  92. c.HTML(http.StatusInternalServerError, "500", nil)
  93. return
  94. }
  95. policies := policiesByURL(c, qURLs, rd, ctx)
  96. byqueue, wild, closed, sources, notSources := classifyPolicies(policies)
  97. // log.Printf("DLQs: %#v\nSRCs: %#v\nNoSRCs: %#v\n", maps.Keys(DLQs), maps.Keys(SRCs), NoSRCs)
  98. l := len(byqueue)
  99. if len(wild) > 0 {
  100. l++
  101. }
  102. if len(closed) > 0 {
  103. l++
  104. }
  105. if len(notSources) > 0 {
  106. l++
  107. }
  108. rows := make([]QueueRow, 0, l) // Sources appears within a byQueue row
  109. rows, err = prepareSingleLeft(wild, rows, "All source queues allowed")
  110. if err != nil {
  111. log.Printf("failed converting queue URL %q: %v", qURLs, err)
  112. c.HTML(http.StatusInternalServerError, "500", nil)
  113. return
  114. }
  115. rows, err = prepareSingleLeft(closed, rows, "No source queue allowed")
  116. if err != nil {
  117. log.Printf("failed converting queue URL %q: %v", qURLs, err)
  118. c.HTML(http.StatusInternalServerError, "500", nil)
  119. return
  120. }
  121. rows, err = prepareSingleRight(notSources, rows, "No associated DLQ")
  122. if err != nil {
  123. log.Printf("failed converting queue URL %q: %v", qURLs, err)
  124. c.HTML(http.StatusInternalServerError, "500", nil)
  125. return
  126. }
  127. // for qURLs := range closed {
  128. //
  129. // }
  130. log.Println(sources)
  131. c.HTML(http.StatusOK, "home", gin.H{
  132. "flashes": flashes,
  133. "latency": latency,
  134. "rows": rows,
  135. })
  136. }
  137. }
  138. func prepareSingleLeft(list map[string]redriver.QueueRedrivePolicies, rows []QueueRow, msg string) ([]QueueRow, error) {
  139. if len(list) > 0 {
  140. row := QueueRow{
  141. {Message: msg},
  142. {Links: make([]link, 0, len(list))},
  143. }
  144. for qURL := range list {
  145. name, err := redriver.NameFromURL(qURL)
  146. if err != nil {
  147. return nil, err
  148. }
  149. row[1].Links = append(row[1].Links, link{URL: "/queue/" + name, Text: name})
  150. }
  151. rows = append(rows, row)
  152. }
  153. return rows, nil
  154. }
  155. func prepareSingleRight(list []string, rows []QueueRow, msg string) ([]QueueRow, error) {
  156. if len(list) > 0 {
  157. row := QueueRow{
  158. {Links: make([]link, 0, len(list))},
  159. {Message: msg},
  160. }
  161. for _, qURL := range list {
  162. name, err := redriver.NameFromURL(qURL)
  163. if err != nil {
  164. return nil, err
  165. }
  166. row[0].Links = append(row[0].Links, link{URL: "/queue/" + name, Text: name})
  167. }
  168. rows = append(rows, row)
  169. }
  170. return rows, nil
  171. }