// Copyright 2019 Yunion // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package models import ( "context" "net/http" "time" "yunion.io/x/pkg/errors" api "yunion.io/x/onecloud/pkg/apis/notify" "yunion.io/x/onecloud/pkg/appsrv" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/mcclient" ) var ReceiverNotificationManager *SReceiverNotificationManager func init() { db.InitManager(func() { ReceiverNotificationManager = &SReceiverNotificationManager{ SJointResourceBaseManager: db.NewJointResourceBaseManager( SReceiverNotification{}, "receivernotification_tbl", "receivernotification", "receivernotifications", NotificationManager, ReceiverManager, ), } ReceiverNotificationManager.SetVirtualObject(ReceiverNotificationManager) ReceiverNotificationManager.TableSpec().AddIndex(true, "receiver_id", "contact", "notification_id") }) } type SReceiverNotificationManager struct { db.SJointResourceBaseManager } const ( ReceiverIdDefault = "default" ) // +onecloud:swagger-gen-ignore type SReceiverNotification struct { db.SJointResourceBase ReceiverID string `width:"128" charset:"ascii" nullable:"false" index:"true"` NotificationID string `width:"128" charset:"ascii" nullable:"false" index:"true"` // ignore if ReceiverID is not empty or default Contact string `width:"128" index:"true"` ReceiverType string `width:"16"` SendAt time.Time SendBy string `width:"128"` Status string `width:"36" charset:"ascii"` FailedReason string `width:"1024"` // minutes GroupTimes uint32 } func (self *SReceiverNotificationManager) InitializeData() error { return dataCleaning(self.TableSpec().Name()) } func (self *SReceiverNotification) GetReceiver() (*SReceiver, error) { recv, err := ReceiverManager.FetchById(self.ReceiverID) if err != nil { return nil, errors.Wrapf(err, "with id %s", self.ReceiverID) } return recv.(*SReceiver), nil } func (rnm *SReceiverNotificationManager) Create(ctx context.Context, userCred mcclient.TokenCredential, receiverID string, groupTimes uint32, notificationID string) (*SReceiverNotification, error) { rn := &SReceiverNotification{ ReceiverID: receiverID, NotificationID: notificationID, GroupTimes: groupTimes, ReceiverType: api.RECEIVER_TYPE_USER, Status: api.RECEIVER_NOTIFICATION_RECEIVED, SendBy: userCred.GetUserId(), } return rn, rnm.TableSpec().Insert(ctx, rn) } func (rnm *SReceiverNotificationManager) CreateRobot(ctx context.Context, userCred mcclient.TokenCredential, RobotID string, groupTimes uint32, notificationID string) (*SReceiverNotification, error) { rn := &SReceiverNotification{ ReceiverID: RobotID, NotificationID: notificationID, ReceiverType: api.RECEIVER_TYPE_ROBOT, Status: api.RECEIVER_NOTIFICATION_RECEIVED, SendBy: userCred.GetUserId(), GroupTimes: groupTimes, } return rn, rnm.TableSpec().Insert(ctx, rn) } func (rnm *SReceiverNotificationManager) GetMasterFieldName() string { return "notification_id" } func (rnm *SReceiverNotificationManager) GetSlaveFieldName() string { return "receiver_id" } func (rnm *SReceiverNotificationManager) CreateContact(ctx context.Context, userCred mcclient.TokenCredential, contact, notificationID string) (*SReceiverNotification, error) { rn := &SReceiverNotification{ NotificationID: notificationID, ReceiverType: api.RECEIVER_TYPE_CONTACT, Contact: contact, Status: api.RECEIVER_NOTIFICATION_RECEIVED, SendBy: userCred.GetUserId(), } return rn, rnm.TableSpec().Insert(ctx, rn) } func (rnm *SReceiverNotificationManager) SetHandlerProcessTimeout(info *appsrv.SHandlerInfo, r *http.Request) time.Duration { if r.Method == http.MethodGet && len(r.URL.Query().Get("export_keys")) > 0 { return time.Hour * 2 } return -time.Second } func (rn *SReceiverNotification) Receiver() (IReceiver, error) { switch rn.ReceiverType { case api.RECEIVER_TYPE_USER: return rn.receiver() case api.RECEIVER_TYPE_CONTACT: return &SContact{contact: rn.Contact}, nil case api.RECEIVER_TYPE_ROBOT: return rn.robot() default: // compatible if rn.ReceiverID != "" && rn.ReceiverID != ReceiverIdDefault { return rn.receiver() } return &SContact{contact: rn.Contact}, nil } } func (rn *SReceiverNotification) receiver() (*SReceiver, error) { q := ReceiverManager.Query().Equals("id", rn.ReceiverID) var receiver SReceiver err := q.First(&receiver) if err != nil { return nil, err } receiver.SetModelManager(ReceiverManager, &receiver) return &receiver, nil } func (rn *SReceiverNotification) robot() (*SRobot, error) { q := RobotManager.Query().Equals("id", rn.ReceiverID) var robot SRobot err := q.First(&robot) if err != nil { return nil, err } robot.SetModelManager(RobotManager, &robot) return &robot, nil } /* func (rn *SReceiverNotification) Receiver() (IReceiver, error) { switch rn.ReceiverType { case api.RECEIVER_TYPE_USER: return rn.receiver() case api.RECEIVER_TYPE_CONTACT: return &SContact{contact: rn.Contact}, nil case api.RECEIVER_TYPE_ROBOT: return rn.robot() default: // compatible if rn.ReceiverID != "" && rn.ReceiverID != ReceiverIdDefault { return rn.receiver() } return &SContact{contact: rn.Contact}, nil } } */ func (rn *SReceiverNotification) BeforeSend(ctx context.Context, sendTime time.Time) error { if sendTime.IsZero() { sendTime = time.Now() } _, err := db.Update(rn, func() error { rn.SendAt = sendTime rn.Status = api.RECEIVER_NOTIFICATION_SENT return nil }) return err } func (rn *SReceiverNotification) AfterSend(ctx context.Context, success bool, reason string) error { _, err := db.Update(rn, func() error { if success { rn.Status = api.RECEIVER_NOTIFICATION_OK } else { rn.Status = api.RECEIVER_NOTIFICATION_FAIL rn.FailedReason = reason } return nil }) return err } type IReceiver interface { IsRobot() bool IsReceiver() bool IsEnabled() bool GetDomainId() string IsEnabledContactType(string) (bool, error) IsVerifiedContactType(string) (bool, error) GetContact(string) (string, error) GetTemplateLang(context.Context) (string, error) } type SReceiverBase struct { } func (s SReceiverBase) IsEnabled() bool { return true } func (s SReceiverBase) GetDomainId() string { return "" } func (s SReceiverBase) IsEnabledContactType(_ string) (bool, error) { return true, nil } func (s SReceiverBase) IsVerifiedContactType(_ string) (bool, error) { return true, nil } func (s SReceiverBase) GetTemplateLang(ctx context.Context) (string, error) { return "", nil } type SContact struct { SReceiverBase contact string } func (s *SContact) GetContact(_ string) (string, error) { return s.contact, nil } func (s *SContact) IsRobot() bool { return false } func (s *SContact) IsReceiver() bool { return false }