465 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			465 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"
 | |
| 	collaborative_area "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.COLLABORATIVE_AREA
 | |
| 	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["command"] = resource_model.Model{
 | |
| 					Type:     "string",
 | |
| 					ReadOnly: false,
 | |
| 				}
 | |
| 				m["args"] = resource_model.Model{
 | |
| 					Type:     "string",
 | |
| 					ReadOnly: false,
 | |
| 				}
 | |
| 				m["env"] = resource_model.Model{
 | |
| 					Type:     "string",
 | |
| 					ReadOnly: false,
 | |
| 				}
 | |
| 			}
 | |
| 			accessor.StoreOne(&resource_model.ResourceModel{
 | |
| 				ResourceType: model,
 | |
| 				Model: map[string]map[string]resource_model.Model{
 | |
| 					"container": 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) ToCollaborativeArea() *collaborative_area.CollaborativeArea {
 | |
| 	if l.Data.GetAccessor(nil).GetType() == utils.COLLABORATIVE_AREA.String() {
 | |
| 		return l.Data.(*collaborative_area.CollaborativeArea)
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (l *LibData) ToRule() *rule.Rule {
 | |
| 	if l.Data.GetAccessor(nil).GetType() == utils.COLLABORATIVE_AREA.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
 | |
| }
 |