2019-12-06 17:37:35 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
2022-06-08 01:40:03 +00:00
|
|
|
"log"
|
2022-05-16 09:38:46 +00:00
|
|
|
"net/http"
|
2019-12-06 17:37:35 +00:00
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2020-01-29 10:35:01 +00:00
|
|
|
"srs.epita.fr/fic-server/admin/pki"
|
2022-06-08 01:40:03 +00:00
|
|
|
"srs.epita.fr/fic-server/libfic"
|
2020-01-29 10:35:01 +00:00
|
|
|
|
2022-05-16 09:38:46 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
2019-12-06 17:37:35 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var TimestampCheck = "submissions"
|
|
|
|
|
2022-05-16 09:38:46 +00:00
|
|
|
func declareHealthRoutes(router *gin.RouterGroup) {
|
|
|
|
router.GET("/timestamps.json", func(c *gin.Context) {
|
|
|
|
stat, err := os.Stat(TimestampCheck)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("timestamp.json: %s", err.Error())})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
now := time.Now().UTC()
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
"frontend": stat.ModTime().UTC(),
|
|
|
|
"backend": now,
|
|
|
|
"diffFB": now.Sub(stat.ModTime()),
|
|
|
|
})
|
|
|
|
})
|
|
|
|
router.GET("/health.json", GetHealth)
|
2022-06-08 01:40:03 +00:00
|
|
|
router.GET("/submissions-stats.json", GetSubmissionsStats)
|
|
|
|
router.GET("/validations-stats.json", GetValidationsStats)
|
2024-02-09 16:56:05 +00:00
|
|
|
|
|
|
|
router.DELETE("/submissions/*path", func(c *gin.Context) {
|
|
|
|
err := os.Remove(path.Join(TimestampCheck, c.Params.ByName("path")))
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c.Status(http.StatusOK)
|
|
|
|
})
|
2019-12-06 17:37:35 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 10:35:01 +00:00
|
|
|
type healthFileReport struct {
|
|
|
|
IdTeam string `json:"id_team,omitempty"`
|
|
|
|
Path string `json:"path"`
|
|
|
|
Error string `json:"error"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func getHealth(pathname string) (ret []healthFileReport) {
|
2019-12-06 17:37:35 +00:00
|
|
|
if ds, err := ioutil.ReadDir(pathname); err != nil {
|
2020-01-29 10:35:01 +00:00
|
|
|
ret = append(ret, healthFileReport{
|
2022-05-16 09:38:46 +00:00
|
|
|
Path: strings.TrimPrefix(pathname, TimestampCheck),
|
|
|
|
Error: fmt.Sprintf("unable to ReadDir: %s", err),
|
|
|
|
})
|
2019-12-06 17:37:35 +00:00
|
|
|
return
|
|
|
|
} else {
|
|
|
|
for _, d := range ds {
|
|
|
|
p := path.Join(pathname, d.Name())
|
|
|
|
if d.IsDir() && d.Name() != ".tmp" && d.Mode()&os.ModeSymlink == 0 {
|
|
|
|
ret = append(ret, getHealth(p)...)
|
2022-05-16 09:38:46 +00:00
|
|
|
} else if !d.IsDir() && d.Mode()&os.ModeSymlink == 0 && time.Since(d.ModTime()) > 2*time.Second {
|
2023-05-05 14:08:31 +00:00
|
|
|
if d.Name() == ".locked" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-01-29 10:35:01 +00:00
|
|
|
teamDir := strings.TrimPrefix(pathname, TimestampCheck)
|
|
|
|
idteam, _ := pki.GetAssociation(path.Join(TeamsDir, teamDir))
|
|
|
|
ret = append(ret, healthFileReport{
|
|
|
|
IdTeam: idteam,
|
2022-05-16 09:38:46 +00:00
|
|
|
Path: path.Join(teamDir, d.Name()),
|
|
|
|
Error: "existing untreated file",
|
2020-01-29 10:35:01 +00:00
|
|
|
})
|
2019-12-06 17:37:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-16 09:38:46 +00:00
|
|
|
func GetHealth(c *gin.Context) {
|
2019-12-06 17:37:35 +00:00
|
|
|
if _, err := os.Stat(TimestampCheck); err != nil {
|
2022-05-16 09:38:46 +00:00
|
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("health.json: %s", err.Error())})
|
|
|
|
return
|
2019-12-06 17:37:35 +00:00
|
|
|
}
|
2022-05-16 09:38:46 +00:00
|
|
|
|
|
|
|
c.JSON(http.StatusOK, getHealth(TimestampCheck))
|
2019-12-06 17:37:35 +00:00
|
|
|
}
|
2022-06-08 01:40:03 +00:00
|
|
|
|
|
|
|
type SubmissionsStats struct {
|
|
|
|
NbSubmissionLastMinute uint `json:"nbsubminute"`
|
|
|
|
NbSubmissionLast5Minute uint `json:"nbsub5minute"`
|
|
|
|
NbSubmissionLastQuarter uint `json:"nbsubquarter"`
|
|
|
|
NbSubmissionLastHour uint `json:"nbsubhour"`
|
|
|
|
NbSubmissionLastDay uint `json:"nbsubday"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func calcSubmissionsStats(tries []time.Time) (stats SubmissionsStats) {
|
|
|
|
lastMinute := time.Now().Add(-1 * time.Minute)
|
|
|
|
last5Minute := time.Now().Add(-5 * time.Minute)
|
|
|
|
lastQuarter := time.Now().Add(-15 * time.Minute)
|
|
|
|
lastHour := time.Now().Add(-1 * time.Hour)
|
|
|
|
lastDay := time.Now().Add(-24 * time.Hour)
|
|
|
|
|
|
|
|
for _, t := range tries {
|
|
|
|
if lastMinute.Before(t) {
|
|
|
|
stats.NbSubmissionLastMinute += 1
|
|
|
|
stats.NbSubmissionLast5Minute += 1
|
|
|
|
stats.NbSubmissionLastQuarter += 1
|
|
|
|
stats.NbSubmissionLastHour += 1
|
|
|
|
stats.NbSubmissionLastDay += 1
|
|
|
|
} else if last5Minute.Before(t) {
|
|
|
|
stats.NbSubmissionLast5Minute += 1
|
|
|
|
stats.NbSubmissionLastQuarter += 1
|
|
|
|
stats.NbSubmissionLastHour += 1
|
|
|
|
stats.NbSubmissionLastDay += 1
|
|
|
|
} else if lastQuarter.Before(t) {
|
|
|
|
stats.NbSubmissionLastQuarter += 1
|
|
|
|
stats.NbSubmissionLastHour += 1
|
|
|
|
stats.NbSubmissionLastDay += 1
|
|
|
|
} else if lastHour.Before(t) {
|
|
|
|
stats.NbSubmissionLastHour += 1
|
|
|
|
stats.NbSubmissionLastDay += 1
|
|
|
|
} else if lastDay.Before(t) {
|
|
|
|
stats.NbSubmissionLastDay += 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetSubmissionsStats(c *gin.Context) {
|
|
|
|
tries, err := fic.GetTries(nil, nil)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Unable to GetTries:", err.Error())
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrieves tries."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, calcSubmissionsStats(tries))
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetValidationsStats(c *gin.Context) {
|
|
|
|
tries, err := fic.GetValidations(nil, nil)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Unable to GetTries:", err.Error())
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrieves tries."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, calcSubmissionsStats(tries))
|
|
|
|
}
|