Refactor package errors + packages names :

- Refactor ErrorType, list errors managment, codeError
- Add interface Error with error interface implement
- Add type CodeError assign typiclly to const that represent code of error
- Add func to registry func to retrieve message from an uint16 codeError (typicaly a switch of each codeError const)
- Add default errorCode with default errorMessage if no one code or message is found
- Add modeError to manage how to manage compatibility between Error interface and error interface
- Add Error interface that allow parent link (parent as error or Error interface), code and trace management
- Add trace finder to allow find func/file/line caller when Error is call
- Add http 2 transport in httpcli
- Add http 2 transport in httpserver
- Add function to get client http with timeout management in httpcli
- Add function to get Error if occurs of http client in httpcli
- Add test for smtp package
- Chg return error by returning Error in all packages
- Chg package njs-archive by archive
- Chg package njs-certif by certificates
- Chg package njs-console by console
- Chg package njs-crypt by crypt
- Chg package njs-errors by errors
- Chg package njs-httpcli by httpcli
- Chg package njs-httpserver by httpserver
- Chg package njs-ioutils by ioutils
- Chg package njs-ldap by ldap
- Chg package njs-logger by logger
- Chg package njs-password by password
- Chg package njs-progress by progress
- Chg package njs-router by router
- Chg package njs-semaphore by semaphore
- Chg package njs-smtp by smtp
- Chg package njs-static by static
- Chg package njs-status by status
- Chg package njs-version by version
- Fix dependancies gopkg by github/go-ldap for go module compatibility
- Fix gin Abort call by gin Abort with Error in static package
- Fix issue #18 in status package : replace partner by component
- Fix go vet error
- Del deprecated function
- Del useless function & files
- Bump dependancies
- Apply CHG in README.md
This commit is contained in:
Nicolas JUHEL
2020-07-14 11:00:57 +02:00
parent 9570840431
commit ca39d7ad26
103 changed files with 2647 additions and 885 deletions

0
status/README.md Normal file
View File

324
status/status.go Normal file
View File

@@ -0,0 +1,324 @@
/*
* MIT License
*
* Copyright (c) 2019 Nicolas JUHEL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package status
import (
"fmt"
"net/http"
"path"
"strings"
njs_router "github.com/nabbar/golib/router"
njs_version "github.com/nabbar/golib/version"
"github.com/gin-gonic/gin"
)
// @TODO : see compliant with https://tools.ietf.org/html/draft-inadarei-api-health-check-02
type StatusItemResponse struct {
Name string
Status string
Message string
Release string
HashBuild string
}
type StatusResponse struct {
StatusItemResponse
Component []StatusItemResponse
}
const statusOK = "OK"
const statusKO = "KO"
type statusItem struct {
name string
build string
msgOK string
msgKO string
health func() error
release string
}
type statusComponent struct {
statusItem
WarnIfErr bool
later *initLater
}
type mainPackage struct {
statusItem
cpt []statusComponent
header gin.HandlerFunc
later *initLater
init bool
}
type initLater struct {
version func() njs_version.Version
info func() (name, release, build string)
msg func() (ok string, ko string)
health func() error
}
type Status interface {
Register(prefix string, register njs_router.RegisterRouter)
AddComponent(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error)
AddVersionComponent(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error)
LaterAddComponent(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool)
LaterAddVersionComponent(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool)
Get(c *gin.Context)
}
func NewStatusLater(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, Header gin.HandlerFunc) Status {
return &mainPackage{
cpt: make([]statusComponent, 0),
header: Header,
later: &initLater{
version: nil,
info: info,
msg: msg,
health: health,
},
init: false,
}
}
func NewStatus(name, msgOK, msgKO, release, build string, health func() error, Header gin.HandlerFunc) Status {
return &mainPackage{
statusItem: newItem(name, msgOK, msgKO, release, build, health),
cpt: make([]statusComponent, 0),
header: Header,
later: nil,
init: false,
}
}
func NewVersionStatusLater(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, Header gin.HandlerFunc) Status {
return &mainPackage{
cpt: make([]statusComponent, 0),
header: Header,
later: &initLater{
version: vers,
info: nil,
msg: msg,
health: health,
},
init: false,
}
}
func NewVersionStatus(vers njs_version.Version, msgOK, msgKO string, health func() error, Header gin.HandlerFunc) Status {
return NewStatus(vers.GetPackage(), msgOK, msgKO, vers.GetRelease(), vers.GetBuild(), health, Header)
}
func newItem(name, msgOK, msgKO, release, build string, health func() error) statusItem {
return statusItem{
name: name,
build: build,
msgOK: msgOK,
msgKO: msgKO,
health: health,
release: release,
}
}
func (p *mainPackage) AddComponent(name, msgOK, msgKO, release, build string, WarnIfError bool, health func() error) {
p.cpt = append(p.cpt, statusComponent{
statusItem: newItem(name, msgOK, msgKO, release, build, health),
WarnIfErr: WarnIfError,
later: nil,
})
}
func (p *mainPackage) LaterAddComponent(info func() (name, release, build string), msg func() (ok string, ko string), health func() error, WarnIfError bool) {
p.cpt = append(p.cpt, statusComponent{
WarnIfErr: WarnIfError,
later: &initLater{
version: nil,
info: info,
msg: msg,
health: health,
},
})
}
func (p *mainPackage) AddVersionComponent(vers njs_version.Version, msgOK, msgKO string, WarnIfError bool, health func() error) {
p.AddComponent(vers.GetPackage(), msgOK, msgKO, vers.GetRelease(), vers.GetBuild(), WarnIfError, health)
}
func (p *mainPackage) LaterAddVersionComponent(vers func() njs_version.Version, msg func() (ok string, ko string), health func() error, WarnIfError bool) {
p.cpt = append(p.cpt, statusComponent{
WarnIfErr: WarnIfError,
later: &initLater{
version: vers,
info: nil,
msg: msg,
health: health,
},
})
}
func (p *mainPackage) initStatus() {
if p.later != nil {
if p.later.info != nil {
name, release, build := p.later.info()
ok, ko := p.later.msg()
p.statusItem = newItem(name, ok, ko, release, build, p.health)
} else if p.later.version != nil {
vers := p.later.version()
ok, ko := p.later.msg()
p.statusItem = newItem(vers.GetPackage(), ok, ko, vers.GetRelease(), vers.GetBuild(), p.health)
}
if p.later.health != nil {
p.health = p.later.health
}
p.later = nil
}
var cpt = make([]statusComponent, 0)
for _, part := range p.cpt {
if part.later != nil {
if part.later.info != nil {
name, release, build := part.later.info()
ok, ko := part.later.msg()
part = statusComponent{
statusItem: newItem(name, ok, ko, release, build, part.health),
WarnIfErr: part.WarnIfErr,
later: nil,
}
} else if p.later.version != nil {
v := p.later.version()
ok, ko := p.later.msg()
part = statusComponent{
statusItem: newItem(v.GetPackage(), ok, ko, v.GetRelease(), v.GetBuild(), part.health),
WarnIfErr: part.WarnIfErr,
later: nil,
}
}
if part.later.health != nil {
part.health = part.later.health
}
}
cpt = append(cpt, part)
}
p.init = true
p.cpt = cpt
}
func (p *mainPackage) cleanPrefix(prefix string) string {
return path.Clean(strings.TrimRight(path.Join("/", prefix), "/"))
}
func (p *mainPackage) Register(prefix string, register njs_router.RegisterRouter) {
prefix = p.cleanPrefix(prefix)
register(http.MethodGet, prefix, p.header, p.Get)
if prefix != "/" {
register(http.MethodGet, prefix+"/", p.header, p.Get)
}
}
func (p *mainPackage) RegisterGroup(group, prefix string, register njs_router.RegisterRouterInGroup) {
prefix = p.cleanPrefix(prefix)
register(group, http.MethodGet, prefix, p.header, p.Get)
if prefix != "/" {
register(group, http.MethodGet, prefix+"/", p.header, p.Get)
}
}
func (p *statusItem) GetStatusResponse(c *gin.Context) StatusItemResponse {
res := StatusItemResponse{
Name: p.name,
Status: statusOK,
Message: p.msgOK,
Release: p.release,
HashBuild: p.build,
}
if p.health != nil {
if err := p.health(); err != nil {
msg := fmt.Sprintf("%s: %v", p.msgKO, err)
c.Errors = append(c.Errors, &gin.Error{
Err: fmt.Errorf(msg),
Type: gin.ErrorTypePrivate,
})
res = StatusItemResponse{
Name: p.name,
Status: statusKO,
Message: msg,
Release: p.release,
HashBuild: p.build,
}
}
}
return res
}
func (p *mainPackage) Get(c *gin.Context) {
if !p.init {
p.initStatus()
}
hasError := false
res := StatusResponse{
p.GetStatusResponse(c),
make([]StatusItemResponse, 0),
}
for _, pkg := range p.cpt {
pres := pkg.GetStatusResponse(c)
if res.Status == statusOK && pres.Status == statusKO && !pkg.WarnIfErr {
res.Status = statusKO
} else if pres.Status == statusKO {
hasError = true
}
res.Component = append(res.Component, pres)
}
if res.Status != statusOK {
c.AbortWithStatusJSON(http.StatusInternalServerError, &res)
} else if hasError {
c.JSON(http.StatusAccepted, &res)
} else {
c.JSON(http.StatusOK, &res)
}
}