From c5f45e03f36594c38e73b57de4219c654b3c33d4 Mon Sep 17 00:00:00 2001 From: mr Date: Wed, 21 Aug 2024 10:58:24 +0200 Subject: [PATCH] State of an API with OClib :D --- dbs/mongo/mongo.go | 52 +++++++++++++++++++++++++++++++++------------- tools/api.go | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 tools/api.go diff --git a/dbs/mongo/mongo.go b/dbs/mongo/mongo.go index d727294..e8644c2 100644 --- a/dbs/mongo/mongo.go +++ b/dbs/mongo/mongo.go @@ -3,6 +3,7 @@ package mongo import ( "context" "errors" + "slices" "time" "cloud.o-forge.io/core/oc-lib/dbs" @@ -47,12 +48,36 @@ func (m *MongoDB) Init(collections []string, config MongoConf) { m.Logger.Info().Msg("Connecting to" + config.GetUrl()) mngoCollections = collections mngoConfig = config - if err := m.createClient(config.GetUrl()); err != nil { + if err := m.createClient(config.GetUrl(), false); err != nil { m.Logger.Error().Msg(err.Error()) } } -func (m *MongoDB) createClient(MongoURL string) error { +func (m *MongoDB) TestDB(config MongoConf) error { + err := m.createClient(config.GetUrl(), true) + if err != nil { + return err + } + return nil +} +func (m *MongoDB) TestCollections(config MongoConf, neededCols []string) error { + mngoDB = mngoClient.Database(config.GetDatabase()) + MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + existingCollections, err := mngoDB.ListCollectionNames(MngoCtx, bson.D{}) + if err != nil { + return errors.New("Error contacting MongoDB\n" + err.Error()) + } + for _, col := range neededCols { + if slices.Contains(existingCollections, col) { + continue + } + return errors.New("Collection " + col + " not found") + } + return nil +} + +func (m *MongoDB) createClient(MongoURL string, test bool) error { if mngoClient != nil { return nil } @@ -72,7 +97,7 @@ func (m *MongoDB) createClient(MongoURL string) error { isConnected = false return errors.New("Mongodb connect " + MongoURL + ":" + err.Error()) } - MngoCtx, cancel = context.WithTimeout(context.Background(), 60*time.Second) + MngoCtx, cancel = context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err = mngoClient.Ping(MngoCtx, nil); err != nil { @@ -80,12 +105,11 @@ func (m *MongoDB) createClient(MongoURL string) error { isConnected = false return errors.New("Mongodb ping " + MongoURL + ":" + err.Error()) } - if !isConnected && mngoClient != nil { + if !isConnected && mngoClient != nil && !test { m.Logger.Info().Msg("Connecting mongo client to db " + mngoConfig.GetDatabase()) m.prepareDB(mngoCollections, mngoConfig) m.Logger.Info().Msg("Database is READY") } - return nil } @@ -145,7 +169,7 @@ func (m *MongoDB) createCollection(collection_name string, new_collection *mongo } func (m *MongoDB) DeleteOne(id string, collection_name string) (int64, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return 0, 503, err } filter := bson.M{"_id": id} @@ -163,7 +187,7 @@ func (m *MongoDB) DeleteOne(id string, collection_name string) (int64, int, erro } func (m *MongoDB) DeleteMultiple(f map[string]interface{}, collection_name string) (int64, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return 0, 503, err } filter := bson.D{} @@ -184,7 +208,7 @@ func (m *MongoDB) DeleteMultiple(f map[string]interface{}, collection_name strin } func (m *MongoDB) UpdateMultiple(set interface{}, filter map[string]interface{}, collection_name string) (int64, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return 0, 503, err } var doc map[string]interface{} @@ -206,7 +230,7 @@ func (m *MongoDB) UpdateMultiple(set interface{}, filter map[string]interface{}, } func (m *MongoDB) UpdateOne(set interface{}, id string, collection_name string) (string, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return "", 503, err } var doc map[string]interface{} @@ -225,7 +249,7 @@ func (m *MongoDB) UpdateOne(set interface{}, id string, collection_name string) } func (m *MongoDB) StoreOne(obj interface{}, id string, collection_name string) (string, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return "", 503, err } var doc map[string]interface{} @@ -246,7 +270,7 @@ func (m *MongoDB) StoreOne(obj interface{}, id string, collection_name string) ( } func (m *MongoDB) LoadOne(id string, collection_name string) (*mongo.SingleResult, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return nil, 503, err } filter := bson.M{"_id": id} @@ -265,7 +289,7 @@ func (m *MongoDB) LoadOne(id string, collection_name string) (*mongo.SingleResul } func (m *MongoDB) Search(filters *dbs.Filters, collection_name string) (*mongo.Cursor, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return nil, 503, err } opts := options.Find() @@ -309,7 +333,7 @@ func (m *MongoDB) Search(filters *dbs.Filters, collection_name string) (*mongo.C } func (m *MongoDB) LoadFilter(filter map[string]interface{}, collection_name string) (*mongo.Cursor, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return nil, 503, err } f := bson.D{} @@ -330,7 +354,7 @@ func (m *MongoDB) LoadFilter(filter map[string]interface{}, collection_name stri } func (m *MongoDB) LoadAll(collection_name string) (*mongo.Cursor, int, error) { - if err := m.createClient(mngoConfig.GetUrl()); err != nil { + if err := m.createClient(mngoConfig.GetUrl(), false); err != nil { return nil, 503, err } targetDBCollection := CollectionMap[collection_name] diff --git a/tools/api.go b/tools/api.go new file mode 100644 index 0000000..a9027f3 --- /dev/null +++ b/tools/api.go @@ -0,0 +1,41 @@ +package tools + +import ( + "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 +) + +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"}[s] +} + +type API struct{} + +func (a *API) GetState() State { + // Check if the database is up + err := mongo.MONGOService.TestDB(GetConfig()) + if err != nil { + return DB_FALLOUT + } + err = mongo.MONGOService.TestCollections(GetConfig(), []string{}) + if err != nil { + return UNPROCESSABLE_ENTITY + } + if len(UncatchedError) > 0 { + return TEAPOT + } + return ALIVE +}