/* * Micro Service * Package: gitlab.hexacode.org/go-libs/microservice * Maintainer: Azzis Arswendo * * Copyright (C) 2023 Hexacode Teknologi Indonesia * All Rights Reserved */ // Example: ./config.json // // ```json // // { // "namespace": "api-registration", // "server": { // "port": 8080 // }, // "templates": [ // { // "name": "registration", // "path": "/", // "file_path": "example/template.html" // } // ], // "apis": [ // { // "name": "registration", // "path": "/registration", // "method": "POST", // "content_type": "application/json", // "response_type": "application/json", // "callback": { // "plugin": "plugin.so", // "function": "Registration" // }, // "params": [ // { // "name": "username", // "label": "Username", // "placeholder": "Enter Username", // "type": "username", // "validate": "username", // "required": true, // "min": 5, // "max": 32 // }, // { // "name": "fullname", // "label": "Full Name", // "placeholder": "Enter Full Name", // "type": "name", // "validate": "name", // "required": true, // "min": 5, // "max": 32 // }, // { // "name": "email", // "label": "Email Address", // "placeholder": "Enter Email Address", // "type": "email", // "required": true, // "min": 5, // "max": 32 // }, // { // "name": "password", // "label": "Password", // "placeholder": "Enter Password", // "type": "password", // "required": true, // "min": 8, // "max": 120 // }, // { // "name": "confirm_password", // "label": "Confirm Password", // "placeholder": "Enter Confirm Password", // "type": "password", // "required": true, // "min": 8, // "max": 120 // } // ] // }, // { // "name": "verification", // "path": "/verification/:id/:otp", // "method": "GET", // "content_type": "application/json", // "response_type": "application/json", // "callback": { // "plugin": "plugin.so", // "function": "Verification" // }, // "url_params": [ // { // "name": "id", // "type": "textnumber", // "required": true // }, // { // "name": "otp", // "type": "textnumber", // "required": true // } // ] // } // ] // } // // ``` // // Example: main.go // // ```go // // package main // // import ( // "fmt" // // "gitlab.hexacode.org/go-libs/hctypes" // "gitlab.hexacode.org/go-libs/microservice/config" // ) // // func Registration(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) { // fmt.Println(ctx.Config.ToDict().ToColoredJson()) // fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson()) // fmt.Println(ctx.URLParams.ToColoredJson()) // fmt.Println(ctx.Params.ToColoredJson()) // fmt.Println(ctx.Headers.ToColoredJson()) // // return 200, hctypes.Dict{ // "id": 1, // "otp": 123456, // }, nil // } // // func Verification(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) { // fmt.Println(ctx.Config.ToDict().ToColoredJson()) // fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson()) // fmt.Println(ctx.URLParams.ToColoredJson()) // fmt.Println(ctx.Params.ToColoredJson()) // fmt.Println(ctx.Headers.ToColoredJson()) // // return 200, hctypes.Dict{ // "success": true, // "message": "OTP verified", // }, nil // } // // ``` package config import ( "encoding/json" "fmt" "os" "time" "github.com/gin-gonic/gin" "gitlab.hexacode.org/go-libs/hctypes" "gitlab.hexacode.org/go-libs/requests" ) type Config struct { Namespace string `json:"namespace,omitempty"` Server ConfigServer `json:"server,omitempty"` Templates []*ConfigTemplate `json:"templates,omitempty"` APIs []*ConfigAPI `json:"apis,omitempty"` Options hctypes.Dict `json:"options,omitempty"` source hctypes.Buffer `json:"-"` file string `json:"file,omitempty"` router *gin.Engine `json:"-"` } type ReturnError struct { Name string `json:"name,omitempty"` Errors interface{} `json:"errors,omitempty"` } func LoadConfig() (*Config, error) { var config *Config filePath := "./config.json" config = &Config{ Namespace: "default", Server: ConfigServer{ Port: 8080, }, APIs: []*ConfigAPI{}, } content, err := os.ReadFile(filePath) if err != nil { panic(err) return nil, err } config.file = filePath config.source = hctypes.Buffer(content) err = json.Unmarshal(content, &config) if err != nil { panic(err) return nil, err } return config, nil } func (config *Config) ForPublic() *Config { apis := []*ConfigAPI{} for _, api := range config.APIs { apis = append(apis, api.ForPublic()) } return &Config{ Namespace: config.Namespace, APIs: apis, } } // Example: ./config.json // // ```json // // { // "namespace": "api-registration", // "server": { // "port": 8080 // }, // "templates": [ // { // "name": "registration", // "path": "/", // "file_path": "example/template.html" // } // ], // "apis": [ // { // "name": "registration", // "path": "/registration", // "method": "POST", // "content_type": "application/json", // "response_type": "application/json", // "callback": { // "plugin": "plugin.so", // "function": "Registration" // }, // "params": [ // { // "name": "username", // "label": "Username", // "placeholder": "Enter Username", // "type": "username", // "validate": "username", // "required": true, // "min": 5, // "max": 32 // }, // { // "name": "fullname", // "label": "Full Name", // "placeholder": "Enter Full Name", // "type": "name", // "validate": "name", // "required": true, // "min": 5, // "max": 32 // }, // { // "name": "email", // "label": "Email Address", // "placeholder": "Enter Email Address", // "type": "email", // "required": true, // "min": 5, // "max": 32 // }, // { // "name": "password", // "label": "Password", // "placeholder": "Enter Password", // "type": "password", // "required": true, // "min": 8, // "max": 120 // }, // { // "name": "confirm_password", // "label": "Confirm Password", // "placeholder": "Enter Confirm Password", // "type": "password", // "required": true, // "min": 8, // "max": 120 // } // ] // }, // { // "name": "verification", // "path": "/verification/:id/:otp", // "method": "GET", // "content_type": "application/json", // "response_type": "application/json", // "callback": { // "plugin": "plugin.so", // "function": "Verification" // }, // "url_params": [ // { // "name": "id", // "type": "textnumber", // "required": true // }, // { // "name": "otp", // "type": "textnumber", // "required": true // } // ] // } // ] // } // // ``` // // Example: main.go // // ```go // // package main // // import ( // "fmt" // // "gitlab.hexacode.org/go-libs/hctypes" // "gitlab.hexacode.org/go-libs/microservice/config" // ) // // func Registration(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) { // fmt.Println(ctx.Config.ToDict().ToColoredJson()) // fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson()) // fmt.Println(ctx.URLParams.ToColoredJson()) // fmt.Println(ctx.Params.ToColoredJson()) // fmt.Println(ctx.Headers.ToColoredJson()) // // return 200, hctypes.Dict{ // "id": 1, // "otp": 123456, // }, nil // } // // func Verification(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) { // fmt.Println(ctx.Config.ToDict().ToColoredJson()) // fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson()) // fmt.Println(ctx.URLParams.ToColoredJson()) // fmt.Println(ctx.Params.ToColoredJson()) // fmt.Println(ctx.Headers.ToColoredJson()) // // return 200, hctypes.Dict{ // "success": true, // "message": "OTP verified", // }, nil // } // // ``` func (config *Config) Run() { err := config.LoadPlugin() if err != nil { panic(err) } config.router = gin.Default() optionses_urls := map[string]bool{} set_options := func(path string, handler func(*gin.Context)) { if _, ok := optionses_urls[path]; ok { return } optionses_urls[path] = true config.router.OPTIONS(path, handler) } if config.Templates != nil { config.router.Static("/"+config.Namespace+"/public", "public") for _, template := range config.Templates { config.router.GET(fmt.Sprintf("%s%s", config.Namespace, template.Path), template.HTTPHandler) set_options(fmt.Sprintf("%s%s", config.Namespace, template.Path), options_handler) } } if config.APIs != nil { for _, api := range config.APIs { api.config = config config.router.Handle(api.Method, fmt.Sprintf("%s%s", config.Namespace, api.Path), api.HTTPHandler) config.router.GET(fmt.Sprintf("%s/config/%s", config.Namespace, api.Name), api.HTTPHandlerConfig) set_options(fmt.Sprintf("%s%s", config.Namespace, api.Path), options_handler) set_options(fmt.Sprintf("%s/config/%s", config.Namespace, api.Name), options_handler) } } config.router.GET(fmt.Sprintf("%s/health", config.Namespace), func(c *gin.Context) { c.String(200, "OK") }) config.router.GET(fmt.Sprintf("%s/configs", config.Namespace), func(c *gin.Context) { c.JSON(200, config.ForPublic()) }) set_options(fmt.Sprintf("%s/health", config.Namespace), options_handler) set_options(fmt.Sprintf("%s/configs", config.Namespace), options_handler) config.router.NoRoute(func(c *gin.Context) { c.JSON(404, &ReturnHTTPError{ StatusCode: 404, Errors: []*ReturnError{ { Name: "not_found", Errors: "Not Found", }, }, }) }) config.router.Run(fmt.Sprintf("0.0.0.0:%d", config.Server.Port)) } func (config *Config) ToDict() hctypes.Dict { return hctypes.NewDictFromJson(config.source) } // Schedule for monitoring the module // // Parameters: // // host - the host address // module_manager_url - the URL of the module manager func Schedule(host string, module_manager_url string) { go func(host_ string, module_manager_url_ string) { cfg, err := LoadConfig() if err != nil { return } port := cfg.Server.Port port_i := port if port_i == 0 { return } http := requests.NewHttp(hctypes.Dict{ "Content-Type": "application/json", }) cfg_s := cfg.ToDict().ToJson().ToString() param := hctypes.Dict{ "config": cfg_s, "host": host_, "port": port_i, } for { http.Post(fmt.Sprintf("%s/module-manager/monitoring", module_manager_url_), nil, param.ToJson()) fmt.Println("Monitoring") time.Sleep(time.Minute) } }(host, module_manager_url) }