Rainbond/api/util/events.go
2019-09-10 12:53:50 +08:00

134 lines
3.8 KiB
Go

// Copyright (C) 2014-2018 Goodrain Co., Ltd.
// RAINBOND, Application Management Platform
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package util
import (
"time"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/db"
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/util"
"github.com/jinzhu/gorm"
)
// CanDoEvent check can do event or not
func CanDoEvent(optType string, synType int, target, targetID string) bool {
if synType == dbmodel.SYNEVENTTYPE {
return true
}
event, err := db.GetManager().ServiceEventDao().GetLastASyncEvent(target, targetID)
if err != nil {
if err.Error() == gorm.ErrRecordNotFound.Error() {
return true
}
logrus.Error("get event by targetID error:", err)
return false
}
if event == nil || event.FinalStatus != "" {
return true
}
if !checkTimeout(event) {
return false
}
return true
}
func checkTimeout(event *dbmodel.ServiceEvent) bool {
if event.SynType == dbmodel.ASYNEVENTTYPE {
if event.FinalStatus == "" {
startTime := event.StartTime
start, err := time.ParseInLocation(time.RFC3339, startTime, time.Local)
if err != nil {
return false
}
var end time.Time
if event.OptType == "deploy-service" || event.OptType == "create-service" || event.OptType == "build-service" {
end = start.Add(10 * time.Minute)
} else {
end = start.Add(3 * time.Minute)
}
if time.Now().After(end) {
event.FinalStatus = "timeout"
err = db.GetManager().ServiceEventDao().UpdateModel(event)
if err != nil {
logrus.Error("check event timeout error : ", err.Error())
return false
}
return true
}
// latest event is still processing on
return false
}
}
return true
}
// CreateEvent save event
func CreateEvent(target, optType, targetID, tenantID, reqBody, userName string, synType int) (*dbmodel.ServiceEvent, error) {
if len(reqBody) > 1024 {
reqBody = reqBody[0:1024]
}
event := dbmodel.ServiceEvent{
EventID: util.NewUUID(),
TenantID: tenantID,
Target: target,
TargetID: targetID,
RequestBody: reqBody,
UserName: userName,
StartTime: time.Now().Format(time.RFC3339),
SynType: synType,
OptType: optType,
}
err := db.GetManager().ServiceEventDao().AddModel(&event)
return &event, err
}
// UpdateEvent update event
func UpdateEvent(eventID string, statusCode int) {
event, err := db.GetManager().ServiceEventDao().GetEventByEventID(eventID)
if err != nil && err != gorm.ErrRecordNotFound {
logrus.Errorf("find event by eventID error : %s", err.Error())
return
}
if err == gorm.ErrRecordNotFound {
logrus.Errorf("do not found event by eventID %s", eventID)
return
}
event.FinalStatus = "complete"
event.EndTime = time.Now().Format(time.RFC3339)
if statusCode < 400 { // status code 2XX/3XX all equal to success
event.Status = "success"
} else {
event.Status = "failure"
}
err = db.GetManager().ServiceEventDao().UpdateModel(event)
if err != nil {
logrus.Errorf("update event status failure %s", err.Error())
retry := 2
for retry > 0 {
if err = db.GetManager().ServiceEventDao().UpdateModel(event); err != nil {
retry--
} else {
break
}
}
}
}