package productManager import ( "context" "time" "github.com/go-openapi/runtime/middleware" "github.com/prometheus/client_golang/prometheus" "github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/models" "github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/restapi/operations/product_management" "github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/server/dbManager" "github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/server/statusManager" l "gitlab.com/cyclops-utilities/logging" ) const ( statusDuplicated = iota statusFail statusMissing statusOK ) // ProductManager is the struct defined to group and contain all the methods // that interact with the product endpoint. // Parameters: // - db: a DbParameter reference to be able to use the DBManager methods. // - monit: a StatusManager reference to be able to use the status subsystem methods. // - BasePath: a string with the base path of the system. type ProductManager struct { db *dbManager.DbParameter monit *statusManager.StatusManager BasePath string } // New is the function to create the struct ProductManager that grant // access to the methods to interact with the Product endpoint. // Parameters: // - db: a reference to the DbParameter to be able to interact with the db methods. // - monit: a reference to the StatusManager to be able to interact with the // status subsystem. // - bp: a string containing the base path of the service. // Returns: // - ProductManager: struct to interact with product endpoint functionalities. func New(db *dbManager.DbParameter, monit *statusManager.StatusManager, bp string) *ProductManager { l.Trace.Printf("[ProductManager] Generating new ProductManager.\n") monit.InitEndpoint("product") return &ProductManager{ db: db, monit: monit, BasePath: bp, } } // AddProduct (Swagger func) is the function behind the (POST) API Endpoint // /product // Its function is to add the provided product into the db. func (m *ProductManager) AddProduct(ctx context.Context, params product_management.AddProductParams) middleware.Responder { l.Trace.Printf("[ProductManager] AddProduct endpoint invoked.\n") callTime := time.Now() m.monit.APIHit("product", callTime) id, productStatus := m.db.AddProduct(params.Product) switch productStatus { case statusOK: acceptedReturn := models.ItemCreatedResponse{ Message: "Product added to the system", APILink: m.BasePath + "/product/" + id, } m.db.Metrics["api"].With(prometheus.Labels{"code": "201", "method": "POST", "route": "/product"}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewAddProductCreated().WithPayload(&acceptedReturn) case statusFail: s := "It wasn't possible to insert the Product in the system." errorReturn := models.ErrorResponse{ ErrorString: &s, } m.db.Metrics["api"].With(prometheus.Labels{"code": "500", "method": "POST", "route": "/product"}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewAddProductInternalServerError().WithPayload(&errorReturn) } s := "The Product already exists in the system." conflictReturn := models.ErrorResponse{ ErrorString: &s, } m.db.Metrics["api"].With(prometheus.Labels{"code": "409", "method": "POST", "route": "/product"}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewAddProductConflict().WithPayload(&conflictReturn) } // GetProduct (Swagger func) is the function behind the (GET) API Endpoint // /product/{id} // Its function is to retrieve the information that the system has about the // product whose ID has been provided. func (m *ProductManager) GetProduct(ctx context.Context, params product_management.GetProductParams) middleware.Responder { l.Trace.Printf("[ProductManager] GetProduct endpoint invoked.\n") callTime := time.Now() m.monit.APIHit("product", callTime) product, e := m.db.GetProduct(params.ID) if e != nil { s := "There was an error retrieving the Product from the system: " + e.Error() errorReturn := models.ErrorResponse{ ErrorString: &s, } m.db.Metrics["api"].With(prometheus.Labels{"code": "500", "method": "POST", "route": "/product/" + params.ID}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewGetProductInternalServerError().WithPayload(&errorReturn) } if product != nil { m.db.Metrics["api"].With(prometheus.Labels{"code": "200", "method": "GET", "route": "/product/" + params.ID}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewGetProductOK().WithPayload(product) } s := "The Product doesn't exists in the system." missingReturn := models.ErrorResponse{ ErrorString: &s, } m.db.Metrics["api"].With(prometheus.Labels{"code": "404", "method": "GET", "route": "/product/" + params.ID}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewGetProductNotFound().WithPayload(&missingReturn) } // ListProducts (Swagger func) is the function behind the (GET) API Endpoint // /product // Its function is to provide a list containing all the products in the system. func (m *ProductManager) ListProducts(ctx context.Context, params product_management.ListProductsParams) middleware.Responder { l.Trace.Printf("[ProductManager] ListProducts endpoint invoked.\n") callTime := time.Now() m.monit.APIHit("product", callTime) products, e := m.db.ListProducts() if e != nil { s := "There was an error retrieving the Products from the system: " + e.Error() errorReturn := models.ErrorResponse{ ErrorString: &s, } m.db.Metrics["api"].With(prometheus.Labels{"code": "500", "method": "GET", "route": "/product"}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewListProductsInternalServerError().WithPayload(&errorReturn) } m.db.Metrics["api"].With(prometheus.Labels{"code": "200", "method": "GET", "route": "/product"}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewListProductsOK().WithPayload(products) } // UpdateProduct (Swagger func) is the function behind the (PUT) API Endpoint // /product/{id} // Its function is to update the product whose ID is provided with the new data. func (m *ProductManager) UpdateProduct(ctx context.Context, params product_management.UpdateProductParams) middleware.Responder { l.Trace.Printf("[ProductManager] UpdateProduct endpoint invoked.\n") callTime := time.Now() m.monit.APIHit("product", callTime) product := params.Product product.ProductID = params.ID switch productStatus := m.db.UpdateProduct(product); productStatus { case statusOK: acceptedReturn := models.ItemCreatedResponse{ Message: "Product updated in the system", APILink: m.BasePath + "/product/" + params.Product.ProductID, } m.db.Metrics["api"].With(prometheus.Labels{"code": "200", "method": "PUT", "route": "/product/" + params.ID}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewUpdateProductOK().WithPayload(&acceptedReturn) case statusFail: s := "It wasn't possible to update the product in the system." errorReturn := models.ErrorResponse{ ErrorString: &s, } m.db.Metrics["api"].With(prometheus.Labels{"code": "500", "method": "PUT", "route": "/product/" + params.ID}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewUpdateProductInternalServerError().WithPayload(&errorReturn) } s := "The Product doesn't exists in the system." missingReturn := models.ErrorResponse{ ErrorString: &s, } m.db.Metrics["api"].With(prometheus.Labels{"code": "404", "method": "PUT", "route": "/product/" + params.ID}).Inc() m.monit.APIHitDone("product", callTime) return product_management.NewUpdateProductNotFound().WithPayload(&missingReturn) }