...

Source file src/gitlab.hexacode.org/go-libs/microservice/config/config.go

Documentation: gitlab.hexacode.org/go-libs/microservice/config

     1  /*
     2   * Micro Service
     3   * Package: gitlab.hexacode.org/go-libs/microservice
     4   * Maintainer: Azzis Arswendo <azzis@hexacode.org>
     5   *
     6   * Copyright (C) 2023 Hexacode Teknologi Indonesia
     7   * All Rights Reserved
     8   */
     9  
    10  // Example: ./config.json
    11  //
    12  // ```json
    13  //
    14  //	{
    15  //	    "namespace": "api-registration",
    16  //	    "server": {
    17  //	        "port": 8080
    18  //	    },
    19  //		"templates": [
    20  //			{
    21  //				"name": "registration",
    22  //				"path": "/",
    23  //				"file_path": "example/template.html"
    24  //			}
    25  //		],
    26  //	    "apis": [
    27  //	        {
    28  //	            "name": "registration",
    29  //	            "path": "/registration",
    30  //	            "method": "POST",
    31  //	            "content_type": "application/json",
    32  //	            "response_type": "application/json",
    33  //	            "callback": {
    34  //	                "plugin": "plugin.so",
    35  //	                "function": "Registration"
    36  //	            },
    37  //	            "params": [
    38  //	                {
    39  //	                    "name": "username",
    40  //	                    "label": "Username",
    41  //	                    "placeholder": "Enter Username",
    42  //	                    "type": "username",
    43  //	                    "validate": "username",
    44  //	                    "required": true,
    45  //	                    "min": 5,
    46  //	                    "max": 32
    47  //	                },
    48  //	                {
    49  //	                    "name": "fullname",
    50  //	                    "label": "Full Name",
    51  //	                    "placeholder": "Enter Full Name",
    52  //	                    "type": "name",
    53  //	                    "validate": "name",
    54  //	                    "required": true,
    55  //	                    "min": 5,
    56  //	                    "max": 32
    57  //	                },
    58  //	                {
    59  //	                    "name": "email",
    60  //	                    "label": "Email Address",
    61  //	                    "placeholder": "Enter Email Address",
    62  //	                    "type": "email",
    63  //	                    "required": true,
    64  //	                    "min": 5,
    65  //	                    "max": 32
    66  //	                },
    67  //	                {
    68  //	                    "name": "password",
    69  //	                    "label": "Password",
    70  //	                    "placeholder": "Enter Password",
    71  //	                    "type": "password",
    72  //	                    "required": true,
    73  //	                    "min": 8,
    74  //	                    "max": 120
    75  //	                },
    76  //	                {
    77  //	                    "name": "confirm_password",
    78  //	                    "label": "Confirm Password",
    79  //	                    "placeholder": "Enter Confirm Password",
    80  //	                    "type": "password",
    81  //	                    "required": true,
    82  //	                    "min": 8,
    83  //	                    "max": 120
    84  //	                }
    85  //	            ]
    86  //	        },
    87  //	        {
    88  //	            "name": "verification",
    89  //	            "path": "/verification/:id/:otp",
    90  //	            "method": "GET",
    91  //	            "content_type": "application/json",
    92  //	            "response_type": "application/json",
    93  //	            "callback": {
    94  //	                "plugin": "plugin.so",
    95  //	                "function": "Verification"
    96  //	            },
    97  //	            "url_params": [
    98  //	                {
    99  //	                    "name": "id",
   100  //	                    "type": "textnumber",
   101  //	                    "required": true
   102  //	                },
   103  //	                {
   104  //	                    "name": "otp",
   105  //	                    "type": "textnumber",
   106  //	                    "required": true
   107  //	                }
   108  //	            ]
   109  //	        }
   110  //	    ]
   111  //	}
   112  //
   113  // ```
   114  //
   115  // Example: main.go
   116  //
   117  // ```go
   118  //
   119  //	package main
   120  //
   121  //	import (
   122  //	  "fmt"
   123  //
   124  //	  "gitlab.hexacode.org/go-libs/hctypes"
   125  //	  "gitlab.hexacode.org/go-libs/microservice/config"
   126  //	)
   127  //
   128  //	func Registration(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) {
   129  //	  fmt.Println(ctx.Config.ToDict().ToColoredJson())
   130  //	  fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson())
   131  //	  fmt.Println(ctx.URLParams.ToColoredJson())
   132  //	  fmt.Println(ctx.Params.ToColoredJson())
   133  //	  fmt.Println(ctx.Headers.ToColoredJson())
   134  //
   135  //	  return 200, hctypes.Dict{
   136  //	    "id":  1,
   137  //	    "otp": 123456,
   138  //	  }, nil
   139  //	}
   140  //
   141  //	func Verification(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) {
   142  //	  fmt.Println(ctx.Config.ToDict().ToColoredJson())
   143  //	  fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson())
   144  //	  fmt.Println(ctx.URLParams.ToColoredJson())
   145  //	  fmt.Println(ctx.Params.ToColoredJson())
   146  //	  fmt.Println(ctx.Headers.ToColoredJson())
   147  //
   148  //	  return 200, hctypes.Dict{
   149  //	    "success": true,
   150  //	    "message": "OTP verified",
   151  //	  }, nil
   152  //	}
   153  //
   154  // ```
   155  
   156  package config
   157  
   158  import (
   159  	"encoding/json"
   160  	"fmt"
   161  	"os"
   162  	"time"
   163  
   164  	"github.com/gin-gonic/gin"
   165  	"gitlab.hexacode.org/go-libs/hctypes"
   166  	"gitlab.hexacode.org/go-libs/requests"
   167  )
   168  
   169  type Config struct {
   170  	Namespace string            `json:"namespace,omitempty"`
   171  	Server    ConfigServer      `json:"server,omitempty"`
   172  	Templates []*ConfigTemplate `json:"templates,omitempty"`
   173  	APIs      []*ConfigAPI      `json:"apis,omitempty"`
   174  	Options   hctypes.Dict      `json:"options,omitempty"`
   175  	source    hctypes.Buffer    `json:"-"`
   176  	file      string            `json:"file,omitempty"`
   177  	router    *gin.Engine       `json:"-"`
   178  }
   179  
   180  type ReturnError struct {
   181  	Name   string      `json:"name,omitempty"`
   182  	Errors interface{} `json:"errors,omitempty"`
   183  }
   184  
   185  func LoadConfig() (*Config, error) {
   186  	var config *Config
   187  
   188  	filePath := "./config.json"
   189  	config = &Config{
   190  		Namespace: "default",
   191  		Server: ConfigServer{
   192  			Port: 8080,
   193  		},
   194  		APIs: []*ConfigAPI{},
   195  	}
   196  
   197  	content, err := os.ReadFile(filePath)
   198  	if err != nil {
   199  		panic(err)
   200  		return nil, err
   201  	}
   202  
   203  	config.file = filePath
   204  	config.source = hctypes.Buffer(content)
   205  
   206  	err = json.Unmarshal(content, &config)
   207  	if err != nil {
   208  		panic(err)
   209  		return nil, err
   210  	}
   211  
   212  	return config, nil
   213  }
   214  
   215  func (config *Config) ForPublic() *Config {
   216  	apis := []*ConfigAPI{}
   217  	for _, api := range config.APIs {
   218  		apis = append(apis, api.ForPublic())
   219  	}
   220  
   221  	return &Config{
   222  		Namespace: config.Namespace,
   223  		APIs:      apis,
   224  	}
   225  }
   226  
   227  // Example: ./config.json
   228  //
   229  // ```json
   230  //
   231  //	{
   232  //	    "namespace": "api-registration",
   233  //	    "server": {
   234  //	        "port": 8080
   235  //	    },
   236  //		"templates": [
   237  //			{
   238  //				"name": "registration",
   239  //				"path": "/",
   240  //				"file_path": "example/template.html"
   241  //			}
   242  //		],
   243  //	    "apis": [
   244  //	        {
   245  //	            "name": "registration",
   246  //	            "path": "/registration",
   247  //	            "method": "POST",
   248  //	            "content_type": "application/json",
   249  //	            "response_type": "application/json",
   250  //	            "callback": {
   251  //	                "plugin": "plugin.so",
   252  //	                "function": "Registration"
   253  //	            },
   254  //	            "params": [
   255  //	                {
   256  //	                    "name": "username",
   257  //	                    "label": "Username",
   258  //	                    "placeholder": "Enter Username",
   259  //	                    "type": "username",
   260  //	                    "validate": "username",
   261  //	                    "required": true,
   262  //	                    "min": 5,
   263  //	                    "max": 32
   264  //	                },
   265  //	                {
   266  //	                    "name": "fullname",
   267  //	                    "label": "Full Name",
   268  //	                    "placeholder": "Enter Full Name",
   269  //	                    "type": "name",
   270  //	                    "validate": "name",
   271  //	                    "required": true,
   272  //	                    "min": 5,
   273  //	                    "max": 32
   274  //	                },
   275  //	                {
   276  //	                    "name": "email",
   277  //	                    "label": "Email Address",
   278  //	                    "placeholder": "Enter Email Address",
   279  //	                    "type": "email",
   280  //	                    "required": true,
   281  //	                    "min": 5,
   282  //	                    "max": 32
   283  //	                },
   284  //	                {
   285  //	                    "name": "password",
   286  //	                    "label": "Password",
   287  //	                    "placeholder": "Enter Password",
   288  //	                    "type": "password",
   289  //	                    "required": true,
   290  //	                    "min": 8,
   291  //	                    "max": 120
   292  //	                },
   293  //	                {
   294  //	                    "name": "confirm_password",
   295  //	                    "label": "Confirm Password",
   296  //	                    "placeholder": "Enter Confirm Password",
   297  //	                    "type": "password",
   298  //	                    "required": true,
   299  //	                    "min": 8,
   300  //	                    "max": 120
   301  //	                }
   302  //	            ]
   303  //	        },
   304  //	        {
   305  //	            "name": "verification",
   306  //	            "path": "/verification/:id/:otp",
   307  //	            "method": "GET",
   308  //	            "content_type": "application/json",
   309  //	            "response_type": "application/json",
   310  //	            "callback": {
   311  //	                "plugin": "plugin.so",
   312  //	                "function": "Verification"
   313  //	            },
   314  //	            "url_params": [
   315  //	                {
   316  //	                    "name": "id",
   317  //	                    "type": "textnumber",
   318  //	                    "required": true
   319  //	                },
   320  //	                {
   321  //	                    "name": "otp",
   322  //	                    "type": "textnumber",
   323  //	                    "required": true
   324  //	                }
   325  //	            ]
   326  //	        }
   327  //	    ]
   328  //	}
   329  //
   330  // ```
   331  //
   332  // Example: main.go
   333  //
   334  // ```go
   335  //
   336  //	package main
   337  //
   338  //	import (
   339  //	  "fmt"
   340  //
   341  //	  "gitlab.hexacode.org/go-libs/hctypes"
   342  //	  "gitlab.hexacode.org/go-libs/microservice/config"
   343  //	)
   344  //
   345  //	func Registration(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) {
   346  //	  fmt.Println(ctx.Config.ToDict().ToColoredJson())
   347  //	  fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson())
   348  //	  fmt.Println(ctx.URLParams.ToColoredJson())
   349  //	  fmt.Println(ctx.Params.ToColoredJson())
   350  //	  fmt.Println(ctx.Headers.ToColoredJson())
   351  //
   352  //	  return 200, hctypes.Dict{
   353  //	    "id":  1,
   354  //	    "otp": 123456,
   355  //	  }, nil
   356  //	}
   357  //
   358  //	func Verification(ctx *config.ConfigContext) (int, hctypes.Dict, *config.ReturnHTTP) {
   359  //	  fmt.Println(ctx.Config.ToDict().ToColoredJson())
   360  //	  fmt.Println(ctx.ConfigApi.ToDict().ToColoredJson())
   361  //	  fmt.Println(ctx.URLParams.ToColoredJson())
   362  //	  fmt.Println(ctx.Params.ToColoredJson())
   363  //	  fmt.Println(ctx.Headers.ToColoredJson())
   364  //
   365  //	  return 200, hctypes.Dict{
   366  //	    "success": true,
   367  //	    "message": "OTP verified",
   368  //	  }, nil
   369  //	}
   370  //
   371  // ```
   372  func (config *Config) Run() {
   373  	err := config.LoadPlugin()
   374  
   375  	if err != nil {
   376  		panic(err)
   377  	}
   378  
   379  	config.router = gin.Default()
   380  
   381  	optionses_urls := map[string]bool{}
   382  	set_options := func(path string, handler func(*gin.Context)) {
   383  		if _, ok := optionses_urls[path]; ok {
   384  			return
   385  		}
   386  		optionses_urls[path] = true
   387  		config.router.OPTIONS(path, handler)
   388  	}
   389  
   390  	if config.Templates != nil {
   391  		config.router.Static("/"+config.Namespace+"/public", "public")
   392  		for _, template := range config.Templates {
   393  			config.router.GET(fmt.Sprintf("%s%s", config.Namespace, template.Path), template.HTTPHandler)
   394  
   395  			set_options(fmt.Sprintf("%s%s", config.Namespace, template.Path), options_handler)
   396  		}
   397  	}
   398  
   399  	if config.APIs != nil {
   400  		for _, api := range config.APIs {
   401  			api.config = config
   402  			config.router.Handle(api.Method, fmt.Sprintf("%s%s", config.Namespace, api.Path), api.HTTPHandler)
   403  			config.router.GET(fmt.Sprintf("%s/config/%s", config.Namespace, api.Name), api.HTTPHandlerConfig)
   404  
   405  			set_options(fmt.Sprintf("%s%s", config.Namespace, api.Path), options_handler)
   406  			set_options(fmt.Sprintf("%s/config/%s", config.Namespace, api.Name), options_handler)
   407  		}
   408  	}
   409  
   410  	config.router.GET(fmt.Sprintf("%s/health", config.Namespace), func(c *gin.Context) {
   411  		c.String(200, "OK")
   412  	})
   413  
   414  	config.router.GET(fmt.Sprintf("%s/configs", config.Namespace), func(c *gin.Context) {
   415  		c.JSON(200, config.ForPublic())
   416  	})
   417  
   418  	set_options(fmt.Sprintf("%s/health", config.Namespace), options_handler)
   419  	set_options(fmt.Sprintf("%s/configs", config.Namespace), options_handler)
   420  
   421  	config.router.NoRoute(func(c *gin.Context) {
   422  		c.JSON(404, &ReturnHTTPError{
   423  			StatusCode: 404,
   424  			Errors: []*ReturnError{
   425  				{
   426  					Name:   "not_found",
   427  					Errors: "Not Found",
   428  				},
   429  			},
   430  		})
   431  	})
   432  
   433  	config.router.Run(fmt.Sprintf("0.0.0.0:%d", config.Server.Port))
   434  }
   435  
   436  func (config *Config) ToDict() hctypes.Dict {
   437  	return hctypes.NewDictFromJson(config.source)
   438  }
   439  
   440  // Schedule for monitoring the module
   441  //
   442  // Parameters:
   443  //
   444  //	host - the host address
   445  //	module_manager_url - the URL of the module manager
   446  func Schedule(host string, module_manager_url string) {
   447  	go func(host_ string, module_manager_url_ string) {
   448  		cfg, err := LoadConfig()
   449  		if err != nil {
   450  			return
   451  		}
   452  
   453  		port := cfg.Server.Port
   454  
   455  		port_i := port
   456  		if port_i == 0 {
   457  			return
   458  		}
   459  
   460  		http := requests.NewHttp(hctypes.Dict{
   461  			"Content-Type": "application/json",
   462  		})
   463  
   464  		cfg_s := cfg.ToDict().ToJson().ToString()
   465  
   466  		param := hctypes.Dict{
   467  			"config": cfg_s,
   468  			"host":   host_,
   469  			"port":   port_i,
   470  		}
   471  
   472  		for {
   473  			http.Post(fmt.Sprintf("%s/module-manager/monitoring", module_manager_url_), nil, param.ToJson())
   474  			fmt.Println("Monitoring")
   475  			time.Sleep(time.Minute)
   476  		}
   477  	}(host, module_manager_url)
   478  }
   479  

View as plain text