package tools import ( "encoding/json" "errors" "cloud.o-forge.io/core/oc-lib/dbs/mongo" ) var UncatchedError = []error{} type State int const ( ALIVE State = iota REDUCED_SERVICE UNPROCESSABLE_ENTITY DB_FALLOUT TEAPOT DEAD WAITING ) func (s State) EnumIndex() int { return int(s) } func ToState(str string) State { for _, s := range []State{ALIVE, REDUCED_SERVICE, UNPROCESSABLE_ENTITY, DB_FALLOUT, TEAPOT, DEAD, WAITING} { if s.String() == str { return s } } return DEAD } func (s State) String() string { return [...]string{"alive", "reduced service", "unprocessable entity", "database fallout", "some things boils in here, i'm probably a teapot", "dead", "waiting"}[s] } type API struct{} func (a *API) GetState() (State, int, error) { // Check if the database is up err := mongo.MONGOService.TestDB(GetConfig()) if err != nil { return DB_FALLOUT, 200, err } err = mongo.MONGOService.TestCollections(GetConfig(), []string{}) if err != nil { return UNPROCESSABLE_ENTITY, 200, err } if len(UncatchedError) > 0 { errStr := "" for _, e := range UncatchedError { errStr += e.Error() + "\n" } return TEAPOT, 200, errors.New(errStr) } return ALIVE, 200, nil } func (a *API) CheckRemotePeer(url string) (State, map[string]int) { // Check if the database is up caller := NewHTTPCaller(map[string]map[METHOD]string{}) var resp APIStatusResponse b, err := caller.CallPost(url, "/status", []string{}) if err != nil { return DEAD, map[string]int{} } json.Unmarshal(b, &resp) if resp.Data == nil { return DEAD, map[string]int{} } new := map[string]int{} for k, v := range resp.Data.Services { new[k] = ToState(v).EnumIndex() } return ToState(resp.Data.State), new } func (a *API) CheckRemoteAPIs(urls []string) (State, map[string]int, error) { // Check if the database is up new := map[string]int{} caller := NewHTTPCaller(map[string]map[METHOD]string{}) for _, url := range urls { var resp APIStatusResponse b, err := caller.CallGet(url, "/version/status") if err != nil { return REDUCED_SERVICE, new, err } json.Unmarshal(b, &resp) if resp.Data == nil { return DEAD, new, errors.New(url + " -> is DEAD") } for k, v := range resp.Data.Services { new[k] = ToState(v).EnumIndex() } if resp.Data.Code != 0 { return REDUCED_SERVICE, new, errors.New(url + " -> " + resp.Error) } } return ALIVE, new, nil } type APIStatusResponse struct { Data *APIStatus `json:"data"` Error string `json:"error"` } type APIStatus struct { Code int `json:"code"` State string `json:"state"` Services map[string]string `json:"services"` }