// 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 . 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 } } } }