Files
golib/config/README.md
Nicolas JUHEL 49db5e2afb Add Package Config :
- major dependancies are :
  - golib/context config
  - golib/viper
- interface config extend :
  - golib/context config interface
  - component list
- interface component list :
  this interface implement all function to manage a collection of component. All component are registred with they config key.
  A component must implement basic function like start, stop, reload, defaultConfig...
  The main config json is set by calling all component config with the config key attached
  Each component have some status status like isStarted, isRunning, ...
  Each component must also declare his dependencies with other component. As that when start or reload is called,
  the component is sure that dependencies are still started or reloaded.
- They are 4 component for now : log, tls, headers and http server
- The config package will start a new context / cancelfunc on init to be sure to stop cleanly all component and process

Add Package Viper :
- this package is an helper to the config package with the spf13 viper lib
- this package can watch any change of a config file or can be connected to a remote config cluster like ETCD

Add Package Cobra :
- this package is an helper to make a CLI with flag / command
- this package is based on spf13 cobra has all method to be connected to viper golib
2022-02-21 07:32:44 +01:00

4.3 KiB

Config pakcage

This package will make a global config management package for an app. This package work wil component who's will make the real intelligence of the config. For example, the main config file is not existing into this config, because is generated by the sum of all component config part.

Exmaple of implement

You can follow the initialization define into the cobra package Here we will define the intialization of the config package.

Main init of config :

Make a package's file to be called by yours application command or routers Into this file we will use some import

import (
    "fmt"
    "net/http"

    liberr "github.com/nabbar/golib/errors"
    libsts "github.com/nabbar/golib/status"
    liblog "github.com/nabbar/golib/logger"
    librtr "github.com/nabbar/golib/router"
	
    cmphea "github.com/nabbar/golib/config/components/head"
    cmphtp "github.com/nabbar/golib/config/components/http"
    cmplog "github.com/nabbar/golib/config/components/log"
    cmptls "github.com/nabbar/golib/config/components/tls"

    compkg "../pkg"
)

Some constant to prevents error on copy/paste :

const (
    ConfigKeyHead = "headers"
    ConfigKeyHttp = "servers"
    ConfigKeyLog  = "log"
    ConfigKeyTls  = "tls"
)

This function will init the libs and return the lib resource. This is an example, but you can create your own component to add it into you config. The config can have multi instance of same component type but with different config key. As That, you can for example define a TLS config for HTTP server, a TLS config for a client, ...

func SetConfig(lvl liblog.Level, handler map[string]http.Handler) {
    compkg.GetConfig().ComponentSet(ConfigKeyHead, cmphea.New())
    compkg.GetConfig().ComponentSet(ConfigKeyLog, cmplog.New(lvl, compkg.GetLogger))
    compkg.GetConfig().ComponentSet(ConfigKeyTls, cmptls.New())
    compkg.GetConfig().ComponentSet(ConfigKeyHttp, cmphtp.New(_ConfigKeyTls, _ConfigKeyLog, handler))
}

// This function will return the router header based of the component header stored into the config
func GetHeader() librtr.Headers {
    if cmp := cmphea.Load(compkg.GetConfig().ComponentGet, _ConfigKeyHead); cmp != nil {
        return cmp.GetHeaders()
    } else {
        GetLog().Fatal("component '%s' is not initialized", _ConfigKeyHead)
        return nil
    }
}

// This function will return the logger for the application. 
// If the component is not started, this function will return the root logger  
func GetLog() liblog.Logger {
    if !compkg.GetConfig().ComponentIsStarted() {
        return nil
    }

    if cmp := cmplog.Load(compkg.GetConfig().ComponentGet, _ConfigKeyLog); cmp != nil {
        return cmp.Log()
    } else {
        compkg.GetLogger().Error("component '%s' is not initialized", _ConfigKeyLog)
        return compkg.GetLogger()
    }
}

This function will connect the status package of golib with the httpserver package stored into the config :

// This function can be call by the implementation of Status Package to expose the status of the pool web server
// This function will update the status after each reload the pool web server.
func SetRouteStatus(sts libsts.RouteStatus) {
    compkg.GetConfig().RegisterFuncReloadAfter(func() liberr.Error {
        var cmp cmphtp.ComponentHttp

		// If component has not been started, skill the function
        if !compkg.GetConfig().ComponentIsStarted() {
            return nil
        }

		// if cannot access to the Http component, generate an error
        if cmp = cmphtp.Load(compkg.GetConfig().ComponentGet, ConfigKeyHttp); cmp == nil {
            return ErrorComponentNotInitialized.ErrorParent(fmt.Errorf("component '%s'", ConfigKeyHttp))
        }

		// Get the Pool Server
        pool := cmp.GetPool()
        pool.StatusRoute(_ConfigKeyHttp, GetRouteStatusMessage, sts)
		
		// Don't forget to update the component pool
        cmp.SetPool(pool)

        return nil
    })
}

To generate the config example, just call this function :

    compkg.GetConfig().DefaultConfig()

This function will associate the config Key with the component default config into a main buffer to return it. As that, config can be extended easily with many component and the config is automatically managed.