467 lines
15 KiB
Go
467 lines
15 KiB
Go
package oclib
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"runtime/debug"
|
|
|
|
"cloud.o-forge.io/core/oc-lib/config"
|
|
"cloud.o-forge.io/core/oc-lib/dbs"
|
|
"cloud.o-forge.io/core/oc-lib/dbs/mongo"
|
|
"cloud.o-forge.io/core/oc-lib/logs"
|
|
"cloud.o-forge.io/core/oc-lib/models"
|
|
"cloud.o-forge.io/core/oc-lib/models/peer"
|
|
"cloud.o-forge.io/core/oc-lib/models/resource_model"
|
|
"cloud.o-forge.io/core/oc-lib/models/resources/data"
|
|
"cloud.o-forge.io/core/oc-lib/models/resources/datacenter"
|
|
"cloud.o-forge.io/core/oc-lib/models/resources/processing"
|
|
"cloud.o-forge.io/core/oc-lib/models/resources/storage"
|
|
w "cloud.o-forge.io/core/oc-lib/models/resources/workflow"
|
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
|
w2 "cloud.o-forge.io/core/oc-lib/models/workflow"
|
|
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
|
|
"cloud.o-forge.io/core/oc-lib/models/workspace"
|
|
shared_workspace "cloud.o-forge.io/core/oc-lib/models/workspace/shared"
|
|
"cloud.o-forge.io/core/oc-lib/models/workspace/shared/rules/rule"
|
|
"cloud.o-forge.io/core/oc-lib/tools"
|
|
"github.com/goraz/onion"
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
type Filters = dbs.Filters
|
|
|
|
type LibDataEnum int
|
|
|
|
// init accessible constant to retrieve data from the database
|
|
const (
|
|
INVALID LibDataEnum = iota
|
|
DATA_RESOURCE = utils.DATA_RESOURCE
|
|
PROCESSING_RESOURCE = utils.PROCESSING_RESOURCE
|
|
STORAGE_RESOURCE = utils.STORAGE_RESOURCE
|
|
DATACENTER_RESOURCE = utils.DATACENTER_RESOURCE
|
|
WORKFLOW_RESOURCE = utils.WORKFLOW_RESOURCE
|
|
WORKFLOW = utils.WORKFLOW
|
|
WORKSPACE = utils.WORKSPACE
|
|
WORKFLOW_EXECUTION = utils.WORKFLOW_EXECUTION
|
|
PEER = utils.PEER
|
|
SHARED_WORKSPACE = utils.SHARED_WORKSPACE
|
|
RULE = utils.RULE
|
|
BOOKING = utils.BOOKING
|
|
)
|
|
|
|
// will turn into standards api hostnames
|
|
func (d LibDataEnum) API() string {
|
|
return utils.DefaultAPI[d]
|
|
}
|
|
|
|
// will turn into standards name
|
|
func (d LibDataEnum) String() string {
|
|
return utils.Str[d]
|
|
}
|
|
|
|
// will turn into enum index
|
|
func (d LibDataEnum) EnumIndex() int {
|
|
return int(d)
|
|
}
|
|
|
|
// model to define the shallow data structure
|
|
type LibDataShallow struct {
|
|
Data []utils.ShallowDBObject `bson:"data" json:"data"`
|
|
Code int `bson:"code" json:"code"`
|
|
Err string `bson:"error" json:"error"`
|
|
}
|
|
|
|
// model to define the data structure
|
|
type LibData struct {
|
|
Data utils.DBObject `bson:"data" json:"data"`
|
|
Code int `bson:"code" json:"code"`
|
|
Err string `bson:"error" json:"error"`
|
|
}
|
|
|
|
// here is the singleton variable to store the paths that api will use
|
|
var paths map[LibDataEnum]string = map[LibDataEnum]string{}
|
|
|
|
// to get the paths
|
|
func GetPaths() map[LibDataEnum]string {
|
|
return paths
|
|
}
|
|
|
|
// to get the path
|
|
func GetPath(collection LibDataEnum) string {
|
|
return paths[collection]
|
|
}
|
|
|
|
// to add the path
|
|
func AddPath(collection LibDataEnum, path string) {
|
|
paths[collection] = path
|
|
}
|
|
|
|
func Init(appName string) {
|
|
config.SetAppName(appName) // set the app name to the logger to define the main log chan
|
|
// create a temporary console logger for init
|
|
logs.SetLogger(logs.CreateLogger("main"))
|
|
|
|
}
|
|
|
|
//
|
|
// Expose subpackages
|
|
//
|
|
|
|
/* GetLogger returns the main logger
|
|
* @return zerolog.Logger
|
|
*/
|
|
func GetLogger() zerolog.Logger {
|
|
return logs.GetLogger()
|
|
}
|
|
|
|
/* SetConfig will set the config and create a logger according to app configuration and initialize mongo accessor
|
|
* @param url string
|
|
* @param database string
|
|
* @param natsUrl string
|
|
* @param lokiUrl string
|
|
* @param logLevel string
|
|
* @return *Config
|
|
*/
|
|
func SetConfig(mongoUrl string, database string, natsUrl string, lokiUrl string, logLevel string) *config.Config {
|
|
cfg := config.SetConfig(mongoUrl, database, natsUrl, lokiUrl, logLevel)
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in Init : "+fmt.Sprintf("%v", r)+" - "+string(debug.Stack())))
|
|
fmt.Printf("Panic recovered in Init : %v - %v\n", r, string(debug.Stack()))
|
|
}
|
|
}()
|
|
logs.CreateLogger("main")
|
|
mongo.MONGOService.Init(models.GetModelsNames(), config.GetConfig()) // init the mongo service
|
|
/*
|
|
Here we will check if the resource model is already stored in the database
|
|
If not we will store it
|
|
Resource model is the model that will define the structure of the resources
|
|
*/
|
|
accessor := (&resource_model.ResourceModel{}).GetAccessor(nil)
|
|
for _, model := range []string{utils.DATA_RESOURCE.String(), utils.PROCESSING_RESOURCE.String(), utils.STORAGE_RESOURCE.String(), utils.DATACENTER_RESOURCE.String(), utils.WORKFLOW_RESOURCE.String()} {
|
|
data, code, _ := accessor.Search(nil, model)
|
|
if code == 404 || len(data) == 0 {
|
|
m := map[string]resource_model.Model{}
|
|
// TODO Specify the model for each resource
|
|
// for now only processing is specified here (not an elegant way)
|
|
if model == utils.PROCESSING_RESOURCE.String() {
|
|
m["image"] = resource_model.Model{
|
|
Type: "string",
|
|
ReadOnly: false,
|
|
}
|
|
m["command"] = resource_model.Model{
|
|
Type: "string",
|
|
ReadOnly: false,
|
|
}
|
|
m["args"] = resource_model.Model{
|
|
Type: "string",
|
|
ReadOnly: false,
|
|
}
|
|
m["execute"] = resource_model.Model{
|
|
Type: "map[int]map[string]string",
|
|
ReadOnly: false,
|
|
}
|
|
}
|
|
accessor.StoreOne(&resource_model.ResourceModel{
|
|
ResourceType: model,
|
|
Model: m,
|
|
})
|
|
}
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
/* GetConfig will get the config
|
|
* @return *Config
|
|
*/
|
|
func GetConfig() *config.Config {
|
|
return config.GetConfig()
|
|
}
|
|
|
|
/* GetConfLoader
|
|
* Get the configuration loader for the application
|
|
* Parameters:
|
|
* - AppName: string : the name of the application
|
|
* Returns:
|
|
* - *onion.Onion : the configuration loader
|
|
* The configuration loader will load the configuration from the following sources:
|
|
* - the environment variables with the prefix OCAPPNAME_
|
|
* - the file /etc/oc/appname.json
|
|
* - the file ./appname.json
|
|
* The configuration loader will merge the configuration from the different sources
|
|
* The configuration loader will give priority to the environment variables
|
|
* The configuration loader will give priority to the local file over the default file
|
|
*/
|
|
|
|
func GetConfLoader() *onion.Onion {
|
|
return config.GetConfLoader()
|
|
}
|
|
|
|
/*
|
|
* Search will search for the data in the database
|
|
* @param filters *dbs.Filters
|
|
* @param word string
|
|
* @param collection LibDataEnum
|
|
* @param c ...*tools.HTTPCaller
|
|
* @return data LibDataShallow
|
|
*/
|
|
func Search(filters *dbs.Filters, word string, collection LibDataEnum, c ...*tools.HTTPCaller) (data LibDataShallow) {
|
|
defer func() { // recover the panic
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in Search : "+fmt.Sprintf("%v", r)))
|
|
data = LibDataShallow{Data: nil, Code: 500, Err: "Panic recovered in LoadAll : " + fmt.Sprintf("%v", r) + " - " + string(debug.Stack())}
|
|
}
|
|
}()
|
|
var caller *tools.HTTPCaller // define the caller
|
|
if len(c) > 0 {
|
|
caller = c[0]
|
|
}
|
|
d, code, err := models.Model(collection.EnumIndex()).GetAccessor(caller).Search(filters, word)
|
|
if err != nil {
|
|
data = LibDataShallow{Data: d, Code: code, Err: err.Error()}
|
|
return
|
|
}
|
|
data = LibDataShallow{Data: d, Code: code}
|
|
return
|
|
}
|
|
|
|
/*
|
|
* LoadAll will load all the data from the database
|
|
* @param collection LibDataEnum
|
|
* @param c ...*tools.HTTPCaller
|
|
* @return data LibDataShallow
|
|
*/
|
|
func LoadAll(collection LibDataEnum, c ...*tools.HTTPCaller) (data LibDataShallow) {
|
|
defer func() { // recover the panic
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in LoadAll : "+fmt.Sprintf("%v", r)+" - "+string(debug.Stack())))
|
|
data = LibDataShallow{Data: nil, Code: 500, Err: "Panic recovered in LoadAll : " + fmt.Sprintf("%v", r) + " - " + string(debug.Stack())}
|
|
}
|
|
}()
|
|
var caller *tools.HTTPCaller // define the caller
|
|
if len(c) > 0 {
|
|
caller = c[0]
|
|
}
|
|
d, code, err := models.Model(collection.EnumIndex()).GetAccessor(caller).LoadAll()
|
|
if err != nil {
|
|
data = LibDataShallow{Data: d, Code: code, Err: err.Error()}
|
|
return
|
|
}
|
|
data = LibDataShallow{Data: d, Code: code}
|
|
return
|
|
}
|
|
|
|
/*
|
|
* LoadOne will load one data from the database
|
|
* @param collection LibDataEnum
|
|
* @param id string
|
|
* @param c ...*tools.HTTPCaller
|
|
* @return data LibData
|
|
*/
|
|
func LoadOne(collection LibDataEnum, id string, c ...*tools.HTTPCaller) (data LibData) {
|
|
defer func() { // recover the panic
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in LoadOne : "+fmt.Sprintf("%v", r)+" - "+string(debug.Stack())))
|
|
data = LibData{Data: nil, Code: 500, Err: "Panic recovered in LoadOne : " + fmt.Sprintf("%v", r) + " - " + string(debug.Stack())}
|
|
}
|
|
}()
|
|
var caller *tools.HTTPCaller // define the caller
|
|
if len(c) > 0 {
|
|
caller = c[0]
|
|
}
|
|
d, code, err := models.Model(collection.EnumIndex()).GetAccessor(caller).LoadOne(id)
|
|
if err != nil {
|
|
data = LibData{Data: d, Code: code, Err: err.Error()}
|
|
return
|
|
}
|
|
data = LibData{Data: d, Code: code}
|
|
return
|
|
}
|
|
|
|
/*
|
|
* UpdateOne will update one data from the database
|
|
* @param collection LibDataEnum
|
|
* @param set map[string]interface{}
|
|
* @param id string
|
|
* @param c ...*tools.HTTPCaller
|
|
* @return data LibData
|
|
*/
|
|
func UpdateOne(collection LibDataEnum, set map[string]interface{}, id string, c ...*tools.HTTPCaller) (data LibData) {
|
|
defer func() { // recover the panic
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in UpdateOne : "+fmt.Sprintf("%v", r)+" - "+string(debug.Stack())))
|
|
data = LibData{Data: nil, Code: 500, Err: "Panic recovered in UpdateOne : " + fmt.Sprintf("%v", r) + " - " + string(debug.Stack())}
|
|
}
|
|
}()
|
|
var caller *tools.HTTPCaller // define the caller
|
|
if len(c) > 0 {
|
|
caller = c[0]
|
|
}
|
|
model := models.Model(collection.EnumIndex())
|
|
d, code, err := model.GetAccessor(caller).UpdateOne(model.Deserialize(set), id)
|
|
if err != nil {
|
|
data = LibData{Data: d, Code: code, Err: err.Error()}
|
|
return
|
|
}
|
|
data = LibData{Data: d, Code: code}
|
|
return
|
|
}
|
|
|
|
/*
|
|
* DeleteOne will delete one data from the database
|
|
* @param collection LibDataEnum
|
|
* @param id string
|
|
* @param c ...*tools.HTTPCaller
|
|
* @return data LibData
|
|
*/
|
|
func DeleteOne(collection LibDataEnum, id string, c ...*tools.HTTPCaller) (data LibData) {
|
|
defer func() { // recover the panic
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in DeleteOne : "+fmt.Sprintf("%v", r)+" - "+string(debug.Stack())))
|
|
data = LibData{Data: nil, Code: 500, Err: "Panic recovered in DeleteOne : " + fmt.Sprintf("%v", r) + " - " + string(debug.Stack())}
|
|
}
|
|
}()
|
|
var caller *tools.HTTPCaller // define the caller
|
|
if len(c) > 0 {
|
|
caller = c[0]
|
|
}
|
|
d, code, err := models.Model(collection.EnumIndex()).GetAccessor(caller).DeleteOne(id)
|
|
if err != nil {
|
|
data = LibData{Data: d, Code: code, Err: err.Error()}
|
|
return
|
|
}
|
|
data = LibData{Data: d, Code: code}
|
|
return
|
|
}
|
|
|
|
/*
|
|
* StoreOne will store one data from the database
|
|
* @param collection LibDataEnum
|
|
* @param object map[string]interface{}
|
|
* @param c ...*tools.HTTPCaller
|
|
* @return data LibData
|
|
*/
|
|
func StoreOne(collection LibDataEnum, object map[string]interface{}, c ...*tools.HTTPCaller) (data LibData) {
|
|
defer func() { // recover the panic
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in StoreOne : "+fmt.Sprintf("%v", r)+" - "+string(debug.Stack())))
|
|
data = LibData{Data: nil, Code: 500, Err: "Panic recovered in StoreOne : " + fmt.Sprintf("%v", r) + " - " + string(debug.Stack())}
|
|
}
|
|
}()
|
|
var caller *tools.HTTPCaller // define the caller
|
|
if len(c) > 0 {
|
|
caller = c[0]
|
|
}
|
|
model := models.Model(collection.EnumIndex())
|
|
d, code, err := model.GetAccessor(caller).StoreOne(model.Deserialize(object))
|
|
if err != nil {
|
|
data = LibData{Data: d, Code: code, Err: err.Error()}
|
|
return
|
|
}
|
|
data = LibData{Data: d, Code: code}
|
|
return
|
|
}
|
|
|
|
/*
|
|
* CopyOne will copy one data from the database
|
|
* @param collection LibDataEnum
|
|
* @param object map[string]interface{}
|
|
* @param c ...*tools.HTTPCaller
|
|
* @return data LibData
|
|
*/
|
|
func CopyOne(collection LibDataEnum, object map[string]interface{}, c ...*tools.HTTPCaller) (data LibData) {
|
|
defer func() { // recover the panic
|
|
if r := recover(); r != nil {
|
|
tools.UncatchedError = append(tools.UncatchedError, errors.New("Panic recovered in CopyOne : "+fmt.Sprintf("%v", r)+" - "+string(debug.Stack())))
|
|
data = LibData{Data: nil, Code: 500, Err: "Panic recovered in UpdateOne : " + fmt.Sprintf("%v", r) + " - " + string(debug.Stack())}
|
|
}
|
|
}()
|
|
var caller *tools.HTTPCaller // define the caller
|
|
if len(c) > 0 {
|
|
caller = c[0]
|
|
}
|
|
model := models.Model(collection.EnumIndex())
|
|
d, code, err := model.GetAccessor(caller).CopyOne(model.Deserialize(object))
|
|
if err != nil {
|
|
data = LibData{Data: d, Code: code, Err: err.Error()}
|
|
return
|
|
}
|
|
data = LibData{Data: d, Code: code}
|
|
return
|
|
}
|
|
|
|
// ================ CAST ========================= //
|
|
|
|
func (l *LibData) ToDataResource() *data.DataResource {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.DATA_RESOURCE.String() {
|
|
return l.Data.(*data.DataResource)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *LibData) ToDatacenterResource() *datacenter.DatacenterResource {
|
|
if l.Data != nil && l.Data.GetAccessor(nil).GetType() == utils.DATACENTER_RESOURCE.String() {
|
|
return l.Data.(*datacenter.DatacenterResource)
|
|
}
|
|
return nil
|
|
}
|
|
func (l *LibData) ToStorageResource() *storage.StorageResource {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.STORAGE_RESOURCE.String() {
|
|
return l.Data.(*storage.StorageResource)
|
|
}
|
|
return nil
|
|
}
|
|
func (l *LibData) ToProcessingResource() *processing.ProcessingResource {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.PROCESSING_RESOURCE.String() {
|
|
return l.Data.(*processing.ProcessingResource)
|
|
}
|
|
return nil
|
|
}
|
|
func (l *LibData) ToWorkflowResource() *w.WorkflowResource {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.WORKFLOW_RESOURCE.String() {
|
|
return l.Data.(*w.WorkflowResource)
|
|
}
|
|
return nil
|
|
}
|
|
func (l *LibData) ToPeer() *peer.Peer {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.PEER.String() {
|
|
return l.Data.(*peer.Peer)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *LibData) ToWorkflow() *w2.Workflow {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.WORKFLOW.String() {
|
|
return l.Data.(*w2.Workflow)
|
|
}
|
|
return nil
|
|
}
|
|
func (l *LibData) ToWorkspace() *workspace.Workspace {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.WORKSPACE.String() {
|
|
return l.Data.(*workspace.Workspace)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *LibData) ToSharedWorkspace() *shared_workspace.SharedWorkspace {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.SHARED_WORKSPACE.String() {
|
|
return l.Data.(*shared_workspace.SharedWorkspace)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *LibData) ToRule() *rule.Rule {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.SHARED_WORKSPACE.String() {
|
|
return l.Data.(*rule.Rule)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *LibData) ToWorkflowExecution() *workflow_execution.WorkflowExecution {
|
|
if l.Data.GetAccessor(nil).GetType() == utils.WORKFLOW_EXECUTION.String() {
|
|
return l.Data.(*workflow_execution.WorkflowExecution)
|
|
}
|
|
return nil
|
|
}
|