receiver_notification.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package models
  15. import (
  16. "context"
  17. "net/http"
  18. "time"
  19. "yunion.io/x/pkg/errors"
  20. api "yunion.io/x/onecloud/pkg/apis/notify"
  21. "yunion.io/x/onecloud/pkg/appsrv"
  22. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  23. "yunion.io/x/onecloud/pkg/mcclient"
  24. )
  25. var ReceiverNotificationManager *SReceiverNotificationManager
  26. func init() {
  27. db.InitManager(func() {
  28. ReceiverNotificationManager = &SReceiverNotificationManager{
  29. SJointResourceBaseManager: db.NewJointResourceBaseManager(
  30. SReceiverNotification{},
  31. "receivernotification_tbl",
  32. "receivernotification",
  33. "receivernotifications",
  34. NotificationManager,
  35. ReceiverManager,
  36. ),
  37. }
  38. ReceiverNotificationManager.SetVirtualObject(ReceiverNotificationManager)
  39. ReceiverNotificationManager.TableSpec().AddIndex(true, "receiver_id", "contact", "notification_id")
  40. })
  41. }
  42. type SReceiverNotificationManager struct {
  43. db.SJointResourceBaseManager
  44. }
  45. const (
  46. ReceiverIdDefault = "default"
  47. )
  48. // +onecloud:swagger-gen-ignore
  49. type SReceiverNotification struct {
  50. db.SJointResourceBase
  51. ReceiverID string `width:"128" charset:"ascii" nullable:"false" index:"true"`
  52. NotificationID string `width:"128" charset:"ascii" nullable:"false" index:"true"`
  53. // ignore if ReceiverID is not empty or default
  54. Contact string `width:"128" index:"true"`
  55. ReceiverType string `width:"16"`
  56. SendAt time.Time
  57. SendBy string `width:"128"`
  58. Status string `width:"36" charset:"ascii"`
  59. FailedReason string `width:"1024"`
  60. // minutes
  61. GroupTimes uint32
  62. }
  63. func (self *SReceiverNotificationManager) InitializeData() error {
  64. return dataCleaning(self.TableSpec().Name())
  65. }
  66. func (self *SReceiverNotification) GetReceiver() (*SReceiver, error) {
  67. recv, err := ReceiverManager.FetchById(self.ReceiverID)
  68. if err != nil {
  69. return nil, errors.Wrapf(err, "with id %s", self.ReceiverID)
  70. }
  71. return recv.(*SReceiver), nil
  72. }
  73. func (rnm *SReceiverNotificationManager) Create(ctx context.Context, userCred mcclient.TokenCredential, receiverID string, groupTimes uint32, notificationID string) (*SReceiverNotification, error) {
  74. rn := &SReceiverNotification{
  75. ReceiverID: receiverID,
  76. NotificationID: notificationID,
  77. GroupTimes: groupTimes,
  78. ReceiverType: api.RECEIVER_TYPE_USER,
  79. Status: api.RECEIVER_NOTIFICATION_RECEIVED,
  80. SendBy: userCred.GetUserId(),
  81. }
  82. return rn, rnm.TableSpec().Insert(ctx, rn)
  83. }
  84. func (rnm *SReceiverNotificationManager) CreateRobot(ctx context.Context, userCred mcclient.TokenCredential, RobotID string, groupTimes uint32, notificationID string) (*SReceiverNotification, error) {
  85. rn := &SReceiverNotification{
  86. ReceiverID: RobotID,
  87. NotificationID: notificationID,
  88. ReceiverType: api.RECEIVER_TYPE_ROBOT,
  89. Status: api.RECEIVER_NOTIFICATION_RECEIVED,
  90. SendBy: userCred.GetUserId(),
  91. GroupTimes: groupTimes,
  92. }
  93. return rn, rnm.TableSpec().Insert(ctx, rn)
  94. }
  95. func (rnm *SReceiverNotificationManager) GetMasterFieldName() string {
  96. return "notification_id"
  97. }
  98. func (rnm *SReceiverNotificationManager) GetSlaveFieldName() string {
  99. return "receiver_id"
  100. }
  101. func (rnm *SReceiverNotificationManager) CreateContact(ctx context.Context, userCred mcclient.TokenCredential, contact, notificationID string) (*SReceiverNotification, error) {
  102. rn := &SReceiverNotification{
  103. NotificationID: notificationID,
  104. ReceiverType: api.RECEIVER_TYPE_CONTACT,
  105. Contact: contact,
  106. Status: api.RECEIVER_NOTIFICATION_RECEIVED,
  107. SendBy: userCred.GetUserId(),
  108. }
  109. return rn, rnm.TableSpec().Insert(ctx, rn)
  110. }
  111. func (rnm *SReceiverNotificationManager) SetHandlerProcessTimeout(info *appsrv.SHandlerInfo, r *http.Request) time.Duration {
  112. if r.Method == http.MethodGet && len(r.URL.Query().Get("export_keys")) > 0 {
  113. return time.Hour * 2
  114. }
  115. return -time.Second
  116. }
  117. func (rn *SReceiverNotification) Receiver() (IReceiver, error) {
  118. switch rn.ReceiverType {
  119. case api.RECEIVER_TYPE_USER:
  120. return rn.receiver()
  121. case api.RECEIVER_TYPE_CONTACT:
  122. return &SContact{contact: rn.Contact}, nil
  123. case api.RECEIVER_TYPE_ROBOT:
  124. return rn.robot()
  125. default:
  126. // compatible
  127. if rn.ReceiverID != "" && rn.ReceiverID != ReceiverIdDefault {
  128. return rn.receiver()
  129. }
  130. return &SContact{contact: rn.Contact}, nil
  131. }
  132. }
  133. func (rn *SReceiverNotification) receiver() (*SReceiver, error) {
  134. q := ReceiverManager.Query().Equals("id", rn.ReceiverID)
  135. var receiver SReceiver
  136. err := q.First(&receiver)
  137. if err != nil {
  138. return nil, err
  139. }
  140. receiver.SetModelManager(ReceiverManager, &receiver)
  141. return &receiver, nil
  142. }
  143. func (rn *SReceiverNotification) robot() (*SRobot, error) {
  144. q := RobotManager.Query().Equals("id", rn.ReceiverID)
  145. var robot SRobot
  146. err := q.First(&robot)
  147. if err != nil {
  148. return nil, err
  149. }
  150. robot.SetModelManager(RobotManager, &robot)
  151. return &robot, nil
  152. }
  153. /*
  154. func (rn *SReceiverNotification) Receiver() (IReceiver, error) {
  155. switch rn.ReceiverType {
  156. case api.RECEIVER_TYPE_USER:
  157. return rn.receiver()
  158. case api.RECEIVER_TYPE_CONTACT:
  159. return &SContact{contact: rn.Contact}, nil
  160. case api.RECEIVER_TYPE_ROBOT:
  161. return rn.robot()
  162. default:
  163. // compatible
  164. if rn.ReceiverID != "" && rn.ReceiverID != ReceiverIdDefault {
  165. return rn.receiver()
  166. }
  167. return &SContact{contact: rn.Contact}, nil
  168. }
  169. }
  170. */
  171. func (rn *SReceiverNotification) BeforeSend(ctx context.Context, sendTime time.Time) error {
  172. if sendTime.IsZero() {
  173. sendTime = time.Now()
  174. }
  175. _, err := db.Update(rn, func() error {
  176. rn.SendAt = sendTime
  177. rn.Status = api.RECEIVER_NOTIFICATION_SENT
  178. return nil
  179. })
  180. return err
  181. }
  182. func (rn *SReceiverNotification) AfterSend(ctx context.Context, success bool, reason string) error {
  183. _, err := db.Update(rn, func() error {
  184. if success {
  185. rn.Status = api.RECEIVER_NOTIFICATION_OK
  186. } else {
  187. rn.Status = api.RECEIVER_NOTIFICATION_FAIL
  188. rn.FailedReason = reason
  189. }
  190. return nil
  191. })
  192. return err
  193. }
  194. type IReceiver interface {
  195. IsRobot() bool
  196. IsReceiver() bool
  197. IsEnabled() bool
  198. GetDomainId() string
  199. IsEnabledContactType(string) (bool, error)
  200. IsVerifiedContactType(string) (bool, error)
  201. GetContact(string) (string, error)
  202. GetTemplateLang(context.Context) (string, error)
  203. }
  204. type SReceiverBase struct {
  205. }
  206. func (s SReceiverBase) IsEnabled() bool {
  207. return true
  208. }
  209. func (s SReceiverBase) GetDomainId() string {
  210. return ""
  211. }
  212. func (s SReceiverBase) IsEnabledContactType(_ string) (bool, error) {
  213. return true, nil
  214. }
  215. func (s SReceiverBase) IsVerifiedContactType(_ string) (bool, error) {
  216. return true, nil
  217. }
  218. func (s SReceiverBase) GetTemplateLang(ctx context.Context) (string, error) {
  219. return "", nil
  220. }
  221. type SContact struct {
  222. SReceiverBase
  223. contact string
  224. }
  225. func (s *SContact) GetContact(_ string) (string, error) {
  226. return s.contact, nil
  227. }
  228. func (s *SContact) IsRobot() bool {
  229. return false
  230. }
  231. func (s *SContact) IsReceiver() bool {
  232. return false
  233. }