mirror of
https://github.com/nabbar/golib.git
synced 2025-12-24 11:51:02 +08:00
Rework Monitoring, Prometheus, Status system
Package Monitoring : - use packag dedicated to monitor component - each monitor work as standalone server to monitor health - collect metrics to export them to prometheus exporter Package Prometheus : - review to simplify use for API and not API metrics - optimize code Package Status : - Rework to use Monitor package - Rework to use native json / text Marshaller interface Context : - rework context config (context var) to use sync map and sync RWMutex (WORM) - move gin context to dedicated sub package (dependancies of logger make circular dependencies) - optimize code Config : - rework to optimize sync / collect of component - rework status to monitor - remove monitor managment from config to each component - add a func to set default logger to implement inherit default logger options - optimize code IOUtils : - isolate logger / closer interface as a usable & public interface & instance - this interface / instance allow to collect io.closer over a context to close all if context is done Logger : - rework to use context.config map - rework to use ioutils closer - rework to allow options to inherit a default options, or the last version of options - optimize code Size : - Add package Size to calculate and manipulate size Byte or bit - Add encoding : Text/JSON/Yaml/Toml... - Add option to défine default unit : Byte or bit Other : - adjust following code - optimize code - limit use of atomic value - rework to use RWMutex instead of sync.Mutex to maximize capabilities of read instead of write - remove 32bit build for CI/CD - add darwin/arm64 build for CI/CD Bump Dependencies
This commit is contained in:
32
.github/workflows/go.yml
vendored
32
.github/workflows/go.yml
vendored
@@ -93,43 +93,21 @@ jobs:
|
||||
continue-on-error: false
|
||||
run: sudo apt-get install gcc-multilib gcc-mingw-w64
|
||||
|
||||
- name: Test Build Linux/amd64 with suffix
|
||||
- name: Test Build Linux/amd64 with suffix/CGO
|
||||
continue-on-error: false
|
||||
run: |
|
||||
CGO_ENABLED=0
|
||||
GOOS=linux
|
||||
GOARCH=amd64
|
||||
GOAMD64=v4
|
||||
IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"')" | tr '\n' '|')
|
||||
go build -a -v -installsuffix cgo -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
|
||||
|
||||
- name: Test Build Linux/386 with suffix
|
||||
continue-on-error: false
|
||||
run: |
|
||||
CGO_ENABLED=0
|
||||
GOOS=linux
|
||||
GOARCH=386
|
||||
IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"')" | tr '\n' '|')
|
||||
go build -a -v -installsuffix cgo -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
|
||||
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 GOAMD64=v4 go build -a -v -race -installsuffix cgo -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
|
||||
|
||||
- name: Test Build Windows/amd64 with CGO
|
||||
continue-on-error: false
|
||||
run: |
|
||||
CC=/usr/bin/x86_64-w64-mingw32-gcc
|
||||
CGO_ENABLED=1
|
||||
GOOS=windows
|
||||
GOARCH=amd64
|
||||
GOAMD64=v4
|
||||
IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"')" | tr '\n' '|')
|
||||
go build -a -v -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
|
||||
CC=/usr/bin/x86_64-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows GOARCH=amd64 GOAMD64=v4 go build -a -v -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
|
||||
|
||||
- name: Test Build Windows/386 with CGO
|
||||
- name: Test Build Darwin/arm64 with suffix/CGO
|
||||
continue-on-error: false
|
||||
run: |
|
||||
CC=/usr/bin/i686-w64-mingw32-gcc
|
||||
CGO_ENABLED=1
|
||||
GOOS=windows
|
||||
GOARCH=386
|
||||
IGNORE_BUILD=$(sed '/^[[:space:]]*$/d' "build.$(go env | grep GOARCH | cut -d'=' -f2 | tr -d '"')" | tr '\n' '|')
|
||||
go build -a -v -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 GOAMD64=v1 go build -a -v -ldflags "-w -s -extldflags '-static' " $(go list ./... | grep -vPi ${IGNORE_BUILD::-1})
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@ import (
|
||||
"net"
|
||||
"net/url"
|
||||
|
||||
libsts "github.com/nabbar/golib/status/config"
|
||||
moncfg "github.com/nabbar/golib/monitor/types"
|
||||
|
||||
sdkaws "github.com/aws/aws-sdk-go-v2/aws"
|
||||
libval "github.com/go-playground/validator/v10"
|
||||
"github.com/nabbar/golib/errors"
|
||||
"github.com/nabbar/golib/httpcli"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libhtc "github.com/nabbar/golib/httpcli"
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
@@ -47,8 +47,9 @@ type Model struct {
|
||||
}
|
||||
|
||||
type ModelStatus struct {
|
||||
Config Model `json:"config" yaml:"config" toml:"config" mapstructure:"config" validate:"required,dive"`
|
||||
Status libsts.ConfigStatus `json:"status" yaml:"status" toml:"status" mapstructure:"status" validate:"required,dive"`
|
||||
Config Model `json:"config" yaml:"config" toml:"config" mapstructure:"config" validate:"required,dive"`
|
||||
HTTPClient libhtc.Options `json:"http-client" yaml:"http-client" toml:"http-client" mapstructure:"http-client" validate:"required,dive"`
|
||||
Monitor moncfg.Config `json:"monitor" yaml:"monitor" toml:"monitor" mapstructure:"monitor" validate:"required,dive"`
|
||||
}
|
||||
|
||||
type awsModel struct {
|
||||
@@ -56,7 +57,7 @@ type awsModel struct {
|
||||
retryer func() sdkaws.Retryer
|
||||
}
|
||||
|
||||
func (c *awsModel) Validate() errors.Error {
|
||||
func (c *awsModel) Validate() liberr.Error {
|
||||
err := ErrorConfigValidator.Error(nil)
|
||||
|
||||
if er := libval.New().Struct(c); er != nil {
|
||||
@@ -89,11 +90,11 @@ func (c *awsModel) SetCredentials(accessKey, secretKey string) {
|
||||
func (c *awsModel) ResetRegionEndpoint() {
|
||||
}
|
||||
|
||||
func (c *awsModel) RegisterRegionEndpoint(region string, endpoint *url.URL) errors.Error {
|
||||
func (c *awsModel) RegisterRegionEndpoint(region string, endpoint *url.URL) liberr.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *awsModel) RegisterRegionAws(endpoint *url.URL) errors.Error {
|
||||
func (c *awsModel) RegisterRegionAws(endpoint *url.URL) liberr.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -108,7 +109,7 @@ func (c *awsModel) GetRegion() string {
|
||||
func (c *awsModel) SetEndpoint(endpoint *url.URL) {
|
||||
}
|
||||
|
||||
func (c awsModel) GetEndpoint() *url.URL {
|
||||
func (c *awsModel) GetEndpoint() *url.URL {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -116,6 +117,18 @@ func (c *awsModel) ResolveEndpoint(service, region string) (sdkaws.Endpoint, err
|
||||
return sdkaws.Endpoint{}, ErrorEndpointInvalid.Error(nil)
|
||||
}
|
||||
|
||||
func (c *awsModel) ResolveEndpointWithOptions(service, region string, options ...interface{}) (sdkaws.Endpoint, error) {
|
||||
return sdkaws.Endpoint{}, ErrorEndpointInvalid.Error(nil)
|
||||
}
|
||||
|
||||
func (c *awsModel) GetDisableHTTPS() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *awsModel) GetResolvedRegion() string {
|
||||
return c.GetRegion()
|
||||
}
|
||||
|
||||
func (c *awsModel) IsHTTPs() bool {
|
||||
return true
|
||||
}
|
||||
@@ -124,14 +137,14 @@ func (c *awsModel) SetRetryer(retryer func() sdkaws.Retryer) {
|
||||
c.retryer = retryer
|
||||
}
|
||||
|
||||
func (c awsModel) Check(ctx context.Context) errors.Error {
|
||||
func (c *awsModel) Check(ctx context.Context) liberr.Error {
|
||||
var (
|
||||
cfg *sdkaws.Config
|
||||
con net.Conn
|
||||
end sdkaws.Endpoint
|
||||
adr *url.URL
|
||||
err error
|
||||
e errors.Error
|
||||
e liberr.Error
|
||||
)
|
||||
|
||||
if cfg, e = c.GetConfig(ctx, nil); e != nil {
|
||||
@@ -142,7 +155,7 @@ func (c awsModel) Check(ctx context.Context) errors.Error {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
if end, err = cfg.EndpointResolver.ResolveEndpoint("s3", c.GetRegion()); err != nil {
|
||||
if end, err = cfg.EndpointResolverWithOptions.ResolveEndpoint("s3", c.GetRegion()); err != nil {
|
||||
return ErrorEndpointInvalid.ErrorParent(err)
|
||||
}
|
||||
|
||||
@@ -155,8 +168,8 @@ func (c awsModel) Check(ctx context.Context) errors.Error {
|
||||
}
|
||||
|
||||
d := net.Dialer{
|
||||
Timeout: httpcli.ClientTimeout5Sec,
|
||||
KeepAlive: httpcli.ClientTimeout5Sec,
|
||||
Timeout: libhtc.ClientTimeout5Sec,
|
||||
KeepAlive: libhtc.ClientTimeout5Sec,
|
||||
}
|
||||
|
||||
con, err = d.DialContext(ctx, "tcp", adr.Host)
|
||||
|
||||
@@ -111,6 +111,7 @@ func (c *awsModel) GetConfig(ctx context.Context, cli *http.Client) (*sdkaws.Con
|
||||
cfg.Credentials = sdkcrd.NewStaticCredentialsProvider(c.AccessKey, c.SecretKey, "")
|
||||
cfg.Retryer = c.retryer
|
||||
cfg.EndpointResolver = sdkaws.EndpointResolverFunc(c.ResolveEndpoint)
|
||||
cfg.EndpointResolverWithOptions = sdkaws.EndpointResolverWithOptionsFunc(c.ResolveEndpointWithOptions)
|
||||
cfg.Region = c.Region
|
||||
|
||||
if cli != nil {
|
||||
|
||||
@@ -32,12 +32,13 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
moncfg "github.com/nabbar/golib/monitor/types"
|
||||
|
||||
sdkaws "github.com/aws/aws-sdk-go-v2/aws"
|
||||
libval "github.com/go-playground/validator/v10"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libhtc "github.com/nabbar/golib/httpcli"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libsts "github.com/nabbar/golib/status/config"
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
@@ -49,8 +50,9 @@ type Model struct {
|
||||
}
|
||||
|
||||
type ModelStatus struct {
|
||||
Config Model `json:"config" yaml:"config" toml:"config" mapstructure:"config" validate:"required,dive"`
|
||||
Status libsts.ConfigStatus `json:"status" yaml:"status" toml:"status" mapstructure:"status" validate:"required,dive"`
|
||||
Config Model `json:"config" yaml:"config" toml:"config" mapstructure:"config" validate:"required,dive"`
|
||||
HTTPClient libhtc.Options `json:"http-client" yaml:"http-client" toml:"http-client" mapstructure:"http-client" validate:"required,dive"`
|
||||
Monitor moncfg.Config `json:"monitor" yaml:"monitor" toml:"monitor" mapstructure:"monitor" validate:"required,dive"`
|
||||
}
|
||||
|
||||
type awsModel struct {
|
||||
@@ -220,11 +222,15 @@ func (c *awsModel) SetEndpoint(endpoint *url.URL) {
|
||||
c.Endpoint = strings.TrimSuffix(c.endpoint.String(), "/")
|
||||
}
|
||||
|
||||
func (c awsModel) GetEndpoint() *url.URL {
|
||||
func (c *awsModel) GetEndpoint() *url.URL {
|
||||
return c.endpoint
|
||||
}
|
||||
|
||||
func (c *awsModel) ResolveEndpoint(service, region string) (sdkaws.Endpoint, error) {
|
||||
return c.ResolveEndpointWithOptions(service, region)
|
||||
}
|
||||
|
||||
func (c *awsModel) ResolveEndpointWithOptions(service, region string, options ...interface{}) (sdkaws.Endpoint, error) {
|
||||
if e, ok := c.mapRegion[region]; ok {
|
||||
return sdkaws.Endpoint{
|
||||
URL: strings.TrimSuffix(e.String(), "/"),
|
||||
@@ -245,6 +251,14 @@ func (c *awsModel) ResolveEndpoint(service, region string) (sdkaws.Endpoint, err
|
||||
return sdkaws.Endpoint{}, ErrorEndpointInvalid.Error(nil)
|
||||
}
|
||||
|
||||
func (c *awsModel) GetDisableHTTPS() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *awsModel) GetResolvedRegion() string {
|
||||
return c.GetRegion()
|
||||
}
|
||||
|
||||
func (c *awsModel) IsHTTPs() bool {
|
||||
return strings.HasSuffix(strings.ToLower(c.endpoint.Scheme), "s")
|
||||
}
|
||||
@@ -253,7 +267,7 @@ func (c *awsModel) SetRetryer(retryer func() sdkaws.Retryer) {
|
||||
c.retryer = retryer
|
||||
}
|
||||
|
||||
func (c awsModel) Check(ctx context.Context) liberr.Error {
|
||||
func (c *awsModel) Check(ctx context.Context) liberr.Error {
|
||||
var (
|
||||
cfg *sdkaws.Config
|
||||
con net.Conn
|
||||
@@ -269,7 +283,7 @@ func (c awsModel) Check(ctx context.Context) liberr.Error {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
if _, err = cfg.EndpointResolver.ResolveEndpoint("s3", c.GetRegion()); err != nil {
|
||||
if _, err = cfg.EndpointResolverWithOptions.ResolveEndpoint("s3", c.GetRegion()); err != nil {
|
||||
return ErrorEndpointInvalid.ErrorParent(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ type Config interface {
|
||||
|
||||
IsHTTPs() bool
|
||||
ResolveEndpoint(service, region string) (sdkaws.Endpoint, error)
|
||||
ResolveEndpointWithOptions(service, region string, options ...interface{}) (sdkaws.Endpoint, error)
|
||||
GetDisableHTTPS() bool
|
||||
GetResolvedRegion() string
|
||||
SetRetryer(retryer func() sdkaws.Retryer)
|
||||
|
||||
GetConfig(ctx context.Context, cli *http.Client) (*sdkaws.Config, liberr.Error)
|
||||
|
||||
27
cache/expiration.go
vendored
Normal file
27
cache/expiration.go
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 cache
|
||||
73
cache/interface.go
vendored
Normal file
73
cache/interface.go
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FuncCache[T any] func() Cache[T]
|
||||
|
||||
type Cache[T any] interface {
|
||||
Clone(ctx context.Context, exp time.Duration) Cache[T]
|
||||
Close()
|
||||
Clean()
|
||||
|
||||
Merge(c Cache[T])
|
||||
Walk(fct func(key any, val interface{}, exp time.Duration) bool)
|
||||
|
||||
Load(key any) (val interface{}, exp time.Duration, ok bool)
|
||||
Store(key any, val interface{}) time.Duration
|
||||
Delete(key any)
|
||||
|
||||
LoadOrStore(key any, val interface{}) (res interface{}, exp time.Duration, loaded bool)
|
||||
LoadAndDelete(key any) (val interface{}, loaded bool)
|
||||
}
|
||||
|
||||
func New[T any](ctx context.Context, exp time.Duration) Cache[T] {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
if exp < time.Microsecond {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := &cache[T]{
|
||||
Context: ctx,
|
||||
w: sync.RWMutex{},
|
||||
m: sync.Map{},
|
||||
c: make(chan struct{}),
|
||||
e: exp,
|
||||
}
|
||||
|
||||
go n.ticker(exp)
|
||||
|
||||
return n
|
||||
}
|
||||
51
cache/item.go
vendored
Normal file
51
cache/item.go
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 cache
|
||||
|
||||
import "time"
|
||||
|
||||
type cacheItem struct {
|
||||
t time.Time
|
||||
v interface{}
|
||||
}
|
||||
|
||||
func store(val interface{}) *cacheItem {
|
||||
return &cacheItem{
|
||||
t: time.Now(),
|
||||
v: val,
|
||||
}
|
||||
}
|
||||
|
||||
func parse(v any, exp time.Duration) (interface{}, time.Duration) {
|
||||
if i, ok := v.(*cacheItem); !ok {
|
||||
return nil, 0
|
||||
} else if e := exp - time.Since(i.t); e < time.Microsecond {
|
||||
return nil, 0
|
||||
} else {
|
||||
return i.v, e
|
||||
}
|
||||
}
|
||||
218
cache/model.go
vendored
Normal file
218
cache/model.go
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type cache[T any] struct {
|
||||
context.Context
|
||||
|
||||
w sync.RWMutex
|
||||
m sync.Map
|
||||
c chan struct{}
|
||||
e time.Duration
|
||||
}
|
||||
|
||||
func (t *cache[T]) ticker(exp time.Duration) {
|
||||
ticker := time.NewTicker(exp)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
t.expire()
|
||||
|
||||
case <-t.Done():
|
||||
t.Clean()
|
||||
return
|
||||
|
||||
case <-t.c:
|
||||
t.Clean()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *cache[T]) expire() {
|
||||
t.w.RLock()
|
||||
defer t.w.RUnlock()
|
||||
|
||||
exp := t.e
|
||||
|
||||
t.m.Range(func(key, value any) bool {
|
||||
if v, _ := parse(value, exp); v == nil {
|
||||
t.m.Delete(key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (t *cache[T]) Clone(ctx context.Context, exp time.Duration) Cache[T] {
|
||||
t.w.RLock()
|
||||
defer t.w.RUnlock()
|
||||
|
||||
if ctx == nil {
|
||||
ctx = t.Context
|
||||
}
|
||||
|
||||
if exp < time.Microsecond {
|
||||
exp = t.e
|
||||
}
|
||||
|
||||
n := &cache[T]{
|
||||
Context: ctx,
|
||||
w: sync.RWMutex{},
|
||||
m: sync.Map{},
|
||||
c: make(chan struct{}),
|
||||
e: exp,
|
||||
}
|
||||
|
||||
t.m.Range(func(key any, val interface{}) bool {
|
||||
n.Store(key, val)
|
||||
return true
|
||||
})
|
||||
|
||||
go n.ticker(exp)
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (t *cache[T]) Close() {
|
||||
t.c <- struct{}{}
|
||||
}
|
||||
|
||||
func (t *cache[T]) Clean() {
|
||||
t.w.Lock()
|
||||
defer t.w.Unlock()
|
||||
|
||||
t.m = sync.Map{}
|
||||
}
|
||||
|
||||
func (t *cache[T]) Merge(c Cache[T]) {
|
||||
t.w.RLock()
|
||||
defer t.w.RUnlock()
|
||||
|
||||
c.Walk(func(key any, val interface{}, exp time.Duration) bool {
|
||||
t.m.Store(key, &cacheItem{
|
||||
t: time.Now().Add(-exp),
|
||||
v: nil,
|
||||
})
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (t *cache[T]) Walk(fct func(key any, val interface{}, exp time.Duration) bool) {
|
||||
t.w.RLock()
|
||||
defer t.w.RUnlock()
|
||||
|
||||
exp := t.e
|
||||
|
||||
t.m.Range(func(key, value any) bool {
|
||||
if v, e := parse(value, exp); v == nil {
|
||||
t.m.Delete(key)
|
||||
return true
|
||||
} else {
|
||||
return fct(key, v, e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (t *cache[T]) Load(key any) (val interface{}, exp time.Duration, ok bool) {
|
||||
t.w.RLock()
|
||||
defer t.w.RUnlock()
|
||||
|
||||
var o any
|
||||
|
||||
if o, ok = t.m.Load(key); !ok {
|
||||
return nil, 0, false
|
||||
} else if val, exp = parse(o, t.e); val == nil {
|
||||
t.m.Delete(key)
|
||||
return nil, 0, false
|
||||
} else {
|
||||
return val, exp, true
|
||||
}
|
||||
}
|
||||
|
||||
func (t *cache[T]) Store(key any, val interface{}) time.Duration {
|
||||
i := store(val)
|
||||
e := time.Now()
|
||||
|
||||
t.w.RLock()
|
||||
defer t.w.RUnlock()
|
||||
|
||||
t.m.Store(key, i)
|
||||
return t.e - time.Since(e)
|
||||
}
|
||||
|
||||
func (t *cache[T]) Delete(key any) {
|
||||
t.m.LoadAndDelete(key)
|
||||
}
|
||||
|
||||
func (t *cache[T]) LoadOrStore(key any, val interface{}) (res interface{}, exp time.Duration, loaded bool) {
|
||||
if res, exp, loaded = t.Load(key); !loaded {
|
||||
exp = t.Store(key, val)
|
||||
return val, exp, false
|
||||
}
|
||||
|
||||
return res, exp, loaded
|
||||
}
|
||||
|
||||
func (t *cache[T]) LoadAndDelete(key any) (val interface{}, loaded bool) {
|
||||
if val, _, loaded = t.Load(key); !loaded {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
t.w.RLock()
|
||||
defer t.w.RUnlock()
|
||||
|
||||
t.m.Delete(key)
|
||||
return val, loaded
|
||||
}
|
||||
|
||||
func (t *cache[T]) Deadline() (deadline time.Time, ok bool) {
|
||||
return t.Context.Deadline()
|
||||
}
|
||||
|
||||
func (t *cache[T]) Done() <-chan struct{} {
|
||||
return t.Context.Done()
|
||||
}
|
||||
|
||||
func (t *cache[T]) Err() error {
|
||||
return t.Context.Err()
|
||||
}
|
||||
|
||||
func (t *cache[T]) Value(key any) any {
|
||||
if v, _, ok := t.Load(key); ok {
|
||||
return v
|
||||
} else {
|
||||
return t.Context.Value(key)
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,14 @@ package certificates
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"net/http"
|
||||
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
type FctHttpClient func(def TLSConfig, servername string) *http.Client
|
||||
type FctTLSDefault func() TLSConfig
|
||||
|
||||
type TLSConfig interface {
|
||||
AddRootCAString(rootCA string) bool
|
||||
AddRootCAFile(pemFile string) liberr.Error
|
||||
|
||||
@@ -36,11 +36,10 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/pelletier/go-toml"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
"github.com/pelletier/go-toml"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var cfgFile string
|
||||
|
||||
361
config/components.go
Normal file
361
config/components.go
Normal file
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
_const "github.com/nabbar/golib/config/const"
|
||||
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func (c *configModel) ComponentHas(key string) bool {
|
||||
if i, l := c.cpt.Load(key); !l {
|
||||
return false
|
||||
} else {
|
||||
_, k := i.(cfgtps.Component)
|
||||
return k
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentType(key string) string {
|
||||
if v := c.ComponentGet(key); v == nil {
|
||||
return ""
|
||||
} else {
|
||||
return v.Type()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentGet(key string) cfgtps.Component {
|
||||
if i, l := c.cpt.Load(key); !l {
|
||||
return nil
|
||||
} else if v, k := i.(cfgtps.Component); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentDel(key string) {
|
||||
c.cpt.Delete(key)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentSet(key string, cpt cfgtps.Component) {
|
||||
cpt.Init(key, c.ctx.GetContext, c.ComponentGet, c.getViper, c.getVersion(), c.getDefaultLogger)
|
||||
if f := c.getFctMonitorPool(); f != nil {
|
||||
cpt.RegisterMonitorPool(f)
|
||||
} else {
|
||||
cpt.RegisterMonitorPool(c.getMonitorPool)
|
||||
}
|
||||
c.cpt.Store(key, cpt)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentList() map[string]cfgtps.Component {
|
||||
var res = make(map[string]cfgtps.Component, 0)
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
if v, k := val.(cfgtps.Component); k {
|
||||
res[key] = v
|
||||
} else {
|
||||
c.cpt.Delete(key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentKeys() []string {
|
||||
var res = make([]string, 0)
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
if _, k := val.(cfgtps.Component); k {
|
||||
res = append(res, key)
|
||||
} else {
|
||||
c.cpt.Delete(key)
|
||||
}
|
||||
return true
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentStart() liberr.Error {
|
||||
var err = ErrorComponentStart.Error(nil)
|
||||
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
|
||||
if v, k := val.(cfgtps.Component); !k {
|
||||
c.cpt.Delete(key)
|
||||
} else if v == nil {
|
||||
c.cpt.Delete(key)
|
||||
} else if e := c.startComponent(key, v); e != nil {
|
||||
err.AddParent(e)
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
if err.HasParent() {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) startComponent(key string, cpt cfgtps.Component) liberr.Error {
|
||||
if cpt.IsStarted() {
|
||||
return nil
|
||||
} else if err := c.startDependencies(cpt.Dependencies()); err != nil {
|
||||
return err
|
||||
} else if err = cpt.Start(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
c.cpt.Store(key, cpt)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) startDependencies(list []string) liberr.Error {
|
||||
if len(list) < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, d := range list {
|
||||
if cpt := c.ComponentGet(d); cpt == nil {
|
||||
return ErrorComponentNotFound.ErrorParent(fmt.Errorf("cvomponent '%s' not found", d))
|
||||
} else if cpt.IsStarted() {
|
||||
continue
|
||||
} else if err := c.startComponent(d, cpt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentIsStarted() bool {
|
||||
isOk := false
|
||||
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
if v, k := val.(cfgtps.Component); !k {
|
||||
c.cpt.Delete(key)
|
||||
} else if v == nil {
|
||||
c.cpt.Delete(key)
|
||||
} else if v.IsStarted() {
|
||||
isOk = true
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return isOk
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentReload() liberr.Error {
|
||||
var err = ErrorComponentReload.Error(nil)
|
||||
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
if v, k := val.(cfgtps.Component); !k {
|
||||
c.cpt.Delete(key)
|
||||
} else if v == nil {
|
||||
c.cpt.Delete(key)
|
||||
} else if e := c.reloadComponent(key, v); e != nil {
|
||||
err.AddParent(e)
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
if err.HasParent() {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) reloadComponent(key string, cpt cfgtps.Component) liberr.Error {
|
||||
if cpt.IsStarted() {
|
||||
return nil
|
||||
} else if err := c.reloadDependencies(cpt.Dependencies()); err != nil {
|
||||
return err
|
||||
} else if err = cpt.Start(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
c.cpt.Store(key, cpt)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) reloadDependencies(list []string) liberr.Error {
|
||||
if len(list) < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, d := range list {
|
||||
if cpt := c.ComponentGet(d); cpt == nil {
|
||||
return ErrorComponentNotFound.ErrorParent(fmt.Errorf("cvomponent '%s' not found", d))
|
||||
} else if cpt.IsStarted() {
|
||||
continue
|
||||
} else if err := c.startComponent(d, cpt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentStop() {
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
if v, k := val.(cfgtps.Component); !k {
|
||||
c.cpt.Delete(key)
|
||||
} else if v == nil {
|
||||
c.cpt.Delete(key)
|
||||
} else if v.IsStarted() {
|
||||
v.Stop()
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentIsRunning(atLeast bool) bool {
|
||||
isOk := false
|
||||
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
v, k := val.(cfgtps.Component)
|
||||
|
||||
if !k {
|
||||
c.cpt.Delete(key)
|
||||
return true
|
||||
} else if v == nil {
|
||||
c.cpt.Delete(key)
|
||||
return true
|
||||
}
|
||||
|
||||
if v.IsRunning() {
|
||||
isOk = true
|
||||
}
|
||||
|
||||
if atLeast && isOk {
|
||||
return false
|
||||
} else if !atLeast && !isOk {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return isOk
|
||||
}
|
||||
|
||||
func (c *configModel) DefaultConfig() io.Reader {
|
||||
var buffer = bytes.NewBuffer(make([]byte, 0))
|
||||
|
||||
buffer.WriteString("{")
|
||||
buffer.WriteString("\n")
|
||||
|
||||
n := buffer.Len()
|
||||
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
v, k := val.(cfgtps.Component)
|
||||
|
||||
if !k {
|
||||
c.ComponentDel(key)
|
||||
return true
|
||||
} else if v == nil {
|
||||
c.ComponentDel(key)
|
||||
return true
|
||||
}
|
||||
|
||||
if p := v.DefaultConfig(_const.JSONIndent); len(p) > 0 {
|
||||
if buffer.Len() > n {
|
||||
buffer.WriteString(",")
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("%s\"%s\": ", _const.JSONIndent, key))
|
||||
buffer.Write(p)
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
buffer.WriteString("\n")
|
||||
buffer.WriteString("}")
|
||||
|
||||
var (
|
||||
cmp = bytes.NewBuffer(make([]byte, 0))
|
||||
ind = bytes.NewBuffer(make([]byte, 0))
|
||||
)
|
||||
|
||||
if err := json.Compact(cmp, buffer.Bytes()); err != nil {
|
||||
return buffer
|
||||
} else if err = json.Indent(ind, cmp.Bytes(), "", _const.JSONIndent); err != nil {
|
||||
return buffer
|
||||
}
|
||||
|
||||
return ind
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFlag(Command *spfcbr.Command) error {
|
||||
var err = ErrorComponentFlagError.Error(nil)
|
||||
|
||||
for _, k := range c.ComponentKeys() {
|
||||
if cpt := c.ComponentGet(k); cpt == nil {
|
||||
continue
|
||||
} else if e := cpt.RegisterFlag(Command); e != nil {
|
||||
err.AddParent(e)
|
||||
} else {
|
||||
c.ComponentSet(k, cpt)
|
||||
}
|
||||
}
|
||||
|
||||
if err.HasParent() {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentWalk(fct cfgtps.ComponentListWalkFunc) {
|
||||
c.cpt.Walk(func(key string, val interface{}) bool {
|
||||
if v, k := val.(cfgtps.Component); !k {
|
||||
c.cpt.Delete(key)
|
||||
return true
|
||||
} else if v == nil {
|
||||
c.cpt.Delete(key)
|
||||
return true
|
||||
} else {
|
||||
return fct(key, v)
|
||||
}
|
||||
})
|
||||
}
|
||||
220
config/components/aws/client.go
Normal file
220
config/components/aws/client.go
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 aws
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
libaws "github.com/nabbar/golib/aws"
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentAws) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getTLS() libtls.TLSConfig {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.t == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return o.t()
|
||||
}
|
||||
|
||||
func (o *componentAws) _getHttpClient() *http.Client {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.c == nil {
|
||||
return &http.Client{}
|
||||
}
|
||||
|
||||
return o.c()
|
||||
}
|
||||
|
||||
func (o *componentAws) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentAws) _runCli() liberr.Error {
|
||||
var prt = ErrorComponentReload
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorComponentStart
|
||||
}
|
||||
|
||||
if cfg, mon, htc, err := o._getConfig(); err != nil {
|
||||
return prt.Error(err)
|
||||
} else if cli, er := libaws.New(o.x.GetContext(), cfg, o._getHttpClient()); er != nil {
|
||||
return prt.Error(er)
|
||||
} else {
|
||||
o.m.Lock()
|
||||
o.a = cli
|
||||
o.m.Unlock()
|
||||
|
||||
if htc != nil {
|
||||
o.RegisterHTTPClient(func() *http.Client {
|
||||
if c, e := htc.GetClient(o._getTLS(), ""); e == nil {
|
||||
return c
|
||||
}
|
||||
|
||||
return &http.Client{}
|
||||
})
|
||||
}
|
||||
|
||||
if e := o._registerMonitor(mon, cfg); e != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentAws) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
155
config/components/aws/component.go
Normal file
155
config/components/aws/component.go
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 aws
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "aws"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentAws) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentAws) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentAws) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentAws) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentAws) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.a != nil
|
||||
}
|
||||
|
||||
func (o *componentAws) IsRunning() bool {
|
||||
return o.IsStarted()
|
||||
}
|
||||
|
||||
func (o *componentAws) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentAws) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentAws) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.a = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentAws) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = make([]string, 0)
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
236
config/components/aws/config.go
Normal file
236
config/components/aws/config.go
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 aws
|
||||
|
||||
import (
|
||||
libaws "github.com/nabbar/golib/aws"
|
||||
cfgstd "github.com/nabbar/golib/aws/configAws"
|
||||
cfgcus "github.com/nabbar/golib/aws/configCustom"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libhtc "github.com/nabbar/golib/httpcli"
|
||||
libmon "github.com/nabbar/golib/monitor/types"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type _configFlag struct {
|
||||
accessKey *string
|
||||
secretKey *string
|
||||
bucket *string
|
||||
region *string
|
||||
endpoint *string
|
||||
}
|
||||
|
||||
func (c *_configFlag) updCustom(cfg *cfgcus.Model) {
|
||||
if c.accessKey != nil {
|
||||
cfg.AccessKey = *c.accessKey
|
||||
}
|
||||
if c.secretKey != nil {
|
||||
cfg.SecretKey = *c.secretKey
|
||||
}
|
||||
if c.bucket != nil {
|
||||
cfg.Bucket = *c.bucket
|
||||
}
|
||||
if c.region != nil {
|
||||
cfg.Region = *c.region
|
||||
}
|
||||
if c.endpoint != nil {
|
||||
cfg.Endpoint = *c.endpoint
|
||||
}
|
||||
}
|
||||
|
||||
func (c *_configFlag) updStandard(cfg *cfgstd.Model) {
|
||||
if c.accessKey != nil {
|
||||
cfg.AccessKey = *c.accessKey
|
||||
}
|
||||
if c.secretKey != nil {
|
||||
cfg.SecretKey = *c.secretKey
|
||||
}
|
||||
if c.bucket != nil {
|
||||
cfg.Bucket = *c.bucket
|
||||
}
|
||||
if c.region != nil {
|
||||
cfg.Region = *c.region
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) RegisterFlag(Command *spfcbr.Command) error {
|
||||
var (
|
||||
key = o._getKey()
|
||||
vpr *spfvpr.Viper
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
_ = Command.PersistentFlags().String(key+".access-key", "", "AWS Access Key")
|
||||
_ = Command.PersistentFlags().String(key+".secret-key", "", "AWS Secret Key")
|
||||
_ = Command.PersistentFlags().String(key+".bucket", "", "Bucket to use")
|
||||
_ = Command.PersistentFlags().String(key+".region", "", "Region for bucket")
|
||||
_ = Command.PersistentFlags().String(key+".endpoint", "", "Endpoint if necessary for the region")
|
||||
|
||||
if err := vpr.BindPFlag(key+".access-key", Command.PersistentFlags().Lookup(key+".access-key")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".secret-key", Command.PersistentFlags().Lookup(key+".secret-key")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".bucket", Command.PersistentFlags().Lookup(key+".bucket")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".region", Command.PersistentFlags().Lookup(key+".region")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".endpoint", Command.PersistentFlags().Lookup(key+".endpoint")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentAws) _getConfig() (libaws.Config, *libmon.Config, *libhtc.Options, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg libaws.Config
|
||||
flg = o._getFlagUpdate()
|
||||
mon *libmon.Config
|
||||
htc *libhtc.Options
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, nil, nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, nil, nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
switch o.d {
|
||||
case ConfigCustomStatus:
|
||||
cnf := cfgcus.ModelStatus{}
|
||||
if e := vpr.UnmarshalKey(key, &cnf); e != nil {
|
||||
return nil, nil, nil, ErrorParamInvalid.ErrorParent(e)
|
||||
} else {
|
||||
flg.updCustom(&cnf.Config)
|
||||
}
|
||||
|
||||
if cfg, err = o.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
mon = &cnf.Monitor
|
||||
htc = &cnf.HTTPClient
|
||||
}
|
||||
|
||||
case ConfigCustom:
|
||||
cnf := cfgcus.Model{}
|
||||
if e := vpr.UnmarshalKey(key, &cnf); e != nil {
|
||||
return nil, nil, nil, ErrorParamInvalid.ErrorParent(e)
|
||||
} else {
|
||||
flg.updCustom(&cnf)
|
||||
}
|
||||
|
||||
if cfg, err = o.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
mon = nil
|
||||
htc = nil
|
||||
}
|
||||
|
||||
case ConfigStandardStatus:
|
||||
cnf := cfgstd.ModelStatus{}
|
||||
if e := vpr.UnmarshalKey(key, &cnf); e != nil {
|
||||
return nil, nil, nil, ErrorParamInvalid.ErrorParent(e)
|
||||
} else {
|
||||
flg.updStandard(&cnf.Config)
|
||||
}
|
||||
|
||||
if cfg, err = o.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
mon = &cnf.Monitor
|
||||
htc = &cnf.HTTPClient
|
||||
}
|
||||
|
||||
case ConfigStandard:
|
||||
cnf := cfgstd.Model{}
|
||||
if e := vpr.UnmarshalKey(key, &cnf); e != nil {
|
||||
return nil, nil, nil, ErrorParamInvalid.ErrorParent(e)
|
||||
} else {
|
||||
flg.updStandard(&cnf)
|
||||
}
|
||||
|
||||
if cfg, err = o.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, nil, err
|
||||
} else {
|
||||
mon = nil
|
||||
htc = nil
|
||||
}
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, nil, nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return cfg, mon, htc, nil
|
||||
}
|
||||
|
||||
func (o *componentAws) _getFlagUpdate() *_configFlag {
|
||||
var (
|
||||
cfg = &_configFlag{
|
||||
accessKey: nil,
|
||||
secretKey: nil,
|
||||
bucket: nil,
|
||||
region: nil,
|
||||
endpoint: nil,
|
||||
}
|
||||
vpr *spfvpr.Viper
|
||||
key string
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s := vpr.GetString(key + ".access-key"); s != "" {
|
||||
cfg.accessKey = &s
|
||||
}
|
||||
if s := vpr.GetString(key + ".secret-key"); s != "" {
|
||||
cfg.secretKey = &s
|
||||
}
|
||||
if s := vpr.GetString(key + ".bucket"); s != "" {
|
||||
cfg.bucket = &s
|
||||
}
|
||||
if s := vpr.GetString(key + ".region"); s != "" {
|
||||
cfg.region = &s
|
||||
}
|
||||
if s := vpr.GetString(key + ".endpoint"); s != "" {
|
||||
cfg.endpoint = &s
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
@@ -30,14 +30,9 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libaws "github.com/nabbar/golib/aws"
|
||||
cfgstd "github.com/nabbar/golib/aws/configAws"
|
||||
cfgcus "github.com/nabbar/golib/aws/configCustom"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libsts "github.com/nabbar/golib/status/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgcst "github.com/nabbar/golib/config/const"
|
||||
libhtc "github.com/nabbar/golib/httpcli"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
var _defaultConfigStandard = []byte(`{
|
||||
@@ -49,12 +44,9 @@ var _defaultConfigStandard = []byte(`{
|
||||
}`)
|
||||
|
||||
var _defaultConfigStandardWithStatus = []byte(`{
|
||||
"bucket": "",
|
||||
"accesskey": "",
|
||||
"secretkey": "",
|
||||
"region": "",
|
||||
"endpoint": "",
|
||||
"status":` + string(libsts.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
"config":` + string(DefaultConfigStandard(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"http-client":` + string(libhtc.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"monitor":` + string(montps.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `
|
||||
}`)
|
||||
|
||||
var _defaultConfigCustom = []byte(`{
|
||||
@@ -66,12 +58,9 @@ var _defaultConfigCustom = []byte(`{
|
||||
}`)
|
||||
|
||||
var _defaultConfigCustomWithStatus = []byte(`{
|
||||
"bucket": "",
|
||||
"accesskey": "",
|
||||
"secretkey": "",
|
||||
"region": "",
|
||||
"endpoint": "",
|
||||
"status":` + string(libsts.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
"config":` + string(DefaultConfigCustom(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"http-client":` + string(libhtc.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"monitor":` + string(montps.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `
|
||||
}`)
|
||||
|
||||
var _defaultConfig = _defaultConfigCustom
|
||||
@@ -96,145 +85,51 @@ func SetDefaultConfigCustom(withStatus bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
func DefaultConfigStandard(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfigStandard, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentAws) DefaultConfig(indent string) []byte {
|
||||
func DefaultConfigStandardStatus(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfigStandardWithStatus, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultConfigCustom(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfigCustom, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultConfigCustomStatus(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfigCustomWithStatus, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentAws) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
_ = Command.PersistentFlags().String(c.key+".access-key", "", "AWS Access Key")
|
||||
_ = Command.PersistentFlags().String(c.key+".secret-key", "", "AWS Secret Key")
|
||||
_ = Command.PersistentFlags().String(c.key+".bucket", "", "Bucket to use")
|
||||
_ = Command.PersistentFlags().String(c.key+".region", "", "Region for bucket")
|
||||
_ = Command.PersistentFlags().String(c.key+".endpoint", "", "Endpoint if necessary for the region")
|
||||
|
||||
if err := Viper.BindPFlag(c.key+".access-key", Command.PersistentFlags().Lookup(c.key+".access-key")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".secret-key", Command.PersistentFlags().Lookup(c.key+".secret-key")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".bucket", Command.PersistentFlags().Lookup(c.key+".bucket")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".region", Command.PersistentFlags().Lookup(c.key+".region")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".endpoint", Command.PersistentFlags().Lookup(c.key+".endpoint")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentAws) _getConfig(getCfg libcfg.FuncComponentConfigGet) (libaws.Config, *libsts.ConfigStatus, liberr.Error) {
|
||||
var (
|
||||
vpr = c.vpr()
|
||||
cfg libaws.Config
|
||||
sts *libsts.ConfigStatus
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
switch c.d {
|
||||
case ConfigCustomStatus:
|
||||
cnf := cfgcus.ModelStatus{}
|
||||
if e := getCfg(c.key, &cnf); e != nil {
|
||||
return nil, nil, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".access-key"); s != "" {
|
||||
cnf.Config.AccessKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".secret-key"); s != "" {
|
||||
cnf.Config.SecretKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".bucket"); s != "" {
|
||||
cnf.Config.Bucket = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".region"); s != "" {
|
||||
cnf.Config.Region = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".endpoint"); s != "" {
|
||||
cnf.Config.Endpoint = s
|
||||
}
|
||||
if cfg, err = c.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, err
|
||||
} else {
|
||||
sts = &cnf.Status
|
||||
}
|
||||
case ConfigCustom:
|
||||
cnf := cfgcus.Model{}
|
||||
if e := getCfg(c.key, &cnf); e != nil {
|
||||
return nil, nil, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".access-key"); s != "" {
|
||||
cnf.AccessKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".secret-key"); s != "" {
|
||||
cnf.SecretKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".bucket"); s != "" {
|
||||
cnf.Bucket = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".region"); s != "" {
|
||||
cnf.Region = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".endpoint"); s != "" {
|
||||
cnf.Endpoint = s
|
||||
}
|
||||
if cfg, err = c.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
case ConfigStandardStatus:
|
||||
cnf := cfgstd.ModelStatus{}
|
||||
if e := getCfg(c.key, &cnf); e != nil {
|
||||
return nil, nil, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".access-key"); s != "" {
|
||||
cnf.Config.AccessKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".secret-key"); s != "" {
|
||||
cnf.Config.SecretKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".bucket"); s != "" {
|
||||
cnf.Config.Bucket = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".region"); s != "" {
|
||||
cnf.Config.Region = s
|
||||
}
|
||||
if cfg, err = c.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, err
|
||||
} else {
|
||||
sts = &cnf.Status
|
||||
}
|
||||
case ConfigStandard:
|
||||
cnf := cfgstd.Model{}
|
||||
if e := getCfg(c.key, &cnf); e != nil {
|
||||
return nil, nil, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".access-key"); s != "" {
|
||||
cnf.AccessKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".secret-key"); s != "" {
|
||||
cnf.SecretKey = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".bucket"); s != "" {
|
||||
cnf.Bucket = s
|
||||
}
|
||||
if s := vpr.GetString(c.key + ".region"); s != "" {
|
||||
cnf.Region = s
|
||||
}
|
||||
if cfg, err = c.d.NewFromModel(cnf); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return cfg, sts, nil
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ const (
|
||||
ErrorParamInvalid
|
||||
ErrorComponentNotInitialized
|
||||
ErrorConfigInvalid
|
||||
ErrorStartComponent
|
||||
ErrorReloadComponent
|
||||
ErrorComponentStart
|
||||
ErrorComponentReload
|
||||
ErrorDependencyLogDefault
|
||||
)
|
||||
|
||||
@@ -60,9 +60,9 @@ func getMessage(code liberr.CodeError) (message string) {
|
||||
return "this component seems to not be correctly initialized"
|
||||
case ErrorConfigInvalid:
|
||||
return "invalid component config"
|
||||
case ErrorStartComponent:
|
||||
case ErrorComponentStart:
|
||||
return "cannot start component with config"
|
||||
case ErrorReloadComponent:
|
||||
case ErrorComponentReload:
|
||||
return "cannot reload component with new config"
|
||||
case ErrorDependencyLogDefault:
|
||||
return "cannot retrieve default Logger"
|
||||
|
||||
@@ -31,32 +31,36 @@ import (
|
||||
"sync"
|
||||
|
||||
libaws "github.com/nabbar/golib/aws"
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "aws"
|
||||
)
|
||||
type ComponentAwsClient interface {
|
||||
cfgtps.Component
|
||||
RegisterHTTPClient(fct func() *http.Client)
|
||||
}
|
||||
|
||||
type ComponentAwsAPI interface {
|
||||
cfgtps.Component
|
||||
RegisterTLS(fct libtls.FctTLSDefault)
|
||||
}
|
||||
|
||||
type ComponentAws interface {
|
||||
libcfg.Component
|
||||
RegisterHTTPClient(fct func() *http.Client)
|
||||
ComponentAwsClient
|
||||
ComponentAwsAPI
|
||||
|
||||
GetAws() (libaws.AWS, liberr.Error)
|
||||
SetAws(a libaws.AWS)
|
||||
}
|
||||
|
||||
func New(drv ConfigDriver) ComponentAws {
|
||||
return &componentAws{
|
||||
ctx: nil,
|
||||
get: nil,
|
||||
fsa: nil,
|
||||
fsb: nil,
|
||||
fra: nil,
|
||||
frb: nil,
|
||||
m: sync.Mutex{},
|
||||
d: drv,
|
||||
a: nil,
|
||||
m: sync.RWMutex{},
|
||||
x: nil,
|
||||
d: drv,
|
||||
a: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +72,7 @@ func RegisterNew(cfg libcfg.Config, drv ConfigDriver, key string) {
|
||||
cfg.ComponentSet(key, New(drv))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentAws {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentAws {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentAws); !ok {
|
||||
|
||||
@@ -31,177 +31,50 @@ import (
|
||||
"sync"
|
||||
|
||||
libaws "github.com/nabbar/golib/aws"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
stscfg "github.com/nabbar/golib/status/config"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
type componentAws struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
sts libcfg.FuncRouteStatus
|
||||
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
fsi libsts.FctInfo
|
||||
fsh libsts.FctHealth
|
||||
|
||||
m sync.Mutex
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
d ConfigDriver
|
||||
p montps.FuncPool
|
||||
c func() *http.Client
|
||||
t libtls.FctTLSDefault
|
||||
a libaws.AWS
|
||||
s stscfg.ConfigStatus
|
||||
}
|
||||
|
||||
func (c *componentAws) _getHttpClient() *http.Client {
|
||||
if c.c == nil {
|
||||
return &http.Client{}
|
||||
}
|
||||
func (o *componentAws) RegisterHTTPClient(fct func() *http.Client) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
return c.c()
|
||||
o.c = fct
|
||||
}
|
||||
|
||||
func (c *componentAws) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentAws) RegisterTLS(fct libtls.FctTLSDefault) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if c.a != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
o.t = fct
|
||||
}
|
||||
|
||||
func (c *componentAws) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
func (o *componentAws) GetAws() (libaws.AWS, liberr.Error) {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentAws) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if cfg, sts, err := c._getConfig(getCfg); err != nil {
|
||||
return err
|
||||
} else if cli, er := libaws.New(c.ctx(), cfg, c._getHttpClient()); er != nil {
|
||||
return er
|
||||
} else {
|
||||
c.a = cli
|
||||
|
||||
if sts != nil && c.sts != nil && c.fsi != nil && c.fsh != nil {
|
||||
sts.RegisterStatus(c.sts(), c.key, c.fsi, c.fsh)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentAws) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentAws) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentAws) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentAws) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentAws) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentAws) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.a != nil
|
||||
}
|
||||
|
||||
func (c *componentAws) IsRunning(atLeast bool) bool {
|
||||
return c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentAws) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentAws) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentAws) Stop() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.a = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (c *componentAws) Dependencies() []string {
|
||||
return make([]string, 0)
|
||||
}
|
||||
|
||||
func (c *componentAws) RegisterHTTPClient(fct func() *http.Client) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.c = fct
|
||||
}
|
||||
|
||||
func (c *componentAws) GetAws() (libaws.AWS, liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.a == nil {
|
||||
if o.a == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
return c.a.Clone(c.ctx())
|
||||
return o.a.Clone(o.x.GetContext())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentAws) SetAws(a libaws.AWS) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentAws) SetAws(a libaws.AWS) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
c.a = a
|
||||
o.a = a
|
||||
}
|
||||
|
||||
178
config/components/aws/monitor.go
Normal file
178
config/components/aws/monitor.go
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 aws
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
libaws "github.com/nabbar/golib/aws"
|
||||
libmon "github.com/nabbar/golib/monitor"
|
||||
moninf "github.com/nabbar/golib/monitor/info"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultNameMonitor = "AWS Client"
|
||||
)
|
||||
|
||||
func (o *componentAws) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.p = fct
|
||||
}
|
||||
|
||||
func (o *componentAws) _getMonitorPool() montps.Pool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.p == nil {
|
||||
return nil
|
||||
} else if p := o.p(); p == nil {
|
||||
return nil
|
||||
} else {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _registerMonitor(cfg *montps.Config, aws libaws.Config) error {
|
||||
var (
|
||||
e error
|
||||
key = o._getKey()
|
||||
inf moninf.Info
|
||||
mon montps.Monitor
|
||||
res = make(map[string]interface{}, 0)
|
||||
vrs = o._getVersion()
|
||||
)
|
||||
|
||||
if o._getMonitorPool() == nil {
|
||||
return nil
|
||||
} else if len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if cfg == nil {
|
||||
return nil
|
||||
} else if aws == nil {
|
||||
return ErrorConfigInvalid.Error(nil)
|
||||
}
|
||||
|
||||
res["runtime"] = runtime.Version()[2:]
|
||||
|
||||
if vrs != nil {
|
||||
res["release"] = vrs.GetRelease()
|
||||
res["build"] = vrs.GetBuild()
|
||||
res["date"] = vrs.GetDate()
|
||||
res["endpoint"] = aws.GetEndpoint().Host
|
||||
res["region"] = aws.GetRegion()
|
||||
}
|
||||
|
||||
if inf, e = moninf.New(defaultNameMonitor); e != nil {
|
||||
return e
|
||||
} else if vrs != nil {
|
||||
inf.RegisterName(func() (string, error) {
|
||||
return fmt.Sprintf("%s %s", defaultNameMonitor, o._getKey()), nil
|
||||
})
|
||||
inf.RegisterInfo(func() (map[string]interface{}, error) {
|
||||
return res, nil
|
||||
})
|
||||
}
|
||||
|
||||
if mon = o._getMonitor(key, inf); mon == nil {
|
||||
if mon, e = o._newMonitor(inf); e != nil {
|
||||
return e
|
||||
} else if mon == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if e = mon.SetConfig(o.x.GetContext, *cfg); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
mon.SetHealthCheck(o.HealthCheck)
|
||||
|
||||
if e = mon.Restart(o.x.GetContext()); e != nil {
|
||||
return e
|
||||
} else if e = o._setMonitor(mon); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentAws) _newMonitor(inf montps.Info) (montps.Monitor, error) {
|
||||
if c, e := libmon.New(o.x.GetContext, inf); e != nil {
|
||||
return nil, e
|
||||
} else if c != nil {
|
||||
c.RegisterLoggerDefault(o.getLogger)
|
||||
return c, nil
|
||||
} else {
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentAws) _getMonitor(key string, inf montps.Info) montps.Monitor {
|
||||
var (
|
||||
mon libmon.Monitor
|
||||
pol = o._getMonitorPool()
|
||||
)
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mon = pol.MonitorGet(key)
|
||||
|
||||
if mon != nil {
|
||||
mon.InfoUpd(inf)
|
||||
mon.RegisterLoggerDefault(o.getLogger)
|
||||
}
|
||||
|
||||
return mon
|
||||
}
|
||||
|
||||
func (o *componentAws) _setMonitor(mon montps.Monitor) error {
|
||||
var pol = o._getMonitorPool()
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pol.MonitorSet(mon)
|
||||
}
|
||||
|
||||
func (o *componentAws) HealthCheck(ctx context.Context) error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if !o.IsStarted() {
|
||||
return fmt.Errorf("component not started")
|
||||
} else {
|
||||
return o.a.Config().Check(ctx)
|
||||
}
|
||||
}
|
||||
203
config/components/database/client.go
Normal file
203
config/components/database/client.go
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libdbs "github.com/nabbar/golib/database"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentDatabase) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getContext() context.Context {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.x.GetContext()
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _runCli() liberr.Error {
|
||||
var (
|
||||
err liberr.Error
|
||||
prt = ErrorComponentReload
|
||||
dbo libdbs.Database
|
||||
cfg *libdbs.Config
|
||||
)
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorComponentStart
|
||||
}
|
||||
|
||||
if cfg, err = o._getConfig(); err != nil {
|
||||
return prt.Error(err)
|
||||
}
|
||||
|
||||
if dbo, err = libdbs.New(cfg); err != nil {
|
||||
return prt.Error(err)
|
||||
}
|
||||
|
||||
o.Stop()
|
||||
|
||||
o.m.Lock()
|
||||
o.d = dbo
|
||||
o.m.Unlock()
|
||||
|
||||
if e := o._registerMonitor(cfg); e != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
168
config/components/database/component.go
Normal file
168
config/components/database/component.go
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 database
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "database"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentDatabase) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentDatabase) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentDatabase) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentDatabase) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentDatabase) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o != nil && o.d != nil
|
||||
}
|
||||
|
||||
func (o *componentDatabase) IsRunning() bool {
|
||||
if !o.IsStarted() {
|
||||
return false
|
||||
} else if db := o.GetDatabase(); db == nil {
|
||||
return false
|
||||
} else if e := db.CheckConn(); e != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (o *componentDatabase) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentDatabase) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentDatabase) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.d != nil {
|
||||
o.d.Close()
|
||||
}
|
||||
|
||||
o.d = nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentDatabase) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = make([]string, 0)
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
191
config/components/database/config.go
Normal file
191
config/components/database/config.go
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 database
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
libdbs "github.com/nabbar/golib/database"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentDatabase) RegisterFlag(Command *spfcbr.Command) error {
|
||||
var (
|
||||
key string
|
||||
vpr *spfvpr.Viper
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
_ = Command.PersistentFlags().String(key+".driver", "", "driver to use for the DSN. It must be one of mysql, psql, sqlite, sqlserver, clickhouse.")
|
||||
_ = Command.PersistentFlags().String(key+".name", "", "string to identify the instance into status.")
|
||||
_ = Command.PersistentFlags().String(key+".dsn", "", "string options to connect to database following database engine. See https://gorm.io/docs/connecting_to_the_database.html for more information.")
|
||||
_ = Command.PersistentFlags().Bool(key+".skip-default-transaction", false, "disable the default transaction for single create, update, delete operations.")
|
||||
_ = Command.PersistentFlags().Bool(key+".full-save-associations", false, "full save associations")
|
||||
_ = Command.PersistentFlags().Bool(key+".dry-run", false, "generate sql without execute")
|
||||
_ = Command.PersistentFlags().Bool(key+".prepare-stmt", false, "executes the given query in cached statement")
|
||||
_ = Command.PersistentFlags().Bool(key+".disable-automatic-ping", false, "is used to disable the automatic ping to the database server")
|
||||
_ = Command.PersistentFlags().Bool(key+".disable-foreign-key-constraint-when-migrating", false, "is used to disable the foreign key constraint when migrating the database")
|
||||
_ = Command.PersistentFlags().Bool(key+".disable-nested-transaction", false, "disable nested transaction")
|
||||
_ = Command.PersistentFlags().Bool(key+".allow-global-update", false, "allow global update")
|
||||
_ = Command.PersistentFlags().Bool(key+".query-fields", false, "executes the SQL query with all fields of the table")
|
||||
_ = Command.PersistentFlags().Int(key+".create-batch-size", 0, "default create batch size")
|
||||
_ = Command.PersistentFlags().Bool(key+".enable-connection-pool", false, "is used to create a connection pool")
|
||||
_ = Command.PersistentFlags().Int(key+".pool-max-idle-conns", 0, "sets the maximum number of connections idle in the connection pool if enable")
|
||||
_ = Command.PersistentFlags().Int(key+".pool-max-open-conns", 0, "sets the maximum number of connections open in the connection pool if enable")
|
||||
_ = Command.PersistentFlags().Duration(key+".pool-conn-max-lifetime", 5*time.Minute, "sets the maximum lifetime of connections in the connection pool if enable")
|
||||
_ = Command.PersistentFlags().Bool(key+".disabled", false, "allow to disable a database connection without clean his configuration")
|
||||
|
||||
if err := vpr.BindPFlag(key+".driver", Command.PersistentFlags().Lookup(key+".driver")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".name", Command.PersistentFlags().Lookup(key+".name")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".dsn", Command.PersistentFlags().Lookup(key+".dsn")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".skip-default-transaction", Command.PersistentFlags().Lookup(key+".skip-default-transaction")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".full-save-associations", Command.PersistentFlags().Lookup(key+".full-save-associations")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".dry-run", Command.PersistentFlags().Lookup(key+".dry-run")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".prepare-stmt", Command.PersistentFlags().Lookup(key+".prepare-stmt")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".disable-automatic-ping", Command.PersistentFlags().Lookup(key+".disable-automatic-ping")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".disable-foreign-key-constraint-when-migrating", Command.PersistentFlags().Lookup(key+".disable-foreign-key-constraint-when-migrating")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".disable-nested-transaction", Command.PersistentFlags().Lookup(key+".disable-nested-transaction")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".allow-global-update", Command.PersistentFlags().Lookup(key+".allow-global-update")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".query-fields", Command.PersistentFlags().Lookup(key+".query-fields")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".create-batch-size", Command.PersistentFlags().Lookup(key+".create-batch-size")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".enable-connection-pool", Command.PersistentFlags().Lookup(key+".enable-connection-pool")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".pool-max-idle-conns", Command.PersistentFlags().Lookup(key+".pool-max-idle-conns")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".pool-max-open-conns", Command.PersistentFlags().Lookup(key+".pool-max-open-conns")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".pool-conn-max-lifetime", Command.PersistentFlags().Lookup(key+".pool-conn-max-lifetime")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".disabled", Command.PersistentFlags().Lookup(key+".disabled")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getConfig() (*libdbs.Config, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg libdbs.Config
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
cfg.RegisterLogger(o.getLogger, o.li, o.ls)
|
||||
cfg.RegisterContext(o.x.GetContext)
|
||||
|
||||
if val := vpr.GetString(key + ".driver"); val != "" {
|
||||
cfg.Driver = libdbs.DriverFromString(val)
|
||||
}
|
||||
if val := vpr.GetString(key + ".name"); val != "" {
|
||||
cfg.Name = val
|
||||
}
|
||||
if val := vpr.GetString(key + ".dsn"); val != "" {
|
||||
cfg.DSN = val
|
||||
}
|
||||
if val := vpr.GetBool(key + ".skip-default-transaction"); val {
|
||||
cfg.SkipDefaultTransaction = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".full-save-associations"); val {
|
||||
cfg.FullSaveAssociations = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".dry-run"); val {
|
||||
cfg.DryRun = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".prepare-stmt"); val {
|
||||
cfg.PrepareStmt = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".disable-automatic-ping"); val {
|
||||
cfg.DisableAutomaticPing = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".disable-foreign-key-constraint-when-migrating"); val {
|
||||
cfg.DisableForeignKeyConstraintWhenMigrating = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".disable-nested-transaction"); val {
|
||||
cfg.DisableNestedTransaction = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".allow-global-update"); val {
|
||||
cfg.AllowGlobalUpdate = true
|
||||
}
|
||||
if val := vpr.GetBool(key + ".query-fields"); val {
|
||||
cfg.QueryFields = true
|
||||
}
|
||||
if val := vpr.GetInt(key + ".create-batch-size"); val != 0 {
|
||||
cfg.CreateBatchSize = val
|
||||
}
|
||||
if val := vpr.GetBool(key + ".enable-connection-pool"); val {
|
||||
cfg.EnableConnectionPool = true
|
||||
}
|
||||
if val := vpr.GetInt(key + ".pool-max-idle-conns"); val != 0 {
|
||||
cfg.PoolMaxIdleConns = val
|
||||
}
|
||||
if val := vpr.GetInt(key + ".pool-max-open-conns"); val != 0 {
|
||||
cfg.PoolMaxOpenConns = val
|
||||
}
|
||||
if val := vpr.GetDuration(key + ".pool-conn-max-lifetime"); val != 0 {
|
||||
cfg.PoolConnMaxLifetime = val
|
||||
}
|
||||
if val := vpr.GetBool(key + ".disabled"); val {
|
||||
cfg.Disabled = true
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -29,15 +29,9 @@ package database
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
libdbs "github.com/nabbar/golib/database"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libsts "github.com/nabbar/golib/status/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgcst "github.com/nabbar/golib/config/const"
|
||||
moncfg "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
@@ -59,7 +53,7 @@ var _defaultConfig = []byte(`{
|
||||
"pool-max-open-conns": 0,
|
||||
"pool-conn-max-lifetime": "0s",
|
||||
"disabled": false,
|
||||
"status": ` + string(libsts.DefaultConfig(libcfg.JSONIndent)) + `
|
||||
"monitor": ` + string(moncfg.DefaultConfig(cfgcst.JSONIndent)) + `
|
||||
}`)
|
||||
|
||||
func SetDefaultConfig(cfg []byte) {
|
||||
@@ -68,163 +62,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentDatabase) DefaultConfig(indent string) []byte {
|
||||
func (o *componentDatabase) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentDatabase) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
_ = Command.PersistentFlags().String(c.key+".driver", "", "driver to use for the DSN. It must be one of mysql, psql, sqlite, sqlserver, clickhouse.")
|
||||
_ = Command.PersistentFlags().String(c.key+".name", "", "string to identify the instance into status.")
|
||||
_ = Command.PersistentFlags().String(c.key+".dsn", "", "string options to connect to database following database engine. See https://gorm.io/docs/connecting_to_the_database.html for more information.")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".skip-default-transaction", false, "disable the default transaction for single create, update, delete operations.")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".full-save-associations", false, "full save associations")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".dry-run", false, "generate sql without execute")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".prepare-stmt", false, "executes the given query in cached statement")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disable-automatic-ping", false, "is used to disable the automatic ping to the database server")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disable-foreign-key-constraint-when-migrating", false, "is used to disable the foreign key constraint when migrating the database")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disable-nested-transaction", false, "disable nested transaction")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".allow-global-update", false, "allow global update")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".query-fields", false, "executes the SQL query with all fields of the table")
|
||||
_ = Command.PersistentFlags().Int(c.key+".create-batch-size", 0, "default create batch size")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".enable-connection-pool", false, "is used to create a connection pool")
|
||||
_ = Command.PersistentFlags().Int(c.key+".pool-max-idle-conns", 0, "sets the maximum number of connections idle in the connection pool if enable")
|
||||
_ = Command.PersistentFlags().Int(c.key+".pool-max-open-conns", 0, "sets the maximum number of connections open in the connection pool if enable")
|
||||
_ = Command.PersistentFlags().Duration(c.key+".pool-conn-max-lifetime", 5*time.Minute, "sets the maximum lifetime of connections in the connection pool if enable")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disabled", false, "allow to disable a database connection without clean his configuration")
|
||||
|
||||
if err := Viper.BindPFlag(c.key+".driver", Command.PersistentFlags().Lookup(c.key+".driver")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".name", Command.PersistentFlags().Lookup(c.key+".name")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".dsn", Command.PersistentFlags().Lookup(c.key+".dsn")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".skip-default-transaction", Command.PersistentFlags().Lookup(c.key+".skip-default-transaction")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".full-save-associations", Command.PersistentFlags().Lookup(c.key+".full-save-associations")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".dry-run", Command.PersistentFlags().Lookup(c.key+".dry-run")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".prepare-stmt", Command.PersistentFlags().Lookup(c.key+".prepare-stmt")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".disable-automatic-ping", Command.PersistentFlags().Lookup(c.key+".disable-automatic-ping")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".disable-foreign-key-constraint-when-migrating", Command.PersistentFlags().Lookup(c.key+".disable-foreign-key-constraint-when-migrating")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".disable-nested-transaction", Command.PersistentFlags().Lookup(c.key+".disable-nested-transaction")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".allow-global-update", Command.PersistentFlags().Lookup(c.key+".allow-global-update")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".query-fields", Command.PersistentFlags().Lookup(c.key+".query-fields")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".create-batch-size", Command.PersistentFlags().Lookup(c.key+".create-batch-size")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".enable-connection-pool", Command.PersistentFlags().Lookup(c.key+".enable-connection-pool")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".pool-max-idle-conns", Command.PersistentFlags().Lookup(c.key+".pool-max-idle-conns")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".pool-max-open-conns", Command.PersistentFlags().Lookup(c.key+".pool-max-open-conns")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".pool-conn-max-lifetime", Command.PersistentFlags().Lookup(c.key+".pool-conn-max-lifetime")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".disabled", Command.PersistentFlags().Lookup(c.key+".disabled")); err != nil {
|
||||
return err
|
||||
} else if err = libsts.RegisterFlag(c.key+".status", Command, Viper); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentDatabase) _getConfig(getCfg libcfg.FuncComponentConfigGet) (libdbs.Config, liberr.Error) {
|
||||
var (
|
||||
cnf = libdbs.Config{}
|
||||
vpr = c.vpr()
|
||||
)
|
||||
|
||||
if !c._CheckDep() {
|
||||
return cnf, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if err := getCfg(c.key, &cnf); err != nil {
|
||||
return cnf, ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
fct := func() liblog.Logger {
|
||||
if l, e := c._GetLogger(); e != nil {
|
||||
return liblog.GetDefault()
|
||||
} else {
|
||||
return l
|
||||
}
|
||||
}
|
||||
|
||||
cnf.RegisterLogger(fct, c.li, c.ls)
|
||||
cnf.RegisterContext(c.ctx)
|
||||
|
||||
if val := vpr.GetString(c.key + ".driver"); val != "" {
|
||||
cnf.Driver = libdbs.DriverFromString(val)
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".name"); val != "" {
|
||||
cnf.Name = val
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".dsn"); val != "" {
|
||||
cnf.DSN = val
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".skip-default-transaction"); val {
|
||||
cnf.SkipDefaultTransaction = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".full-save-associations"); val {
|
||||
cnf.FullSaveAssociations = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".dry-run"); val {
|
||||
cnf.DryRun = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".prepare-stmt"); val {
|
||||
cnf.PrepareStmt = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".disable-automatic-ping"); val {
|
||||
cnf.DisableAutomaticPing = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".disable-foreign-key-constraint-when-migrating"); val {
|
||||
cnf.DisableForeignKeyConstraintWhenMigrating = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".disable-nested-transaction"); val {
|
||||
cnf.DisableNestedTransaction = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".allow-global-update"); val {
|
||||
cnf.AllowGlobalUpdate = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".query-fields"); val {
|
||||
cnf.QueryFields = true
|
||||
}
|
||||
if val := vpr.GetInt(c.key + ".create-batch-size"); val != 0 {
|
||||
cnf.CreateBatchSize = val
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".enable-connection-pool"); val {
|
||||
cnf.EnableConnectionPool = true
|
||||
}
|
||||
if val := vpr.GetInt(c.key + ".pool-max-idle-conns"); val != 0 {
|
||||
cnf.PoolMaxIdleConns = val
|
||||
}
|
||||
if val := vpr.GetInt(c.key + ".pool-max-open-conns"); val != 0 {
|
||||
cnf.PoolMaxOpenConns = val
|
||||
}
|
||||
if val := vpr.GetDuration(c.key + ".pool-conn-max-lifetime"); val != 0 {
|
||||
cnf.PoolConnMaxLifetime = val
|
||||
}
|
||||
if val := vpr.GetBool(c.key + ".disabled"); val {
|
||||
cnf.Disabled = true
|
||||
}
|
||||
|
||||
if err := cnf.Validate(); err != nil {
|
||||
return cnf, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return cnf, nil
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ const (
|
||||
ErrorParamInvalid
|
||||
ErrorComponentNotInitialized
|
||||
ErrorConfigInvalid
|
||||
ErrorStartDatabase
|
||||
ErrorReloadDatabase
|
||||
ErrorComponentStart
|
||||
ErrorComponentReload
|
||||
ErrorDependencyLogDefault
|
||||
)
|
||||
|
||||
@@ -60,9 +60,9 @@ func getMessage(code liberr.CodeError) (message string) {
|
||||
return "this component seems to not be correctly initialized"
|
||||
case ErrorConfigInvalid:
|
||||
return "server invalid config"
|
||||
case ErrorStartDatabase:
|
||||
case ErrorComponentStart:
|
||||
return "cannot open database connection with config"
|
||||
case ErrorReloadDatabase:
|
||||
case ErrorComponentReload:
|
||||
return "cannot update database connection with new config"
|
||||
case ErrorDependencyLogDefault:
|
||||
return "cannot retrieve default Logger"
|
||||
|
||||
@@ -31,27 +31,26 @@ import (
|
||||
"time"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
libdbs "github.com/nabbar/golib/database"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "database"
|
||||
)
|
||||
|
||||
type ComponentDatabase interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
SetLOGKey(logKey string)
|
||||
SetLogOptions(ignoreRecordNotFoundError bool, slowThreshold time.Duration)
|
||||
GetDatabase() libdbs.Database
|
||||
SetDatabase(db libdbs.Database)
|
||||
}
|
||||
|
||||
func New(logKey string) ComponentDatabase {
|
||||
func New(ctx libctx.FuncContext) ComponentDatabase {
|
||||
return &componentDatabase{
|
||||
m: sync.Mutex{},
|
||||
l: logKey,
|
||||
d: nil,
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
li: false,
|
||||
ls: 0,
|
||||
d: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,11 +58,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentDatabase) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key, logKey string) {
|
||||
cfg.ComponentSet(key, New(logKey))
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New(ctx))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentDatabase {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentDatabase {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentDatabase); !ok {
|
||||
|
||||
@@ -30,212 +30,38 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cptlog "github.com/nabbar/golib/config/components/log"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
libdbs "github.com/nabbar/golib/database"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
type componentDatabase struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
l string
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
li bool
|
||||
ls time.Duration
|
||||
d libdbs.Database
|
||||
p montps.FuncPool
|
||||
}
|
||||
|
||||
func (c *componentDatabase) _CheckDep() bool {
|
||||
return c != nil && c.l != ""
|
||||
func (o *componentDatabase) SetLogOptions(ignoreRecordNotFoundError bool, slowThreshold time.Duration) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.li = ignoreRecordNotFoundError
|
||||
o.ls = slowThreshold
|
||||
}
|
||||
|
||||
func (c *componentDatabase) _GetLogger() (liblog.Logger, liberr.Error) {
|
||||
if !c._CheckDep() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
func (o *componentDatabase) SetDatabase(db libdbs.Database) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if i := cptlog.Load(c.get, c.l); i == nil {
|
||||
return nil, ErrorDependencyLogDefault.Error(nil)
|
||||
} else if log := i.Log(); log == nil {
|
||||
return nil, ErrorDependencyLogDefault.Error(nil)
|
||||
} else {
|
||||
return log, nil
|
||||
}
|
||||
o.d = db
|
||||
}
|
||||
|
||||
func (c *componentDatabase) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
var isReload = c.IsStarted()
|
||||
func (o *componentDatabase) GetDatabase() libdbs.Database {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if isReload {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentDatabase) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentDatabase) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
var (
|
||||
err liberr.Error
|
||||
cnf libdbs.Config
|
||||
)
|
||||
|
||||
if cnf, err = c._getConfig(getCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.d != nil {
|
||||
c.d.Close()
|
||||
}
|
||||
|
||||
if c.d, err = libdbs.New(&cnf); err != nil {
|
||||
return ErrorStartDatabase.Error(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentDatabase) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
if !c._CheckDep() {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (c *componentDatabase) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentDatabase) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentDatabase) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentDatabase) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentDatabase) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c == nil || c.d == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if db := c.GetDatabase(); db == nil {
|
||||
return false
|
||||
} else if e := db.CheckConn(); e != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *componentDatabase) IsRunning(atLeast bool) bool {
|
||||
return c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentDatabase) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentDatabase) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentDatabase) Stop() {
|
||||
if db := c.GetDatabase(); db != nil {
|
||||
db.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentDatabase) Dependencies() []string {
|
||||
if c == nil {
|
||||
return []string{cptlog.ComponentType}
|
||||
}
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return []string{c.l}
|
||||
}
|
||||
|
||||
func (c *componentDatabase) SetLOGKey(logKey string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.l = logKey
|
||||
}
|
||||
|
||||
func (c *componentDatabase) SetLogOptions(ignoreRecordNotFoundError bool, slowThreshold time.Duration) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.li = ignoreRecordNotFoundError
|
||||
c.ls = slowThreshold
|
||||
}
|
||||
|
||||
func (c *componentDatabase) SetDatabase(db libdbs.Database) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.d = db
|
||||
}
|
||||
|
||||
func (c *componentDatabase) GetDatabase() libdbs.Database {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.d
|
||||
return o.d
|
||||
}
|
||||
|
||||
133
config/components/database/monitor.go
Normal file
133
config/components/database/monitor.go
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 database
|
||||
|
||||
import (
|
||||
libdbs "github.com/nabbar/golib/database"
|
||||
libmon "github.com/nabbar/golib/monitor"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
)
|
||||
|
||||
func (o *componentDatabase) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.p = fct
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getMonitorPool() montps.Pool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.p == nil {
|
||||
return nil
|
||||
} else if p := o.p(); p == nil {
|
||||
return nil
|
||||
} else {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _registerMonitor(cfg *libdbs.Config) error {
|
||||
var (
|
||||
e error
|
||||
key = o._getKey()
|
||||
mon libmon.Monitor
|
||||
vrs = o._getVersion()
|
||||
)
|
||||
|
||||
if o._getMonitorPool() == nil {
|
||||
return nil
|
||||
} else if len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if cfg == nil {
|
||||
return ErrorConfigInvalid.Error(nil)
|
||||
} else if !o.IsStarted() {
|
||||
return ErrorComponentStart.Error(nil)
|
||||
}
|
||||
|
||||
if mon = o._getMonitor(key); mon == nil {
|
||||
if mon, e = o._newMonitor(vrs); e != nil {
|
||||
return e
|
||||
} else if mon == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if e = mon.SetConfig(o.x.GetContext, cfg.Monitor); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if e = mon.Restart(o.x.GetContext()); e != nil {
|
||||
return e
|
||||
} else if e = o._setMonitor(mon); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _newMonitor(vrs libver.Version) (libmon.Monitor, error) {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
if c, e := o.d.Monitor(vrs); e != nil {
|
||||
return nil, e
|
||||
} else {
|
||||
c.RegisterLoggerDefault(o.getLogger)
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _getMonitor(key string) libmon.Monitor {
|
||||
var (
|
||||
mon libmon.Monitor
|
||||
pol = o._getMonitorPool()
|
||||
)
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mon = pol.MonitorGet(key)
|
||||
|
||||
if mon != nil {
|
||||
mon.RegisterLoggerDefault(o.getLogger)
|
||||
}
|
||||
|
||||
return mon
|
||||
}
|
||||
|
||||
func (o *componentDatabase) _setMonitor(mon libmon.Monitor) error {
|
||||
var pol = o._getMonitorPool()
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pol.MonitorSet(mon)
|
||||
}
|
||||
172
config/components/head/client.go
Normal file
172
config/components/head/client.go
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 head
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentHead) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentHead) _runCli() liberr.Error {
|
||||
if cfg, err := o._getConfig(); err != nil {
|
||||
return ErrorParamInvalid.Error(err)
|
||||
} else {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.h = cfg.New()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
155
config/components/head/component.go
Normal file
155
config/components/head/component.go
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 head
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "head"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentHead) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentHead) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentHead) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentHead) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentHead) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.h != nil
|
||||
}
|
||||
|
||||
func (o *componentHead) IsRunning() bool {
|
||||
return o.IsStarted()
|
||||
}
|
||||
|
||||
func (o *componentHead) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentHead) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentHead) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.h = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentHead) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = make([]string, 0)
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHead) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
63
config/components/head/config.go
Normal file
63
config/components/head/config.go
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 head
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
librtr "github.com/nabbar/golib/router"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentHead) RegisterFlag(Command *spfcbr.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentHead) _getConfig() (*librtr.HeadersConfig, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg librtr.HeadersConfig
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -30,9 +30,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgcst "github.com/nabbar/golib/config/const"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
@@ -51,17 +49,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentHead) DefaultConfig(indent string) []byte {
|
||||
func (o *componentHead) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentHead) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -27,16 +27,15 @@
|
||||
package head
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
librtr "github.com/nabbar/golib/router"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "head"
|
||||
)
|
||||
|
||||
type ComponentHead interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
GetHeaders() librtr.Headers
|
||||
SetHeaders(head librtr.Headers)
|
||||
@@ -44,6 +43,7 @@ type ComponentHead interface {
|
||||
|
||||
func New() ComponentHead {
|
||||
return &componentHead{
|
||||
m: sync.RWMutex{},
|
||||
h: nil,
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func RegisterNew(cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New())
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentHead {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentHead {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentHead); !ok {
|
||||
|
||||
@@ -29,139 +29,26 @@ package head
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
librtr "github.com/nabbar/golib/router"
|
||||
)
|
||||
|
||||
type componentHead struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
h librtr.Headers
|
||||
}
|
||||
|
||||
func (c *componentHead) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentHead) GetHeaders() librtr.Headers {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if c.h != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
return o.h
|
||||
}
|
||||
|
||||
func (c *componentHead) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
func (o *componentHead) SetHeaders(head librtr.Headers) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentHead) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
cnf := librtr.HeadersConfig{}
|
||||
if err := getCfg(c.key, &cnf); err != nil {
|
||||
return ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
c.h = cnf.New()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentHead) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentHead) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentHead) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentHead) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentHead) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentHead) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.h != nil
|
||||
}
|
||||
|
||||
func (c *componentHead) IsRunning(atLeast bool) bool {
|
||||
return c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentHead) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentHead) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentHead) Stop() {
|
||||
|
||||
}
|
||||
|
||||
func (c *componentHead) Dependencies() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (c *componentHead) GetHeaders() librtr.Headers {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.h
|
||||
}
|
||||
|
||||
func (c *componentHead) SetHeaders(head librtr.Headers) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.h = head
|
||||
o.h = head
|
||||
}
|
||||
|
||||
34
config/components/head/monitor.go
Normal file
34
config/components/head/monitor.go
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 head
|
||||
|
||||
import (
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
func (o *componentHead) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
}
|
||||
248
config/components/http/client.go
Normal file
248
config/components/http/client.go
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
htpool "github.com/nabbar/golib/httpserver/pool"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentHttp) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getContext() context.Context {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.x.GetContext()
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _GetTLS() libtls.TLSConfig {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.t == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if i := cpttls.Load(o._getFctCpt(), o.t); i == nil {
|
||||
return nil
|
||||
} else if tls := i.GetTLS(); tls == nil {
|
||||
return nil
|
||||
} else {
|
||||
return tls
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _GetHandler() map[string]http.Handler {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.h == nil {
|
||||
return nil
|
||||
} else {
|
||||
return o.h()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentHttp) _runCli() liberr.Error {
|
||||
var (
|
||||
e error
|
||||
err liberr.Error
|
||||
prt = ErrorComponentReload
|
||||
pol htpool.Pool
|
||||
cfg *htpool.Config
|
||||
)
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorComponentStart
|
||||
}
|
||||
|
||||
if cfg, err = o._getConfig(); err != nil {
|
||||
return prt.Error(err)
|
||||
}
|
||||
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if pol, err = cfg.Pool(o.x.GetContext, o._GetHandler, o.getLogger); err != nil {
|
||||
return prt.ErrorParent(err)
|
||||
}
|
||||
|
||||
if o.s != nil && o.s.Len() > 0 {
|
||||
if e = o.s.Merge(pol, o.getLogger); e != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
} else {
|
||||
o.m.RUnlock()
|
||||
o.m.Lock()
|
||||
o.s = pol
|
||||
o.m.Unlock()
|
||||
o.m.RLock()
|
||||
}
|
||||
|
||||
if e = o.s.Restart(o.x.GetContext()); e != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
|
||||
// Implement wait notify on main call
|
||||
//o.s.StopWaitNotify()
|
||||
//o.s.StartWaitNotify(o.x.GetContext())
|
||||
|
||||
return o._registerMonitor(prt)
|
||||
}
|
||||
|
||||
func (o *componentHttp) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
168
config/components/http/component.go
Normal file
168
config/components/http/component.go
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 http
|
||||
|
||||
import (
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "http"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentHttp) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentHttp) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentHttp) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentHttp) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentHttp) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o != nil && o.s != nil && o.t != "" && o.h != nil
|
||||
}
|
||||
|
||||
func (o *componentHttp) IsRunning() bool {
|
||||
if !o.IsStarted() {
|
||||
return false
|
||||
}
|
||||
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.s.IsRunning()
|
||||
}
|
||||
|
||||
func (o *componentHttp) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentHttp) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentHttp) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
_ = o.s.Stop(o.x.GetContext())
|
||||
o.s = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentHttp) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = []string{cpttls.ComponentType}
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if len(o.t) > 0 {
|
||||
def = []string{o.t}
|
||||
}
|
||||
|
||||
if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
@@ -24,64 +24,50 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package nutsdb
|
||||
package http
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
"fmt"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cptlog "github.com/nabbar/golib/config/components/log"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libndb "github.com/nabbar/golib/nutsdb"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
htpool "github.com/nabbar/golib/httpserver/pool"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "nutsdb"
|
||||
)
|
||||
|
||||
type ComponentNutsDB interface {
|
||||
libcfg.Component
|
||||
|
||||
SetLogger(key string)
|
||||
GetServer() (libndb.NutsDB, liberr.Error)
|
||||
GetClient(tickSync time.Duration) (libndb.Client, liberr.Error)
|
||||
SetStatusRouter(sts libsts.RouteStatus, prefix string)
|
||||
func (o *componentHttp) RegisterFlag(Command *spfcbr.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func New(logKey string) ComponentNutsDB {
|
||||
if logKey == "" {
|
||||
logKey = cptlog.ComponentType
|
||||
func (o *componentHttp) _getConfig() (*htpool.Config, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg htpool.Config
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
return &componentNutsDB{
|
||||
ctx: nil,
|
||||
get: nil,
|
||||
fsa: nil,
|
||||
fsb: nil,
|
||||
fra: nil,
|
||||
frb: nil,
|
||||
m: sync.Mutex{},
|
||||
l: logKey,
|
||||
n: nil,
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
}
|
||||
|
||||
func Register(cfg libcfg.Config, key string, cpt ComponentNutsDB) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
cfg.SetDefaultTLS(o._GetTLS)
|
||||
cfg.SetContext(o.x.GetContext)
|
||||
cfg.SetHandlerFunc(o._GetHandler)
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key, logKey string) {
|
||||
cfg.ComponentSet(key, New(logKey))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentNutsDB {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentNutsDB); !ok {
|
||||
return nil
|
||||
} else {
|
||||
return h
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
} else if o.h == nil {
|
||||
return nil, ErrorComponentNotInitialized.ErrorParent(fmt.Errorf("missing handler"))
|
||||
} else if len(o.h()) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.ErrorParent(fmt.Errorf("missing handler"))
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -30,21 +30,20 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
libsts "github.com/nabbar/golib/status/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgcst "github.com/nabbar/golib/config/const"
|
||||
cptlog "github.com/nabbar/golib/logger/config"
|
||||
moncfg "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`[
|
||||
{
|
||||
"disabled":false,
|
||||
"name":"status_http",
|
||||
"handler_keys":"status",
|
||||
"handler_key":"status",
|
||||
"listen":"0.0.0.0:6080",
|
||||
"expose":"http://0.0.0.0",
|
||||
"status":` + string(libsts.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `,
|
||||
"monitor":` + string(moncfg.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"read_timeout":"0s",
|
||||
"read_header_timeout":"0s",
|
||||
"write_timeout":"0s",
|
||||
@@ -57,15 +56,16 @@ var _defaultConfig = []byte(`[
|
||||
"max_upload_buffer_per_connection":0,
|
||||
"max_upload_buffer_per_stream":0,
|
||||
"tls_mandatory":false,
|
||||
"tls": ` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
"tls":` + string(cpttls.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"logger":` + string(cptlog.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `
|
||||
},
|
||||
{
|
||||
"disabled":false,
|
||||
"name":"api_http",
|
||||
"handler_keys":"api",
|
||||
"handler_key":"api",
|
||||
"listen":"0.0.0.0:7080",
|
||||
"expose":"http://0.0.0.0",
|
||||
"status":` + string(libsts.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `,
|
||||
"monitor":` + string(moncfg.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"read_timeout":"0s",
|
||||
"read_header_timeout":"0s",
|
||||
"write_timeout":"0s",
|
||||
@@ -78,15 +78,16 @@ var _defaultConfig = []byte(`[
|
||||
"max_upload_buffer_per_connection":0,
|
||||
"max_upload_buffer_per_stream":0,
|
||||
"tls_mandatory":false,
|
||||
"tls":` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
"tls":` + string(cpttls.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"logger":` + string(cptlog.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `
|
||||
},
|
||||
{
|
||||
"disabled":false,
|
||||
"name":"metrics_http",
|
||||
"handler_keys":"metrics",
|
||||
"handler_key":"metrics",
|
||||
"listen":"0.0.0.0:8080",
|
||||
"expose":"http://0.0.0.0",
|
||||
"status":` + string(libsts.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `,
|
||||
"monitor":` + string(moncfg.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"read_timeout":"0s",
|
||||
"read_header_timeout":"0s",
|
||||
"write_timeout":"0s",
|
||||
@@ -99,7 +100,8 @@ var _defaultConfig = []byte(`[
|
||||
"max_upload_buffer_per_connection":0,
|
||||
"max_upload_buffer_per_stream":0,
|
||||
"tls_mandatory":false,
|
||||
"tls":` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
"tls":` + string(cpttls.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `,
|
||||
"logger":` + string(cptlog.DefaultConfig(cfgcst.JSONIndent+cfgcst.JSONIndent)) + `
|
||||
}
|
||||
]`)
|
||||
|
||||
@@ -109,17 +111,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentHttp) DefaultConfig(indent string) []byte {
|
||||
func (o *componentHttp) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentHttp) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -38,10 +38,9 @@ const (
|
||||
ErrorParamInvalid
|
||||
ErrorComponentNotInitialized
|
||||
ErrorConfigInvalid
|
||||
ErrorStartComponent
|
||||
ErrorReloadComponent
|
||||
ErrorComponentStart
|
||||
ErrorComponentReload
|
||||
ErrorDependencyTLSDefault
|
||||
ErrorDependencyLogDefault
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -61,14 +60,12 @@ func getMessage(code liberr.CodeError) (message string) {
|
||||
return "this component seems to not be correctly initialized"
|
||||
case ErrorConfigInvalid:
|
||||
return "invalid component config"
|
||||
case ErrorStartComponent:
|
||||
case ErrorComponentStart:
|
||||
return "cannot start component with config"
|
||||
case ErrorReloadComponent:
|
||||
case ErrorComponentReload:
|
||||
return "cannot reload component with new config"
|
||||
case ErrorDependencyTLSDefault:
|
||||
return "cannot retrieve TLS component"
|
||||
case ErrorDependencyLogDefault:
|
||||
return "cannot retrieve Logger Component"
|
||||
}
|
||||
|
||||
return liberr.NullMessage
|
||||
|
||||
@@ -27,46 +27,41 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
libhts "github.com/nabbar/golib/httpserver"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
htpool "github.com/nabbar/golib/httpserver/pool"
|
||||
srvtps "github.com/nabbar/golib/httpserver/types"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultTlsKey = "tls"
|
||||
DefaultLogKey = "log"
|
||||
ComponentType = "http"
|
||||
DefaultTlsKey = "t"
|
||||
)
|
||||
|
||||
type ComponentHttp interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
SetTLSKey(tlsKey string)
|
||||
SetLOGKey(logKey string)
|
||||
SetHandler(handler map[string]http.Handler)
|
||||
SetHandler(fct srvtps.FuncHandler)
|
||||
|
||||
GetPool() libhts.PoolServer
|
||||
SetPool(pool libhts.PoolServer)
|
||||
GetPool() htpool.Pool
|
||||
SetPool(pool htpool.Pool)
|
||||
}
|
||||
|
||||
func New(tlsKey, logKey string, handler map[string]http.Handler) ComponentHttp {
|
||||
func New(ctx libctx.FuncContext, tlsKey string, hdl srvtps.FuncHandler) ComponentHttp {
|
||||
if tlsKey == "" {
|
||||
tlsKey = DefaultTlsKey
|
||||
}
|
||||
|
||||
if logKey == "" {
|
||||
logKey = DefaultLogKey
|
||||
}
|
||||
|
||||
return &componentHttp{
|
||||
m: sync.Mutex{},
|
||||
tls: tlsKey,
|
||||
log: logKey,
|
||||
run: false,
|
||||
hand: handler,
|
||||
pool: nil,
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
t: tlsKey,
|
||||
h: hdl,
|
||||
s: nil,
|
||||
p: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,11 +69,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentHttp) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key string, tlsKey, logKey string, handler map[string]http.Handler) {
|
||||
cfg.ComponentSet(key, New(tlsKey, logKey, handler))
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string, tlsKey string, hdl srvtps.FuncHandler) {
|
||||
cfg.ComponentSet(key, New(ctx, tlsKey, hdl))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentHttp {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentHttp {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentHttp); !ok {
|
||||
|
||||
@@ -27,302 +27,48 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cptlog "github.com/nabbar/golib/config/components/log"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libhts "github.com/nabbar/golib/httpserver"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
htpool "github.com/nabbar/golib/httpserver/pool"
|
||||
srvtps "github.com/nabbar/golib/httpserver/types"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
type componentHttp struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
sts libcfg.FuncRouteStatus
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
|
||||
tls string
|
||||
log string
|
||||
|
||||
run bool
|
||||
hand map[string]http.Handler
|
||||
|
||||
pool libhts.PoolServer
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
r bool
|
||||
t string
|
||||
h srvtps.FuncHandler
|
||||
s htpool.Pool
|
||||
p montps.FuncPool
|
||||
}
|
||||
|
||||
func (c *componentHttp) _CheckDep() bool {
|
||||
return c != nil && len(c.hand) > 0 && c.tls != "" && c.log != ""
|
||||
func (o *componentHttp) SetTLSKey(tlsKey string) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.t = tlsKey
|
||||
}
|
||||
|
||||
func (c *componentHttp) _CheckInit() bool {
|
||||
return c != nil && c._CheckDep() && c.pool != nil
|
||||
func (o *componentHttp) SetHandler(fct srvtps.FuncHandler) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.h = fct
|
||||
}
|
||||
|
||||
func (c *componentHttp) _GetTLS() (libtls.TLSConfig, liberr.Error) {
|
||||
if !c._CheckDep() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
func (o *componentHttp) GetPool() htpool.Pool {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if i := cpttls.Load(c.get, c.tls); i == nil {
|
||||
return nil, ErrorDependencyTLSDefault.Error(nil)
|
||||
} else if tls := i.GetTLS(); tls == nil {
|
||||
return nil, ErrorDependencyTLSDefault.Error(nil)
|
||||
} else {
|
||||
return tls, nil
|
||||
}
|
||||
return o.s
|
||||
}
|
||||
|
||||
func (c *componentHttp) _GetLogger() (liblog.Logger, liberr.Error) {
|
||||
if !c._CheckDep() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
func (o *componentHttp) SetPool(pool htpool.Pool) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if i := cptlog.Load(c.get, c.log); i == nil {
|
||||
return nil, ErrorDependencyLogDefault.Error(nil)
|
||||
} else if log := i.Log(); log == nil {
|
||||
return nil, ErrorDependencyLogDefault.Error(nil)
|
||||
} else {
|
||||
return log, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentHttp) _getPoolServerConfig(getCfg libcfg.FuncComponentConfigGet) (libhts.PoolServerConfig, liberr.Error) {
|
||||
cnf := make(libhts.PoolServerConfig, 0)
|
||||
|
||||
if !c._CheckDep() {
|
||||
return cnf, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if err := getCfg(c.key, &cnf); err != nil {
|
||||
return cnf, ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
if tls, err := c._GetTLS(); err != nil {
|
||||
return cnf, err
|
||||
} else {
|
||||
cnf.MapUpdate(func(sCFG libhts.ServerConfig) libhts.ServerConfig {
|
||||
sCFG.SetDefaultTLS(func() libtls.TLSConfig {
|
||||
return tls
|
||||
})
|
||||
|
||||
sCFG.SetParentContext(c.ctx)
|
||||
return sCFG
|
||||
})
|
||||
}
|
||||
|
||||
if err := cnf.Validate(); err != nil {
|
||||
return cnf, ErrorConfigInvalid.Error(err)
|
||||
} else if len(c.hand) < 1 {
|
||||
return cnf, ErrorComponentNotInitialized.ErrorParent(fmt.Errorf("missing handler"))
|
||||
}
|
||||
|
||||
return cnf, nil
|
||||
}
|
||||
|
||||
func (c *componentHttp) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
var isReload = c.IsStarted()
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if isReload {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentHttp) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentHttp) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
var (
|
||||
err liberr.Error
|
||||
cnf libhts.PoolServerConfig
|
||||
)
|
||||
|
||||
if cnf, err = c._getPoolServerConfig(getCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.pool != nil {
|
||||
if p, e := cnf.UpdatePoolServer(c.pool); e != nil {
|
||||
return ErrorReloadComponent.Error(e)
|
||||
} else {
|
||||
c.pool = p
|
||||
}
|
||||
} else if p, e := cnf.PoolServer(); e != nil {
|
||||
return ErrorReloadComponent.Error(e)
|
||||
} else {
|
||||
c.pool = p
|
||||
}
|
||||
|
||||
c.pool.SetLogger(func() liblog.Logger {
|
||||
var (
|
||||
l liblog.Logger
|
||||
e liberr.Error
|
||||
)
|
||||
if l, e = c._GetLogger(); e != nil {
|
||||
return liblog.GetDefault()
|
||||
} else {
|
||||
return l
|
||||
}
|
||||
})
|
||||
|
||||
if c.sts != nil {
|
||||
c.pool.StatusRoute(c.key, c.sts())
|
||||
}
|
||||
|
||||
if err = c.pool.ListenMultiHandler(c.hand); err != nil {
|
||||
return ErrorStartComponent.Error(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentHttp) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
if !c._CheckDep() {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentHttp) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentHttp) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
c.sts = sts
|
||||
}
|
||||
|
||||
func (c *componentHttp) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentHttp) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentHttp) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c._CheckInit() && c.pool.IsRunning(true)
|
||||
}
|
||||
|
||||
func (c *componentHttp) IsRunning(atLeast bool) bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c._CheckInit() && c.pool.IsRunning(atLeast)
|
||||
}
|
||||
|
||||
func (c *componentHttp) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentHttp) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentHttp) Stop() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c._CheckInit() {
|
||||
c.pool.Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentHttp) Dependencies() []string {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if !c._CheckDep() {
|
||||
return []string{cpttls.ComponentType, cptlog.ComponentType}
|
||||
}
|
||||
|
||||
return []string{c.tls, c.log}
|
||||
}
|
||||
|
||||
func (c *componentHttp) SetTLSKey(tlsKey string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.tls = tlsKey
|
||||
}
|
||||
|
||||
func (c *componentHttp) SetLOGKey(logKey string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.log = logKey
|
||||
}
|
||||
|
||||
func (c *componentHttp) SetHandler(handler map[string]http.Handler) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.hand = handler
|
||||
}
|
||||
|
||||
func (c *componentHttp) GetPool() libhts.PoolServer {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.pool
|
||||
}
|
||||
|
||||
func (c *componentHttp) SetPool(pool libhts.PoolServer) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.pool = pool
|
||||
o.s = pool
|
||||
}
|
||||
|
||||
139
config/components/http/monitor.go
Normal file
139
config/components/http/monitor.go
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 http
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
)
|
||||
|
||||
func (o *componentHttp) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.p = fct
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getMonitorPool() montps.Pool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.p == nil {
|
||||
return nil
|
||||
} else if p := o.p(); p == nil {
|
||||
return nil
|
||||
} else {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _registerMonitor(err liberr.CodeError) liberr.Error {
|
||||
var (
|
||||
e error
|
||||
key = o._getKey()
|
||||
mon []montps.Monitor
|
||||
vrs = o._getVersion()
|
||||
ctx = o.x.GetContext
|
||||
)
|
||||
|
||||
if o._getMonitorPool() == nil {
|
||||
return nil
|
||||
} else if len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if !o.IsStarted() {
|
||||
return ErrorComponentStart.Error(nil)
|
||||
}
|
||||
|
||||
if mon, e = o._newMonitor(vrs); e != nil {
|
||||
return err.ErrorParent(e)
|
||||
} else if mon == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, m := range mon {
|
||||
if old := o._getMonitor(m.Name()); old != nil {
|
||||
old.InfoUpd(m.InfoGet())
|
||||
if e = old.SetConfig(ctx, m.GetConfig()); e == nil {
|
||||
m = old
|
||||
}
|
||||
}
|
||||
|
||||
if e = m.Restart(ctx()); e != nil {
|
||||
return err.ErrorParent(e)
|
||||
} else if e = o._setMonitor(m); e != nil {
|
||||
return err.ErrorParent(e)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentHttp) _newMonitor(vrs libver.Version) ([]montps.Monitor, error) {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if c, e := o.s.Monitor(vrs); e != nil {
|
||||
return nil, e
|
||||
} else {
|
||||
for k := range c {
|
||||
if c[k] != nil {
|
||||
c[k].RegisterLoggerDefault(o.getLogger)
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentHttp) _getMonitor(key string) montps.Monitor {
|
||||
var (
|
||||
mon montps.Monitor
|
||||
pol = o._getMonitorPool()
|
||||
)
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mon = pol.MonitorGet(key)
|
||||
|
||||
if mon != nil {
|
||||
mon.RegisterLoggerDefault(o.getLogger)
|
||||
}
|
||||
|
||||
return mon
|
||||
}
|
||||
|
||||
func (o *componentHttp) _setMonitor(mon montps.Monitor) error {
|
||||
var pol = o._getMonitorPool()
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pol.MonitorSet(mon)
|
||||
}
|
||||
194
config/components/ldap/client.go
Normal file
194
config/components/ldap/client.go
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 ldap
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
lbldap "github.com/nabbar/golib/ldap"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentLDAP) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _runCli() liberr.Error {
|
||||
var (
|
||||
e error
|
||||
err liberr.Error
|
||||
cli *lbldap.HelperLDAP
|
||||
cfg *lbldap.Config
|
||||
)
|
||||
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if cfg, err = o._getConfig(); err != nil {
|
||||
return ErrorParamInvalid.Error(err)
|
||||
} else if cli, e = lbldap.NewLDAP(o.x.GetContext(), cfg, o.a); e != nil {
|
||||
return ErrorConfigInvalid.ErrorParent(e)
|
||||
} else {
|
||||
cli.SetLogger(o.getLogger)
|
||||
}
|
||||
|
||||
if o.l != nil {
|
||||
o.l.Close()
|
||||
}
|
||||
|
||||
o.m.RUnlock()
|
||||
o.m.Lock()
|
||||
o.l = cli
|
||||
o.c = cfg
|
||||
o.m.Unlock()
|
||||
o.m.RLock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
157
config/components/ldap/component.go
Normal file
157
config/components/ldap/component.go
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 ldap
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "LDAP"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentLDAP) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentLDAP) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentLDAP) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentLDAP) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentLDAP) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o != nil && o.l != nil
|
||||
}
|
||||
|
||||
func (o *componentLDAP) IsRunning() bool {
|
||||
return o.IsStarted()
|
||||
}
|
||||
|
||||
func (o *componentLDAP) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentLDAP) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentLDAP) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.l.Close()
|
||||
o.l = nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentLDAP) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = make([]string, 0)
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLDAP) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
63
config/components/ldap/config.go
Normal file
63
config/components/ldap/config.go
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 ldap
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
lbldap "github.com/nabbar/golib/ldap"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentLDAP) RegisterFlag(Command *spfcbr.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentLDAP) _getConfig() (*lbldap.Config, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg lbldap.Config
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -30,9 +30,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgcst "github.com/nabbar/golib/config/const"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
@@ -50,17 +48,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentLDAP) DefaultConfig(indent string) []byte {
|
||||
func (o *componentLDAP) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentLDAP) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -30,25 +30,30 @@ import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
lbldap "github.com/nabbar/golib/ldap"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "LDAP"
|
||||
)
|
||||
|
||||
// @TODO: refactor LDAP Package
|
||||
|
||||
type ComponentLDAP interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
Config() *lbldap.Config
|
||||
LDAP() *lbldap.HelperLDAP
|
||||
SetAttributes(att []string)
|
||||
|
||||
GetConfig() *lbldap.Config
|
||||
SetConfig(opt *lbldap.Config)
|
||||
|
||||
GetLDAP() *lbldap.HelperLDAP
|
||||
SetLDAP(l *lbldap.HelperLDAP)
|
||||
}
|
||||
|
||||
func New() ComponentLDAP {
|
||||
func New(ctx libctx.FuncContext) ComponentLDAP {
|
||||
return &componentLDAP{
|
||||
m: sync.Mutex{},
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
c: nil,
|
||||
l: nil,
|
||||
}
|
||||
}
|
||||
@@ -57,11 +62,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentLDAP) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New())
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New(ctx))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentLDAP {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentLDAP {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentLDAP); !ok {
|
||||
|
||||
@@ -27,173 +27,55 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
lbldap "github.com/nabbar/golib/ldap"
|
||||
)
|
||||
|
||||
type componentLDAP struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
sts libcfg.FuncRouteStatus
|
||||
key string
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
a []string
|
||||
c *lbldap.Config
|
||||
l *lbldap.HelperLDAP
|
||||
}
|
||||
|
||||
func (c *componentLDAP) _GetContext() context.Context {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentLDAP) GetConfig() *lbldap.Config {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if c.ctx != nil {
|
||||
if x := c.ctx(); x != nil {
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
return context.Background()
|
||||
return o.c
|
||||
}
|
||||
|
||||
func (c *componentLDAP) _CheckInit() bool {
|
||||
return c != nil && c.l != nil
|
||||
func (o *componentLDAP) SetConfig(opt *lbldap.Config) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.c = opt
|
||||
}
|
||||
|
||||
func (c *componentLDAP) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentLDAP) GetLDAP() *lbldap.HelperLDAP {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if c.l != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
return o.l
|
||||
}
|
||||
|
||||
func (o *componentLDAP) SetLDAP(l *lbldap.HelperLDAP) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.l = l
|
||||
}
|
||||
|
||||
func (o *componentLDAP) SetAttributes(att []string) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.a = att
|
||||
if o.l != nil {
|
||||
o.l.Attributes = att
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentLDAP) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentLDAP) _runCli(ctx context.Context, getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
cfg := lbldap.Config{}
|
||||
if err := getCfg(c.key, &cfg); err != nil {
|
||||
return ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
if l, e := lbldap.NewLDAP(ctx, &cfg, nil); e != nil {
|
||||
return ErrorConfigInvalid.ErrorParent(e)
|
||||
} else {
|
||||
c.l = l
|
||||
c.c = &cfg
|
||||
}
|
||||
|
||||
if c.sts != nil {
|
||||
if s := c.sts(); s != nil {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentLDAP) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(c._GetContext(), getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentLDAP) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentLDAP) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentLDAP) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentLDAP) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentLDAP) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c != nil && c.l != nil
|
||||
}
|
||||
|
||||
func (c *componentLDAP) IsRunning(atLeast bool) bool {
|
||||
return c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentLDAP) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentLDAP) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentLDAP) Stop() {
|
||||
|
||||
}
|
||||
|
||||
func (c *componentLDAP) Dependencies() []string {
|
||||
return make([]string, 0)
|
||||
}
|
||||
|
||||
func (c *componentLDAP) Config() *lbldap.Config {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.c
|
||||
}
|
||||
|
||||
func (c *componentLDAP) LDAP() *lbldap.HelperLDAP {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.l
|
||||
}
|
||||
|
||||
34
config/components/ldap/monitor.go
Normal file
34
config/components/ldap/monitor.go
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 ldap
|
||||
|
||||
import (
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
func (o *componentLDAP) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
}
|
||||
194
config/components/log/client.go
Normal file
194
config/components/log/client.go
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 log
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentLog) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentLog) _runCli() liberr.Error {
|
||||
var (
|
||||
e error
|
||||
err liberr.Error
|
||||
prt = ErrorReloadLog
|
||||
cfg *liblog.Options
|
||||
)
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorStartLog
|
||||
|
||||
o.m.Lock()
|
||||
|
||||
o.l = liblog.New(o.x.GetContext)
|
||||
o.l.SetLevel(o.v)
|
||||
|
||||
o.m.Unlock()
|
||||
}
|
||||
|
||||
if cfg, err = o._getConfig(); err != nil {
|
||||
return ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if e = o.l.SetOptions(cfg); e != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentLog) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
156
config/components/log/component.go
Normal file
156
config/components/log/component.go
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 log
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "head"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentLog) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentLog) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentLog) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentLog) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentLog) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.l != nil
|
||||
}
|
||||
|
||||
func (o *componentLog) IsRunning() bool {
|
||||
return o.IsStarted()
|
||||
}
|
||||
|
||||
func (o *componentLog) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentLog) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentLog) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
_ = o.l.Close()
|
||||
o.l = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentLog) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = make([]string, 0)
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentLog) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
120
config/components/log/config.go
Normal file
120
config/components/log/config.go
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 log
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentLog) RegisterFlag(Command *spfcbr.Command) error {
|
||||
var (
|
||||
key string
|
||||
vpr *spfvpr.Viper
|
||||
err error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
_ = Command.PersistentFlags().Bool(key+".disableStandard", false, "allow disabling to write log to standard output stdout/stderr.")
|
||||
_ = Command.PersistentFlags().Bool(key+".disableStack", false, "allow to disable the goroutine id before each message")
|
||||
_ = Command.PersistentFlags().Bool(key+".disableTimestamp", false, "allow to disable the timestamp before each message")
|
||||
_ = Command.PersistentFlags().Bool(key+".enableTrace", true, "allow to add the origin caller/file/line of each message")
|
||||
_ = Command.PersistentFlags().String(key+".traceFilter", "", "define the path to clean for trace")
|
||||
_ = Command.PersistentFlags().Bool(key+".disableColor", false, "define if color could be use or not in messages format. If the running process is not a tty, no color will be used.")
|
||||
|
||||
if err = vpr.BindPFlag(key+".disableStandard", Command.PersistentFlags().Lookup(key+".disableStandard")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".disableStack", Command.PersistentFlags().Lookup(key+".disableStack")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".disableTimestamp", Command.PersistentFlags().Lookup(key+".disableTimestamp")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".enableTrace", Command.PersistentFlags().Lookup(key+".enableTrace")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".traceFilter", Command.PersistentFlags().Lookup(key+".traceFilter")); err != nil {
|
||||
return err
|
||||
} else if err = vpr.BindPFlag(key+".disableColor", Command.PersistentFlags().Lookup(key+".disableColor")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentLog) _getConfig() (*liblog.Options, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg liblog.Options
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
if val := vpr.GetBool(key + "disableStandard"); val {
|
||||
cfg.DisableStandard = true
|
||||
}
|
||||
|
||||
if val := vpr.GetBool(key + "disableStack"); val {
|
||||
cfg.DisableStack = true
|
||||
}
|
||||
|
||||
if val := vpr.GetBool(key + "disableTimestamp"); val {
|
||||
cfg.DisableTimestamp = true
|
||||
}
|
||||
|
||||
if val := vpr.GetBool(key + "enableTrace"); val {
|
||||
cfg.EnableTrace = true
|
||||
}
|
||||
|
||||
if val := vpr.GetString(key + "traceFilter"); val != "" {
|
||||
cfg.TraceFilter = val
|
||||
}
|
||||
|
||||
if val := vpr.GetBool(key + "disableColor"); val {
|
||||
cfg.DisableColor = true
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -27,141 +27,9 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
logdef "github.com/nabbar/golib/logger/config"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`
|
||||
{
|
||||
"disableStandard":false,
|
||||
"disableStack":false,
|
||||
"disableTimestamp":false,
|
||||
"enableTrace":true,
|
||||
"traceFilter":"",
|
||||
"disableColor":false,
|
||||
"logFile":[
|
||||
{
|
||||
"logLevel":[
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warning",
|
||||
"Error",
|
||||
"Fatal",
|
||||
"Critical"
|
||||
],
|
||||
"filepath":"",
|
||||
"create":false,
|
||||
"createPath":false,
|
||||
"fileMode":"0644",
|
||||
"pathMode":"0755",
|
||||
"disableStack":false,
|
||||
"disableTimestamp":false,
|
||||
"enableTrace":true
|
||||
}
|
||||
],
|
||||
"logSyslog":[
|
||||
{
|
||||
"logLevel":[
|
||||
"Debug",
|
||||
"Info",
|
||||
"Warning",
|
||||
"Error",
|
||||
"Fatal",
|
||||
"Critical"
|
||||
],
|
||||
"network":"tcp",
|
||||
"host":"",
|
||||
"severity":"Error",
|
||||
"facility":"local0",
|
||||
"tag":"",
|
||||
"disableStack":false,
|
||||
"disableTimestamp":false,
|
||||
"enableTrace":true
|
||||
}
|
||||
]
|
||||
}`)
|
||||
|
||||
func SetDefaultConfig(cfg []byte) {
|
||||
_defaultConfig = cfg
|
||||
}
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentLog) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentLog) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disableStandard", false, "allow disabling to write log to standard output stdout/stderr.")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disableStack", false, "allow to disable the goroutine id before each message")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disableTimestamp", false, "allow to disable the timestamp before each message")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".enableTrace", true, "allow to add the origin caller/file/line of each message")
|
||||
_ = Command.PersistentFlags().String(c.key+".traceFilter", "", "define the path to clean for trace")
|
||||
_ = Command.PersistentFlags().Bool(c.key+".disableColor", false, "define if color could be use or not in messages format. If the running process is not a tty, no color will be used.")
|
||||
|
||||
if err := Viper.BindPFlag(c.key+".disableStandard", Command.PersistentFlags().Lookup(c.key+".disableStandard")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".disableStack", Command.PersistentFlags().Lookup(c.key+".disableStack")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".disableTimestamp", Command.PersistentFlags().Lookup(c.key+".disableTimestamp")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".enableTrace", Command.PersistentFlags().Lookup(c.key+".enableTrace")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".traceFilter", Command.PersistentFlags().Lookup(c.key+".traceFilter")); err != nil {
|
||||
return err
|
||||
} else if err = Viper.BindPFlag(c.key+".disableColor", Command.PersistentFlags().Lookup(c.key+".disableColor")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentLog) _GetOptions(getCfg libcfg.FuncComponentConfigGet) (*liblog.Options, liberr.Error) {
|
||||
var (
|
||||
err liberr.Error
|
||||
cfg = liblog.Options{}
|
||||
vpr = c.vpr()
|
||||
)
|
||||
|
||||
if err = getCfg(c.key, &cfg); err != nil {
|
||||
return nil, ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
if val := vpr.GetBool(c.key + "disableStandard"); val {
|
||||
cfg.DisableStandard = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + "disableStack"); val {
|
||||
cfg.DisableStack = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + "disableTimestamp"); val {
|
||||
cfg.DisableTimestamp = true
|
||||
}
|
||||
if val := vpr.GetBool(c.key + "enableTrace"); val {
|
||||
cfg.EnableTrace = true
|
||||
}
|
||||
if val := vpr.GetString(c.key + "traceFilter"); val != "" {
|
||||
cfg.TraceFilter = val
|
||||
}
|
||||
if val := vpr.GetBool(c.key + "disableColor"); val {
|
||||
cfg.DisableColor = true
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
func (o *componentLog) DefaultConfig(indent string) []byte {
|
||||
return logdef.DefaultConfig(indent)
|
||||
}
|
||||
|
||||
@@ -27,29 +27,38 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultLevel = liblog.InfoLevel
|
||||
ComponentType = "log"
|
||||
DefaultLevel = liblog.InfoLevel
|
||||
)
|
||||
|
||||
type ComponentLog interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
Log() liblog.Logger
|
||||
|
||||
SetLevel(lvl liblog.Level)
|
||||
GetLevel() liblog.Level
|
||||
|
||||
SetField(fields liblog.Fields)
|
||||
GetField() liblog.Fields
|
||||
|
||||
SetOptions(opt *liblog.Options) liberr.Error
|
||||
GetOptions() *liblog.Options
|
||||
}
|
||||
|
||||
func New(lvl liblog.Level, defLogger func() liblog.Logger) ComponentLog {
|
||||
func New(ctx libctx.FuncContext, lvl liblog.Level) ComponentLog {
|
||||
return &componentLog{
|
||||
d: defLogger,
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
l: nil,
|
||||
v: lvl,
|
||||
}
|
||||
@@ -59,11 +68,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentLog) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key string, lvl liblog.Level, defLogger func() liblog.Logger) {
|
||||
cfg.ComponentSet(key, New(lvl, defLogger))
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string, lvl liblog.Level) {
|
||||
cfg.ComponentSet(key, New(ctx, lvl))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentLog {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentLog {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentLog); !ok {
|
||||
|
||||
@@ -29,210 +29,92 @@ package log
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
)
|
||||
|
||||
type componentLog struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
d func() liblog.Logger
|
||||
|
||||
m sync.Mutex
|
||||
l liblog.Logger
|
||||
v liblog.Level
|
||||
}
|
||||
|
||||
func (c *componentLog) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentLog) Log() liblog.Logger {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if c.l != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentLog) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
if o.l != nil {
|
||||
return o.l.Clone()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentLog) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentLog) SetLevel(lvl liblog.Level) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if c.ctx == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
o.v = lvl
|
||||
|
||||
if c.l == nil {
|
||||
c.l = liblog.New(c.ctx())
|
||||
c.l.SetLevel(c.v)
|
||||
}
|
||||
|
||||
var (
|
||||
e error
|
||||
|
||||
log liblog.Logger
|
||||
cnf *liblog.Options
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if log, e = c.l.Clone(); e != nil {
|
||||
log = liblog.New(c.ctx())
|
||||
log.SetLevel(c.v)
|
||||
}
|
||||
|
||||
if cnf, err = c._GetOptions(getCfg); err != nil {
|
||||
return err
|
||||
} else if cnf == nil {
|
||||
return ErrorConfigInvalid.Error(nil)
|
||||
} else if e = log.SetOptions(cnf); e != nil {
|
||||
return ErrorReloadLog.Error(err)
|
||||
}
|
||||
|
||||
if c.l != nil {
|
||||
_ = c.l.Close()
|
||||
}
|
||||
|
||||
c.l = log
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentLog) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentLog) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentLog) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentLog) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentLog) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentLog) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.l != nil
|
||||
}
|
||||
|
||||
func (c *componentLog) IsRunning(atLeast bool) bool {
|
||||
return c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentLog) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentLog) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentLog) Stop() {
|
||||
return
|
||||
}
|
||||
|
||||
func (c *componentLog) Dependencies() []string {
|
||||
return make([]string, 0)
|
||||
}
|
||||
|
||||
func (c *componentLog) Log() liblog.Logger {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.l != nil {
|
||||
if n, e := c.l.Clone(); e != nil {
|
||||
return c.d()
|
||||
} else {
|
||||
return n
|
||||
}
|
||||
}
|
||||
|
||||
return c.d()
|
||||
}
|
||||
|
||||
func (c *componentLog) SetLevel(lvl liblog.Level) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.v = lvl
|
||||
|
||||
if c.l == nil {
|
||||
if o.l == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.l.SetLevel(lvl)
|
||||
o.l.SetLevel(lvl)
|
||||
}
|
||||
|
||||
func (c *componentLog) SetField(fields liblog.Fields) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentLog) GetLevel() liblog.Level {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if c.l == nil {
|
||||
return o.v
|
||||
}
|
||||
|
||||
func (o *componentLog) SetField(fields liblog.Fields) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.l == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.l.SetFields(fields)
|
||||
o.l.SetFields(fields)
|
||||
}
|
||||
|
||||
func (c *componentLog) SetOptions(opt *liblog.Options) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentLog) GetField() liblog.Fields {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if c.l == nil {
|
||||
if o.l == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return o.l.GetFields()
|
||||
}
|
||||
|
||||
func (o *componentLog) GetOptions() *liblog.Options {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.l == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return o.l.GetOptions()
|
||||
}
|
||||
|
||||
func (o *componentLog) SetOptions(opt *liblog.Options) liberr.Error {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.l == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := c.l.SetOptions(opt); e != nil {
|
||||
if e := o.l.SetOptions(opt); e != nil {
|
||||
return ErrorConfigInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
|
||||
34
config/components/log/monitor.go
Normal file
34
config/components/log/monitor.go
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 log
|
||||
|
||||
import (
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
func (o *componentLog) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
}
|
||||
197
config/components/mail/client.go
Normal file
197
config/components/mail/client.go
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 mail
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libmail "github.com/nabbar/golib/mail"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentMail) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _getContext() context.Context {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.x.GetContext()
|
||||
}
|
||||
|
||||
func (o *componentMail) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentMail) _runCli() liberr.Error {
|
||||
var (
|
||||
err liberr.Error
|
||||
prt = ErrorComponentReload
|
||||
obj libmail.Mail
|
||||
cfg *libmail.Config
|
||||
)
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorComponentStart
|
||||
}
|
||||
|
||||
if cfg, err = o._getConfig(); err != nil {
|
||||
return prt.Error(err)
|
||||
} else if obj, err = cfg.NewMailer(); err != nil {
|
||||
return prt.Error(err)
|
||||
}
|
||||
|
||||
o.Stop()
|
||||
|
||||
o.m.Lock()
|
||||
o.e = obj
|
||||
o.m.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentMail) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
155
config/components/mail/component.go
Normal file
155
config/components/mail/component.go
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 mail
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "smtp"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentMail) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentMail) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentMail) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentMail) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentMail) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o != nil && o.e != nil
|
||||
}
|
||||
|
||||
func (o *componentMail) IsRunning() bool {
|
||||
return o.IsStarted()
|
||||
}
|
||||
|
||||
func (o *componentMail) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentMail) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentMail) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.e = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentMail) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = make([]string, 0)
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentMail) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
150
config/components/mail/config.go
Normal file
150
config/components/mail/config.go
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 mail
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libmail "github.com/nabbar/golib/mail"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentMail) RegisterFlag(Command *spfcbr.Command) error {
|
||||
var (
|
||||
key string
|
||||
vpr *spfvpr.Viper
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
_ = Command.PersistentFlags().String(key+".charset", "", "define the charset to use into mail header")
|
||||
_ = Command.PersistentFlags().String(key+".encoding", "", "define the encoding mode for contents of mail")
|
||||
_ = Command.PersistentFlags().String(key+".priority", "", "define the priority of the mail")
|
||||
_ = Command.PersistentFlags().String(key+".subject", "", "define the subject of the mail")
|
||||
_ = Command.PersistentFlags().String(key+".from", "", "define the email use for sending the mail")
|
||||
_ = Command.PersistentFlags().String(key+".sender", "", "define the email show as sender")
|
||||
_ = Command.PersistentFlags().String(key+".replyTo", "", "define the email to use for reply")
|
||||
|
||||
if err := vpr.BindPFlag(key+".charset", Command.PersistentFlags().Lookup(key+".charset")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := vpr.BindPFlag(key+".encoding", Command.PersistentFlags().Lookup(key+".encoding")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := vpr.BindPFlag(key+".priority", Command.PersistentFlags().Lookup(key+".priority")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := vpr.BindPFlag(key+".subject", Command.PersistentFlags().Lookup(key+".subject")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := vpr.BindPFlag(key+".from", Command.PersistentFlags().Lookup(key+".from")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := vpr.BindPFlag(key+".sender", Command.PersistentFlags().Lookup(key+".sender")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := vpr.BindPFlag(key+".replyTo", Command.PersistentFlags().Lookup(key+".replyTo")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentMail) _getConfig() (*libmail.Config, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg libmail.Config
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
if len(cfg.Headers) < 1 {
|
||||
cfg.Headers = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.To) < 1 {
|
||||
cfg.To = make([]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Cc) < 1 {
|
||||
cfg.Cc = make([]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Bcc) < 1 {
|
||||
cfg.Bcc = make([]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Attach) < 1 {
|
||||
cfg.Attach = make([]libmail.ConfigFile, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Inline) < 1 {
|
||||
cfg.Inline = make([]libmail.ConfigFile, 0)
|
||||
}
|
||||
|
||||
if val := vpr.GetString(key + ".charset"); val != "" {
|
||||
cfg.Charset = val
|
||||
}
|
||||
if val := vpr.GetString(key + ".encoding"); val != "" {
|
||||
cfg.Encoding = val
|
||||
}
|
||||
if val := vpr.GetString(key + ".priority"); val != "" {
|
||||
cfg.Priority = val
|
||||
}
|
||||
if val := vpr.GetString(key + ".subject"); val != "" {
|
||||
cfg.Subject = val
|
||||
}
|
||||
if val := vpr.GetString(key + ".from"); val != "" {
|
||||
cfg.From = val
|
||||
}
|
||||
if val := vpr.GetString(key + ".sender"); val != "" {
|
||||
cfg.Sender = val
|
||||
}
|
||||
if val := vpr.GetString(key + ".replyTo"); val != "" {
|
||||
cfg.ReplyTo = val
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -30,11 +30,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libmail "github.com/nabbar/golib/mail"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgtps "github.com/nabbar/golib/config/const"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
@@ -80,111 +76,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgtps.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentMail) DefaultConfig(indent string) []byte {
|
||||
func (o *componentMail) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentMail) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
_ = Command.PersistentFlags().String(c.key+".charset", "", "define the charset to use into mail header")
|
||||
_ = Command.PersistentFlags().String(c.key+".encoding", "", "define the encoding mode for contents of mail")
|
||||
_ = Command.PersistentFlags().String(c.key+".priority", "", "define the priority of the mail")
|
||||
_ = Command.PersistentFlags().String(c.key+".subject", "", "define the subject of the mail")
|
||||
_ = Command.PersistentFlags().String(c.key+".from", "", "define the email use for sending the mail")
|
||||
_ = Command.PersistentFlags().String(c.key+".sender", "", "define the email show as sender")
|
||||
_ = Command.PersistentFlags().String(c.key+".replyTo", "", "define the email to use for reply")
|
||||
|
||||
if err := Viper.BindPFlag(c.key+".charset", Command.PersistentFlags().Lookup(c.key+".charset")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Viper.BindPFlag(c.key+".encoding", Command.PersistentFlags().Lookup(c.key+".encoding")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Viper.BindPFlag(c.key+".priority", Command.PersistentFlags().Lookup(c.key+".priority")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Viper.BindPFlag(c.key+".subject", Command.PersistentFlags().Lookup(c.key+".subject")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Viper.BindPFlag(c.key+".from", Command.PersistentFlags().Lookup(c.key+".from")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Viper.BindPFlag(c.key+".sender", Command.PersistentFlags().Lookup(c.key+".sender")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Viper.BindPFlag(c.key+".replyTo", Command.PersistentFlags().Lookup(c.key+".replyTo")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentMail) _getConfig(getCfg libcfg.FuncComponentConfigGet) (libmail.Config, liberr.Error) {
|
||||
var (
|
||||
cfg = libmail.Config{}
|
||||
vpr = c.vpr()
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if len(cfg.Headers) < 1 {
|
||||
cfg.Headers = make(map[string]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.To) < 1 {
|
||||
cfg.To = make([]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Cc) < 1 {
|
||||
cfg.Cc = make([]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Bcc) < 1 {
|
||||
cfg.Bcc = make([]string, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Attach) < 1 {
|
||||
cfg.Attach = make([]libmail.ConfigFile, 0)
|
||||
}
|
||||
|
||||
if len(cfg.Inline) < 1 {
|
||||
cfg.Inline = make([]libmail.ConfigFile, 0)
|
||||
}
|
||||
|
||||
if e := getCfg(c.key, &cfg); e != nil {
|
||||
return cfg, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
|
||||
if val := vpr.GetString(c.key + ".charset"); val != "" {
|
||||
cfg.Charset = val
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".encoding"); val != "" {
|
||||
cfg.Encoding = val
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".priority"); val != "" {
|
||||
cfg.Priority = val
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".subject"); val != "" {
|
||||
cfg.Subject = val
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".from"); val != "" {
|
||||
cfg.From = val
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".sender"); val != "" {
|
||||
cfg.Sender = val
|
||||
}
|
||||
if val := vpr.GetString(c.key + ".replyTo"); val != "" {
|
||||
cfg.ReplyTo = val
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return cfg, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -38,10 +38,8 @@ const (
|
||||
ErrorParamInvalid
|
||||
ErrorComponentNotInitialized
|
||||
ErrorConfigInvalid
|
||||
ErrorStartComponent
|
||||
ErrorReloadComponent
|
||||
ErrorDependencyTLSDefault
|
||||
ErrorDependencyLogDefault
|
||||
ErrorComponentStart
|
||||
ErrorComponentReload
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -61,14 +59,10 @@ func getMessage(code liberr.CodeError) (message string) {
|
||||
return "this component seems to not be correctly initialized"
|
||||
case ErrorConfigInvalid:
|
||||
return "invalid component config"
|
||||
case ErrorStartComponent:
|
||||
case ErrorComponentStart:
|
||||
return "cannot start component with config"
|
||||
case ErrorReloadComponent:
|
||||
case ErrorComponentReload:
|
||||
return "cannot reload component with new config"
|
||||
case ErrorDependencyTLSDefault:
|
||||
return "cannot retrieve TLS Component"
|
||||
case ErrorDependencyLogDefault:
|
||||
return "cannot retrieve Logger Component"
|
||||
}
|
||||
|
||||
return liberr.NullMessage
|
||||
|
||||
@@ -30,30 +30,23 @@ import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libmail "github.com/nabbar/golib/mail"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "smtp"
|
||||
)
|
||||
|
||||
type ComponentMail interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
GetMail() (libmail.Mail, liberr.Error)
|
||||
}
|
||||
|
||||
func New() ComponentMail {
|
||||
func New(ctx libctx.FuncContext) ComponentMail {
|
||||
return &componentMail{
|
||||
ctx: nil,
|
||||
get: nil,
|
||||
fsa: nil,
|
||||
fsb: nil,
|
||||
fra: nil,
|
||||
frb: nil,
|
||||
m: sync.Mutex{},
|
||||
e: nil,
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
e: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,11 +54,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentMail) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New())
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New(ctx))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentMail {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentMail {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentMail); !ok {
|
||||
|
||||
@@ -29,155 +29,24 @@ package mail
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libmail "github.com/nabbar/golib/mail"
|
||||
)
|
||||
|
||||
type componentMail struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
e libmail.Mail
|
||||
}
|
||||
|
||||
func (c *componentMail) _CheckDep() bool {
|
||||
return c != nil
|
||||
}
|
||||
|
||||
func (c *componentMail) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.e != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentMail) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentMail) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
var (
|
||||
err liberr.Error
|
||||
mlr libmail.Mail
|
||||
cfg libmail.Config
|
||||
)
|
||||
|
||||
if cfg, err = c._getConfig(getCfg); err != nil {
|
||||
return err
|
||||
} else if mlr, err = cfg.NewMailer(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
c.e = mlr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentMail) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
if !c._CheckDep() {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentMail) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentMail) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentMail) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentMail) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentMail) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c._CheckDep() && c.e != nil
|
||||
}
|
||||
|
||||
func (c *componentMail) IsRunning(atLeast bool) bool {
|
||||
return !c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentMail) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentMail) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentMail) Stop() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.e = nil
|
||||
}
|
||||
|
||||
func (c *componentMail) Dependencies() []string {
|
||||
return make([]string, 0)
|
||||
}
|
||||
|
||||
func (c *componentMail) GetMail() (libmail.Mail, liberr.Error) {
|
||||
if !c.IsStarted() {
|
||||
func (o *componentMail) GetMail() (libmail.Mail, liberr.Error) {
|
||||
if !o.IsStarted() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
return c.e.Clone(), nil
|
||||
return o.e.Clone(), nil
|
||||
}
|
||||
|
||||
34
config/components/mail/monitor.go
Normal file
34
config/components/mail/monitor.go
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 mail
|
||||
|
||||
import (
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
func (o *componentMail) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 natsServer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libnat "github.com/nabbar/golib/nats"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
"server":{
|
||||
"name":"node-0",
|
||||
"host":"127.0.0.1",
|
||||
"port":9000,
|
||||
"client_advertise":"",
|
||||
"http_host":"127.0.0.1",
|
||||
"http_port":9200,
|
||||
"https_port":0,
|
||||
"http_base_path":"",
|
||||
"prof_port":9300,
|
||||
"pid_file":"",
|
||||
"ports_file_dir":"",
|
||||
"routes":[
|
||||
{
|
||||
"Scheme":"nats",
|
||||
"Opaque":"",
|
||||
"User":{
|
||||
|
||||
},
|
||||
"Host":"127.0.0.1:9101",
|
||||
"Path":"",
|
||||
"RawPath":"",
|
||||
"ForceQuery":false,
|
||||
"RawQuery":"",
|
||||
"Fragment":"",
|
||||
"RawFragment":""
|
||||
},
|
||||
{
|
||||
"Scheme":"nats",
|
||||
"Opaque":"",
|
||||
"User":{
|
||||
|
||||
},
|
||||
"Host":"127.0.0.1:9102",
|
||||
"Path":"",
|
||||
"RawPath":"",
|
||||
"ForceQuery":false,
|
||||
"RawQuery":"",
|
||||
"Fragment":"",
|
||||
"RawFragment":""
|
||||
},
|
||||
{
|
||||
"Scheme":"nats",
|
||||
"Opaque":"",
|
||||
"User":{
|
||||
|
||||
},
|
||||
"Host":"127.0.0.1:9103",
|
||||
"Path":"",
|
||||
"RawPath":"",
|
||||
"ForceQuery":false,
|
||||
"RawQuery":"",
|
||||
"Fragment":"",
|
||||
"RawFragment":""
|
||||
}
|
||||
],
|
||||
"routes_str":"nats://127.0.0.1:9101,nats://127.0.0.1:9102,nats://127.0.0.1:9103",
|
||||
"no_log":true,
|
||||
"username":"",
|
||||
"password":"",
|
||||
"token":"",
|
||||
"jet_stream":true,
|
||||
"jet_stream_max_memory":0,
|
||||
"jet_stream_max_store":0,
|
||||
"store_dir":"/path/to/working/folder",
|
||||
"permission_store_dir":"0755",
|
||||
"tags":[
|
||||
""
|
||||
],
|
||||
"tls":false,
|
||||
"allow_no_tls":true,
|
||||
"tls_timeout":0,
|
||||
"tls_config":` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
},
|
||||
"cluster":{
|
||||
"name":"Test-cluster",
|
||||
"host":"127.0.0.1",
|
||||
"port":9100,
|
||||
"listen_str":"",
|
||||
"advertise":"",
|
||||
"no_advertise":false,
|
||||
"connect_retries":5,
|
||||
"username":"",
|
||||
"password":"",
|
||||
"auth_timeout":0,
|
||||
"permissions":{
|
||||
"import":{
|
||||
"allow":null,
|
||||
"deny":null
|
||||
},
|
||||
"export":{
|
||||
"allow":null,
|
||||
"deny":null
|
||||
}
|
||||
},
|
||||
"tls":false,
|
||||
"tls_timeout":0,
|
||||
"tls_config":` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
},
|
||||
"gateways":{
|
||||
"name":"",
|
||||
"host":"",
|
||||
"port":0,
|
||||
"username":"",
|
||||
"password":"",
|
||||
"auth_timeout":0,
|
||||
"advertise":"",
|
||||
"connect_retries":0,
|
||||
"gateways":null,
|
||||
"reject_unknown":false,
|
||||
"tls":false,
|
||||
"tls_timeout":0,
|
||||
"tls_config":` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
},
|
||||
"leaf":{
|
||||
"host":"",
|
||||
"port":0,
|
||||
"username":"",
|
||||
"password":"",
|
||||
"auth_timeout":0,
|
||||
"advertise":"",
|
||||
"no_advertise":false,
|
||||
"account":"",
|
||||
"users":null,
|
||||
"reconnect_interval":0,
|
||||
"remotes":null,
|
||||
"tls":false,
|
||||
"tls_timeout":0,
|
||||
"tls_config":` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
},
|
||||
"websockets":{
|
||||
"host":"",
|
||||
"port":0,
|
||||
"advertise":"",
|
||||
"no_auth_user":"",
|
||||
"jwt_cookie":"",
|
||||
"username":"",
|
||||
"password":"",
|
||||
"token":"",
|
||||
"auth_timeout":0,
|
||||
"same_origin":false,
|
||||
"allowed_origins":null,
|
||||
"compression":false,
|
||||
"no_tls":false,
|
||||
"handshake_timeout":0,
|
||||
"tls_config":` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
},
|
||||
"mqtt":{
|
||||
"host":"",
|
||||
"port":0,
|
||||
"no_auth_user":"",
|
||||
"username":"",
|
||||
"password":"",
|
||||
"token":"",
|
||||
"auth_timeout":0,
|
||||
"ack_wait":0,
|
||||
"max_ack_pending":0,
|
||||
"tls":false,
|
||||
"tls_timeout":0,
|
||||
"tls_config": ` + string(cpttls.DefaultConfig(libcfg.JSONIndent+libcfg.JSONIndent)) + `
|
||||
},
|
||||
"limits":{
|
||||
"max_conn":0,
|
||||
"max_subs":0,
|
||||
"ping_interval":0,
|
||||
"max_pings_out":0,
|
||||
"max_control_line":0,
|
||||
"max_payload":0,
|
||||
"max_pending":0,
|
||||
"write_deadline":0,
|
||||
"max_closed_clients":0,
|
||||
"lame_duck_duration":0,
|
||||
"lame_duck_grace_period":0,
|
||||
"no_sublist_cache":false,
|
||||
"no_header_support":false,
|
||||
"disable_short_first_ping":false
|
||||
},
|
||||
"logs":{
|
||||
"log_file":"/path/to/log/file.log",
|
||||
"permission_folder":"0755",
|
||||
"permission_file":"0644",
|
||||
"syslog":false,
|
||||
"remote_syslog":"",
|
||||
"log_size_limit":0,
|
||||
"max_traced_msg_len":0,
|
||||
"connect_error_reports":0,
|
||||
"reconnect_error_reports":0
|
||||
},
|
||||
"auth":{
|
||||
"nkeys":null,
|
||||
"users":[
|
||||
{
|
||||
"username":"username",
|
||||
"password":"password",
|
||||
"account":"cluster",
|
||||
"connection_types":[
|
||||
"STANDARD",
|
||||
"LEAFNODE",
|
||||
"WEBSOCKET",
|
||||
"MQTT"
|
||||
]
|
||||
}
|
||||
],
|
||||
"accounts":[
|
||||
{
|
||||
"name":"cluster",
|
||||
"permission":{
|
||||
"publish":{
|
||||
"allow":[
|
||||
">",
|
||||
"*"
|
||||
],
|
||||
"deny":[]
|
||||
},
|
||||
"subscribe":{
|
||||
"allow":[
|
||||
">",
|
||||
"*"
|
||||
],
|
||||
"deny":[]
|
||||
},
|
||||
"response":{
|
||||
"max_msgs":1000000000,
|
||||
"expires":1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"auth_timeout":0,
|
||||
"no_auth_user":"",
|
||||
"system_account":"cluster",
|
||||
"no_system_account":false,
|
||||
"allow_new_accounts":true,
|
||||
"trusted_keys":[],
|
||||
"trusted_operators":[]
|
||||
}
|
||||
}`)
|
||||
|
||||
func SetDefaultConfig(cfg []byte) {
|
||||
_defaultConfig = cfg
|
||||
}
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNats) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentNats) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNats) _getConfig(getCfg libcfg.FuncComponentConfigGet) (libnat.Config, liberr.Error) {
|
||||
var (
|
||||
cfg = libnat.Config{}
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if e := getCfg(c.key, &cfg); e != nil {
|
||||
return cfg, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return cfg, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 natsServer
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libnat "github.com/nabbar/golib/nats"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
natsrv "github.com/nats-io/nats-server/v2/server"
|
||||
)
|
||||
|
||||
type componentNats struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
t string
|
||||
n libnat.Server
|
||||
}
|
||||
|
||||
func (c *componentNats) _CheckDep() bool {
|
||||
return c != nil && c.t != ""
|
||||
}
|
||||
|
||||
func (c *componentNats) _GetTLS() (libtls.TLSConfig, liberr.Error) {
|
||||
if !c._CheckDep() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if i := cpttls.Load(c.get, c.t); i == nil {
|
||||
return nil, ErrorDependencyTLSDefault.Error(nil)
|
||||
} else if tls := i.GetTLS(); tls == nil {
|
||||
return nil, ErrorDependencyTLSDefault.Error(nil)
|
||||
} else {
|
||||
return tls, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNats) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.n != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNats) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNats) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
var (
|
||||
tls libtls.TLSConfig
|
||||
err liberr.Error
|
||||
cfg libnat.Config
|
||||
opt *natsrv.Options
|
||||
)
|
||||
|
||||
if cfg, err = c._getConfig(getCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if tls, err = c._GetTLS(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opt, err = cfg.NatsOption(tls); err != nil {
|
||||
return ErrorStartComponent.Error(err)
|
||||
}
|
||||
|
||||
if c.n != nil {
|
||||
c.n.SetOptions(opt)
|
||||
if err = c.n.Restart(c.ctx()); err != nil {
|
||||
return ErrorReloadComponent.Error(err)
|
||||
}
|
||||
} else {
|
||||
c.n = libnat.NewServer(opt, cfg.Status)
|
||||
if err = c.n.Listen(c.ctx()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNats) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
if !c._CheckDep() {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNats) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentNats) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentNats) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentNats) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentNats) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c != nil && c.n != nil
|
||||
}
|
||||
|
||||
func (c *componentNats) IsRunning(atLeast bool) bool {
|
||||
if c.IsStarted() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.n.IsRunning()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *componentNats) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentNats) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentNats) Stop() {
|
||||
if c.IsRunning(true) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.n.Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNats) Dependencies() []string {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if !c._CheckDep() {
|
||||
return []string{cpttls.ComponentType}
|
||||
}
|
||||
|
||||
return []string{c.t}
|
||||
}
|
||||
|
||||
func (c *componentNats) SetTLSKey(tlsKey string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.t = tlsKey
|
||||
}
|
||||
|
||||
func (c *componentNats) GetServer() (libnat.Server, liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
return c.n, nil
|
||||
}
|
||||
|
||||
func (c *componentNats) SetStatusRouter(sts libsts.RouteStatus, prefix string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.n.StatusRouter(sts, prefix)
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 nutsdb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libndb "github.com/nabbar/golib/nutsdb"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
"db":{
|
||||
"entry_idx_mode":0,
|
||||
"rw_mode":0,
|
||||
"segment_size":8388608,
|
||||
"sync_enable":false,
|
||||
"start_file_loading_mode":1
|
||||
},
|
||||
"cluster":{
|
||||
"node":{
|
||||
"deployment_id":0,
|
||||
"wal_dir":"",
|
||||
"node_host_dir":"",
|
||||
"rtt_millisecond":200,
|
||||
"raft_address":"localhost:9001",
|
||||
"address_by_node_host_id":false,
|
||||
"listen_address":"",
|
||||
"mutual_tls":false,
|
||||
"ca_file":"",
|
||||
"cert_file":"",
|
||||
"key_file":"",
|
||||
"enable_metrics":true,
|
||||
"max_send_queue_size":0,
|
||||
"max_receive_queue_size":0,
|
||||
"max_snapshot_send_bytes_per_second":0,
|
||||
"max_snapshot_recv_bytes_per_second":0,
|
||||
"notify_commit":false,
|
||||
"gossip":{
|
||||
"bind_address":"",
|
||||
"advertise_address":"",
|
||||
"seed":null
|
||||
},
|
||||
"expert":{
|
||||
"engine":{
|
||||
"exec_shards":0,
|
||||
"commit_shards":0,
|
||||
"apply_shards":0,
|
||||
"snapshot_shards":0,
|
||||
"close_shards":0
|
||||
},
|
||||
"test_node_host_id":0,
|
||||
"test_gossip_probe_interval":0
|
||||
}
|
||||
},
|
||||
"cluster":{
|
||||
"node_id":1,
|
||||
"cluster_id":1,
|
||||
"check_quorum":true,
|
||||
"election_rtt":15,
|
||||
"heartbeat_rtt":1,
|
||||
"snapshot_entries":10,
|
||||
"compaction_overhead":0,
|
||||
"ordered_config_change":false,
|
||||
"max_in_mem_log_size":0,
|
||||
"snapshot_compression":0,
|
||||
"entry_compression":0,
|
||||
"disable_auto_compactions":true,
|
||||
"is_observer":false,
|
||||
"is_witness":false,
|
||||
"quiesce":false
|
||||
},
|
||||
"init_member":{
|
||||
"1":"localhost:9001"
|
||||
}
|
||||
},
|
||||
"directories":{
|
||||
"base":"/tmp/nutsdb/node-%d",
|
||||
"sub_data":"data",
|
||||
"sub_backup":"backup",
|
||||
"sub_temp":"temp",
|
||||
"wal_dir":"",
|
||||
"host_dir":"",
|
||||
"limit_number_backup":5,
|
||||
"permission":504
|
||||
}
|
||||
}`)
|
||||
|
||||
func SetDefaultConfig(cfg []byte) {
|
||||
_defaultConfig = cfg
|
||||
}
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) _getConfig(getCfg libcfg.FuncComponentConfigGet) (libndb.Config, liberr.Error) {
|
||||
var (
|
||||
cfg = libndb.Config{}
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if e := getCfg(c.key, &cfg); e != nil {
|
||||
return cfg, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return cfg, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 nutsdb
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cptlog "github.com/nabbar/golib/config/components/log"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libndb "github.com/nabbar/golib/nutsdb"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
)
|
||||
|
||||
type componentNutsDB struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
l string
|
||||
n libndb.NutsDB
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) _CheckDep() bool {
|
||||
return c != nil && c.l != ""
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) _GetLogger() (liblog.Logger, liberr.Error) {
|
||||
if !c._CheckDep() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if i := cptlog.Load(c.get, c.l); i == nil {
|
||||
return nil, ErrorDependencyLogDefault.Error(nil)
|
||||
} else if log := i.Log(); log == nil {
|
||||
return nil, ErrorDependencyLogDefault.Error(nil)
|
||||
} else {
|
||||
return log, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.n != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
var (
|
||||
err liberr.Error
|
||||
cfg libndb.Config
|
||||
)
|
||||
|
||||
if cfg, err = c._getConfig(getCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
srv := libndb.New(cfg)
|
||||
srv.SetLogger(func() liblog.Logger {
|
||||
var (
|
||||
l liblog.Logger
|
||||
e liberr.Error
|
||||
)
|
||||
|
||||
if l, e = c._GetLogger(); e != nil {
|
||||
return liblog.GetDefault()
|
||||
} else {
|
||||
return l
|
||||
}
|
||||
})
|
||||
|
||||
if err = srv.Listen(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.n != nil {
|
||||
_ = c.n.Shutdown()
|
||||
}
|
||||
|
||||
c.n = srv
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
if !c._CheckDep() {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c._CheckDep() && c.n != nil
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) IsRunning(atLeast bool) bool {
|
||||
if c.IsStarted() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.n.IsRunning()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) Stop() {
|
||||
if c.IsRunning(true) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
_ = c.n.Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) Dependencies() []string {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if !c._CheckDep() {
|
||||
return []string{cptlog.ComponentType}
|
||||
}
|
||||
|
||||
return []string{c.l}
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) GetServer() (libndb.NutsDB, liberr.Error) {
|
||||
if c.IsStarted() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.n, nil
|
||||
}
|
||||
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) SetLogger(key string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.l = key
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) GetClient(tickSync time.Duration) (libndb.Client, liberr.Error) {
|
||||
if c != nil && c.IsStarted() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.n.Client(c.ctx(), tickSync), nil
|
||||
}
|
||||
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
func (c *componentNutsDB) SetStatusRouter(sts libsts.RouteStatus, prefix string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.n.StatusRouter(sts, prefix)
|
||||
}
|
||||
BIN
config/components/old_cpt.tar.gz
Normal file
BIN
config/components/old_cpt.tar.gz
Normal file
Binary file not shown.
233
config/components/request/client.go
Normal file
233
config/components/request/client.go
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 request
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libreq "github.com/nabbar/golib/request"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentRequest) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getContext() context.Context {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.x.GetContext()
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _GetTLS() libtls.TLSConfig {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.t == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if i := cpttls.Load(o._getFctCpt(), o.t); i == nil {
|
||||
return nil
|
||||
} else if tls := i.GetTLS(); tls == nil {
|
||||
return nil
|
||||
} else {
|
||||
return tls
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentRequest) _runCli() liberr.Error {
|
||||
var (
|
||||
e error
|
||||
err liberr.Error
|
||||
prt = ErrorComponentReload
|
||||
req libreq.Request
|
||||
cfg *libreq.Options
|
||||
)
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorComponentStart
|
||||
} else {
|
||||
req = o.r
|
||||
}
|
||||
|
||||
if cfg, err = o._getConfig(); err != nil {
|
||||
return prt.Error(err)
|
||||
}
|
||||
|
||||
cfg.SetDefaultTLS(o._GetTLS)
|
||||
cfg.SetDefaultLog(o.getLogger)
|
||||
|
||||
if req != nil {
|
||||
req.RegisterDefaultLogger(o.getLogger)
|
||||
if req, e = cfg.Update(o.x.GetContext, req); err != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
} else {
|
||||
if req, e = cfg.New(o.x.GetContext); err != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
}
|
||||
|
||||
o.m.Lock()
|
||||
o.r = req
|
||||
o.m.Unlock()
|
||||
|
||||
if e = o._registerMonitor(cfg); e != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentRequest) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
160
config/components/request/component.go
Normal file
160
config/components/request/component.go
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 request
|
||||
|
||||
import (
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "request"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentRequest) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentRequest) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentRequest) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentRequest) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentRequest) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o != nil && o.r != nil
|
||||
}
|
||||
|
||||
func (o *componentRequest) IsRunning() bool {
|
||||
return o.IsStarted()
|
||||
}
|
||||
|
||||
func (o *componentRequest) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentRequest) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentRequest) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.r = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentRequest) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = []string{cpttls.ComponentType}
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if len(o.t) > 0 {
|
||||
def = []string{o.t}
|
||||
}
|
||||
|
||||
if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
63
config/components/request/config.go
Normal file
63
config/components/request/config.go
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 request
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libreq "github.com/nabbar/golib/request"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentRequest) RegisterFlag(Command *spfcbr.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getConfig() (*libreq.Options, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg libreq.Options
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -30,25 +30,14 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cmptls "github.com/nabbar/golib/config/components/tls"
|
||||
libsts "github.com/nabbar/golib/status/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgcst "github.com/nabbar/golib/config/const"
|
||||
libhtc "github.com/nabbar/golib/httpcli"
|
||||
moncfg "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
"endpoint":"https://endpoint.example.com/path",
|
||||
"http_client": {
|
||||
"timeout":"0s",
|
||||
"http2": true,
|
||||
"tls": ` + string(cmptls.DefaultConfig(" ")) + `,
|
||||
"force_ip": {
|
||||
"enable": false,
|
||||
"net":"tcp",
|
||||
"ip":"127.0.0.1:8080"
|
||||
}
|
||||
},
|
||||
"http_client": ` + string(libhtc.DefaultConfig(cfgcst.JSONIndent)) + `,
|
||||
"auth": {
|
||||
"basic":{
|
||||
"enable": false,
|
||||
@@ -80,7 +69,7 @@ var _defaultConfig = []byte(`{
|
||||
"contain": ["OK", "Done"],
|
||||
"not_contain": ["KO", "fail", "error"]
|
||||
},
|
||||
"status": ` + string(libsts.DefaultConfig(" ")) + `
|
||||
"monitor": ` + string(moncfg.DefaultConfig(cfgcst.JSONIndent)) + `
|
||||
}
|
||||
}`)
|
||||
|
||||
@@ -90,17 +79,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentRequest) DefaultConfig(indent string) []byte {
|
||||
func (o *componentRequest) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentRequest) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ const (
|
||||
ErrorComponentNotInitialized
|
||||
ErrorConfigInvalid
|
||||
ErrorDependencyTLSDefault
|
||||
ErrorComponentStart
|
||||
ErrorComponentReload
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -60,6 +62,10 @@ func getMessage(code liberr.CodeError) (message string) {
|
||||
return "server invalid config"
|
||||
case ErrorDependencyTLSDefault:
|
||||
return "cannot retrieve TLS component"
|
||||
case ErrorComponentStart:
|
||||
return "cannot start component with config"
|
||||
case ErrorComponentReload:
|
||||
return "cannot restart component with new config"
|
||||
}
|
||||
|
||||
return liberr.NullMessage
|
||||
|
||||
@@ -30,28 +30,24 @@ import (
|
||||
"sync"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
libreq "github.com/nabbar/golib/request"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "request"
|
||||
)
|
||||
|
||||
type ComponentRequest interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
SetHTTPClient(fct libreq.FctHttpClient)
|
||||
SetDefaultTLS(key string)
|
||||
|
||||
Request() (libreq.Request, error)
|
||||
}
|
||||
|
||||
func New(tls string, cli libreq.FctHttpClient) ComponentRequest {
|
||||
func New(ctx libctx.FuncContext, tls string) ComponentRequest {
|
||||
return &componentRequest{
|
||||
m: sync.Mutex{},
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
r: nil,
|
||||
t: tls,
|
||||
c: cli,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,11 +55,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentRequest) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key, tls string, cli libreq.FctHttpClient) {
|
||||
cfg.ComponentSet(key, New(tls, cli))
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key, tls string) {
|
||||
cfg.ComponentSet(key, New(ctx, tls))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentRequest {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentRequest {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentRequest); !ok {
|
||||
|
||||
@@ -27,214 +27,31 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
libreq "github.com/nabbar/golib/request"
|
||||
)
|
||||
|
||||
type componentRequest struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
sts libcfg.FuncRouteStatus
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
r libreq.Request
|
||||
t string
|
||||
c libreq.FctHttpClient
|
||||
p montps.FuncPool
|
||||
}
|
||||
|
||||
func (c *componentRequest) _GetContext() context.Context {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentRequest) SetDefaultTLS(key string) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if c.ctx != nil {
|
||||
if x := c.ctx(); x != nil {
|
||||
return x
|
||||
}
|
||||
}
|
||||
|
||||
return context.Background()
|
||||
o.t = key
|
||||
}
|
||||
|
||||
func (c *componentRequest) _CheckInit() bool {
|
||||
return c != nil && c.r != nil
|
||||
}
|
||||
|
||||
func (c *componentRequest) _GetTLS() libtls.TLSConfig {
|
||||
if c.t == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if i := cpttls.Load(c.get, c.t); i == nil {
|
||||
return nil
|
||||
} else if tls := i.GetTLS(); tls == nil {
|
||||
return nil
|
||||
} else {
|
||||
return tls
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentRequest) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.r != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentRequest) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentRequest) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
cfg := libreq.Options{}
|
||||
cfg.SetDefaultTLS(c._GetTLS)
|
||||
|
||||
if err := getCfg(c.key, &cfg); err != nil {
|
||||
return ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
if c.r == nil {
|
||||
if r, e := cfg.New(c._GetContext, c.c, c._GetTLS); e != nil {
|
||||
return ErrorConfigInvalid.ErrorParent(e)
|
||||
} else {
|
||||
c.r = r
|
||||
}
|
||||
} else {
|
||||
if r, e := cfg.Update(c.r, c._GetContext, c.c, c._GetTLS); e != nil {
|
||||
return ErrorConfigInvalid.ErrorParent(e)
|
||||
} else {
|
||||
c.r = r
|
||||
}
|
||||
}
|
||||
|
||||
if c.sts != nil {
|
||||
if s := c.sts(); s != nil {
|
||||
c.r.StatusRegister(s, c.key)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentRequest) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentRequest) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentRequest) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
c.sts = sts
|
||||
}
|
||||
|
||||
func (c *componentRequest) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentRequest) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentRequest) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c != nil && c.r != nil
|
||||
}
|
||||
|
||||
func (c *componentRequest) IsRunning(atLeast bool) bool {
|
||||
return c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentRequest) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentRequest) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentRequest) Stop() {
|
||||
|
||||
}
|
||||
|
||||
func (c *componentRequest) Dependencies() []string {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c == nil || c.t == "" {
|
||||
return []string{cpttls.ComponentType}
|
||||
}
|
||||
|
||||
return []string{c.t}
|
||||
}
|
||||
|
||||
func (c *componentRequest) SetHTTPClient(fct libreq.FctHttpClient) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.c = fct
|
||||
}
|
||||
|
||||
func (c *componentRequest) SetDefaultTLS(key string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.t = key
|
||||
}
|
||||
|
||||
func (c *componentRequest) Request() (libreq.Request, error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.r.Clone()
|
||||
func (o *componentRequest) Request() (libreq.Request, error) {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.r.Clone()
|
||||
}
|
||||
|
||||
133
config/components/request/monitor.go
Normal file
133
config/components/request/monitor.go
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 request
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
libreq "github.com/nabbar/golib/request"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
)
|
||||
|
||||
func (o *componentRequest) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.p = fct
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getMonitorPool() montps.Pool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.p == nil {
|
||||
return nil
|
||||
} else if p := o.p(); p == nil {
|
||||
return nil
|
||||
} else {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentRequest) _registerMonitor(cfg *libreq.Options) error {
|
||||
var (
|
||||
e error
|
||||
key = o._getKey()
|
||||
mon montps.Monitor
|
||||
vrs = o._getVersion()
|
||||
ctx = o._getContext()
|
||||
)
|
||||
|
||||
if o._getMonitorPool() == nil {
|
||||
return nil
|
||||
} else if len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if cfg == nil {
|
||||
return ErrorConfigInvalid.Error(nil)
|
||||
} else if !o.IsStarted() {
|
||||
return ErrorComponentStart.Error(nil)
|
||||
} else if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
if mon, e = o._newMonitor(ctx, vrs); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if m := o._getMonitor(mon.Name()); m != nil {
|
||||
mon = m
|
||||
}
|
||||
|
||||
if mon == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mon.RegisterLoggerDefault(o.getLogger)
|
||||
|
||||
if e = mon.SetConfig(o.x.GetContext, cfg.Health.Monitor); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if e = mon.Restart(o.x.GetContext()); e != nil {
|
||||
return e
|
||||
} else if e = o._setMonitor(mon); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentRequest) _newMonitor(ctx context.Context, vrs libver.Version) (montps.Monitor, error) {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
return o.r.Monitor(ctx, vrs)
|
||||
}
|
||||
|
||||
func (o *componentRequest) _getMonitor(key string) montps.Monitor {
|
||||
var (
|
||||
mon montps.Monitor
|
||||
pol = o._getMonitorPool()
|
||||
)
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mon = pol.MonitorGet(key)
|
||||
return mon
|
||||
}
|
||||
|
||||
func (o *componentRequest) _setMonitor(mon montps.Monitor) error {
|
||||
var pol = o._getMonitorPool()
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pol.MonitorSet(mon)
|
||||
}
|
||||
233
config/components/smtp/client.go
Normal file
233
config/components/smtp/client.go
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 smtp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
moncfg "github.com/nabbar/golib/monitor/types"
|
||||
lbsmtp "github.com/nabbar/golib/smtp"
|
||||
smtpcf "github.com/nabbar/golib/smtp/config"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentSmtp) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getContext() context.Context {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.x.GetContext()
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _GetTLS() libtls.TLSConfig {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.t == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if i := cpttls.Load(o._getFctCpt(), o.t); i == nil {
|
||||
return nil
|
||||
} else if tls := i.GetTLS(); tls == nil {
|
||||
return nil
|
||||
} else {
|
||||
return tls
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _GetTLSConfig(cfg libtls.Config) *tls.Config {
|
||||
if i, e := cfg.NewFrom(o._GetTLS()); e != nil {
|
||||
return &tls.Config{}
|
||||
} else {
|
||||
return i.TlsConfig("")
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _runCli() liberr.Error {
|
||||
var (
|
||||
e error
|
||||
err liberr.Error
|
||||
prt = ErrorComponentReload
|
||||
obj lbsmtp.SMTP
|
||||
cfg smtpcf.Config
|
||||
mon *moncfg.Config
|
||||
)
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorComponentStart
|
||||
}
|
||||
|
||||
if cfg, mon, err = o._getConfig(); err != nil {
|
||||
return prt.Error(err)
|
||||
} else if obj, err = lbsmtp.New(cfg, o._GetTLSConfig(cfg.GetTls())); err != nil {
|
||||
return prt.Error(err)
|
||||
}
|
||||
|
||||
o.Stop()
|
||||
|
||||
o.m.Lock()
|
||||
o.s = obj
|
||||
o.m.Unlock()
|
||||
|
||||
if e = o._registerMonitor(mon); e != nil {
|
||||
return prt.ErrorParent(e)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
171
config/components/smtp/component.go
Normal file
171
config/components/smtp/component.go
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 smtp
|
||||
|
||||
import (
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "smtp"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentSmtp) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentSmtp) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentSmtp) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentSmtp) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentSmtp) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o != nil && len(o.t) > 0 && o.s != nil
|
||||
}
|
||||
|
||||
func (o *componentSmtp) IsRunning() bool {
|
||||
if !o.IsStarted() {
|
||||
return false
|
||||
}
|
||||
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.s.Check(o.x.GetContext()) == nil
|
||||
}
|
||||
|
||||
func (o *componentSmtp) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentSmtp) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentSmtp) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.s != nil {
|
||||
o.s.Close()
|
||||
}
|
||||
|
||||
o.s = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentSmtp) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = []string{cpttls.ComponentType}
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if len(o.t) > 0 {
|
||||
def = []string{o.t}
|
||||
}
|
||||
|
||||
if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
89
config/components/smtp/config.go
Normal file
89
config/components/smtp/config.go
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 smtp
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libmon "github.com/nabbar/golib/monitor/types"
|
||||
smtpcf "github.com/nabbar/golib/smtp/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentSmtp) RegisterFlag(Command *spfcbr.Command) error {
|
||||
var (
|
||||
key string
|
||||
vpr *spfvpr.Viper
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
_ = Command.PersistentFlags().String(key+".dsn", "", "A DSN like string to describe the smtp connection. Format allowed is [user[:password]@][net[(addr)]]/tlsmode[?param1=value1¶mN=valueN] ")
|
||||
|
||||
if err := vpr.BindPFlag(key+".dsn", Command.PersistentFlags().Lookup(key+".dsn")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getConfig() (smtpcf.Config, *libmon.Config, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg smtpcf.ConfigModel
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
if val := vpr.GetString(key + "dsn"); val != "" {
|
||||
cfg.DSN = val
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
if c, e := cfg.Config(); e != nil {
|
||||
return nil, nil, e
|
||||
} else {
|
||||
return c, &cfg.Monitor, nil
|
||||
}
|
||||
}
|
||||
@@ -30,20 +30,15 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libsmtp "github.com/nabbar/golib/smtp"
|
||||
libsts "github.com/nabbar/golib/status/config"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgcst "github.com/nabbar/golib/config/const"
|
||||
moncfg "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
"dsn": "",
|
||||
"tls": ` + string(cpttls.DefaultConfig(libcfg.JSONIndent)) + `,
|
||||
"status": ` + string(libsts.DefaultConfig(libcfg.JSONIndent)) + `
|
||||
"tls": ` + string(cpttls.DefaultConfig(cfgcst.JSONIndent)) + `,
|
||||
"monitor": ` + string(moncfg.DefaultConfig(cfgcst.JSONIndent)) + `
|
||||
}`)
|
||||
|
||||
func SetDefaultConfig(cfg []byte) {
|
||||
@@ -52,58 +47,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgcst.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentSmtp) DefaultConfig(indent string) []byte {
|
||||
func (o *componentSmtp) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentSmtp) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
_ = Command.PersistentFlags().String(c.key+".dsn", "", "A DSN like string to describe the smtp connection. Format allowed is [user[:password]@][net[(addr)]]/tlsmode[?param1=value1¶mN=valueN] ")
|
||||
|
||||
if err := Viper.BindPFlag(c.key+".dsn", Command.PersistentFlags().Lookup(c.key+".dsn")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentSmtp) _getConfig(getCfg libcfg.FuncComponentConfigGet) (libsmtp.ConfigModel, liberr.Error) {
|
||||
var (
|
||||
cfg = libsmtp.ConfigModel{}
|
||||
vpr = c.vpr()
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if e := getCfg(c.key, &cfg); e != nil {
|
||||
return cfg, ErrorParamInvalid.Error(e)
|
||||
}
|
||||
|
||||
if val := vpr.GetString(c.key + "dsn"); val != "" {
|
||||
cfg.DSN = val
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return cfg, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
cfg.RegisterDefaultTLS(func() libtls.TLSConfig {
|
||||
var (
|
||||
t libtls.TLSConfig
|
||||
e liberr.Error
|
||||
)
|
||||
|
||||
if t, e = c._GetTLS(); e != nil {
|
||||
return t
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
})
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -38,10 +38,8 @@ const (
|
||||
ErrorParamInvalid
|
||||
ErrorComponentNotInitialized
|
||||
ErrorConfigInvalid
|
||||
ErrorStartComponent
|
||||
ErrorReloadComponent
|
||||
ErrorDependencyTLSDefault
|
||||
ErrorDependencyLogDefault
|
||||
ErrorComponentStart
|
||||
ErrorComponentReload
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -61,14 +59,10 @@ func getMessage(code liberr.CodeError) (message string) {
|
||||
return "this component seems to not be correctly initialized"
|
||||
case ErrorConfigInvalid:
|
||||
return "invalid component config"
|
||||
case ErrorStartComponent:
|
||||
case ErrorComponentStart:
|
||||
return "cannot start component with config"
|
||||
case ErrorReloadComponent:
|
||||
case ErrorComponentReload:
|
||||
return "cannot reload component with new config"
|
||||
case ErrorDependencyTLSDefault:
|
||||
return "cannot retrieve TLS Component"
|
||||
case ErrorDependencyLogDefault:
|
||||
return "cannot retrieve Logger Component"
|
||||
}
|
||||
|
||||
return liberr.NullMessage
|
||||
|
||||
@@ -31,38 +31,29 @@ import (
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libsmtp "github.com/nabbar/golib/smtp"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "smtp"
|
||||
lbsmtp "github.com/nabbar/golib/smtp"
|
||||
)
|
||||
|
||||
type ComponentSMTP interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
|
||||
SetTLSKey(tlsKey string)
|
||||
GetSMTP() (libsmtp.SMTP, liberr.Error)
|
||||
SetStatusRouter(sts libsts.RouteStatus, prefix string)
|
||||
GetSMTP() (lbsmtp.SMTP, liberr.Error)
|
||||
}
|
||||
|
||||
func New(tlsKey string) ComponentSMTP {
|
||||
func New(ctx libctx.FuncContext, tlsKey string) ComponentSMTP {
|
||||
if tlsKey == "" {
|
||||
tlsKey = cpttls.ComponentType
|
||||
}
|
||||
|
||||
return &componentSmtp{
|
||||
ctx: nil,
|
||||
get: nil,
|
||||
fsa: nil,
|
||||
fsb: nil,
|
||||
fra: nil,
|
||||
frb: nil,
|
||||
m: sync.Mutex{},
|
||||
t: tlsKey,
|
||||
s: nil,
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
t: tlsKey,
|
||||
s: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,11 +61,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentSMTP) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key, tlsKey string) {
|
||||
cfg.ComponentSet(key, New(tlsKey))
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key, tlsKey string) {
|
||||
cfg.ComponentSet(key, New(ctx, tlsKey))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentSMTP {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentSMTP {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentSMTP); !ok {
|
||||
|
||||
@@ -29,214 +29,34 @@ package smtp
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
cpttls "github.com/nabbar/golib/config/components/tls"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
libsmtp "github.com/nabbar/golib/smtp"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
)
|
||||
|
||||
type componentSmtp struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
p montps.FuncPool
|
||||
t string
|
||||
s libsmtp.SMTP
|
||||
}
|
||||
|
||||
func (c *componentSmtp) _CheckDep() bool {
|
||||
return c != nil && c.t != ""
|
||||
func (o *componentSmtp) SetTLSKey(tlsKey string) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.t = tlsKey
|
||||
}
|
||||
|
||||
func (c *componentSmtp) _GetTLS() (libtls.TLSConfig, liberr.Error) {
|
||||
if !c._CheckDep() {
|
||||
func (o *componentSmtp) GetSMTP() (libsmtp.SMTP, liberr.Error) {
|
||||
if !o.IsStarted() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if i := cpttls.Load(c.get, c.t); i == nil {
|
||||
return nil, ErrorDependencyTLSDefault.Error(nil)
|
||||
} else if tls := i.GetTLS(); tls == nil {
|
||||
return nil, ErrorDependencyTLSDefault.Error(nil)
|
||||
} else {
|
||||
return tls, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentSmtp) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.s != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentSmtp) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentSmtp) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
var (
|
||||
err liberr.Error
|
||||
cli libsmtp.SMTP
|
||||
cfg libsmtp.ConfigModel
|
||||
)
|
||||
|
||||
if cfg, err = c._getConfig(getCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cli, err = cfg.GetSMTP(); err != nil {
|
||||
if c.s != nil {
|
||||
return ErrorReloadComponent.Error(err)
|
||||
}
|
||||
return ErrorStartComponent.Error(err)
|
||||
}
|
||||
|
||||
if c.s != nil {
|
||||
_ = c.s.Close
|
||||
}
|
||||
|
||||
c.s = cli
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentSmtp) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
if !c._CheckDep() {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentSmtp) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentSmtp) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentSmtp) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentSmtp) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentSmtp) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c._CheckDep() && c.s != nil
|
||||
}
|
||||
|
||||
func (c *componentSmtp) IsRunning(atLeast bool) bool {
|
||||
if !c.IsStarted() {
|
||||
return false
|
||||
}
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
e := c.s.Check(c.ctx())
|
||||
return e == nil
|
||||
}
|
||||
|
||||
func (c *componentSmtp) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentSmtp) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentSmtp) Stop() {
|
||||
if !c.IsStarted() {
|
||||
return
|
||||
}
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.s.Close()
|
||||
}
|
||||
|
||||
func (c *componentSmtp) Dependencies() []string {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if !c._CheckDep() {
|
||||
return []string{cpttls.ComponentType}
|
||||
}
|
||||
|
||||
return []string{c.t}
|
||||
}
|
||||
|
||||
func (c *componentSmtp) SetTLSKey(tlsKey string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.t = tlsKey
|
||||
}
|
||||
|
||||
func (c *componentSmtp) GetSMTP() (libsmtp.SMTP, liberr.Error) {
|
||||
if !c.IsStarted() {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.s.Clone(), nil
|
||||
}
|
||||
|
||||
func (c *componentSmtp) SetStatusRouter(sts libsts.RouteStatus, prefix string) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.s.StatusRouter(sts, prefix)
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
return o.s.Clone(), nil
|
||||
}
|
||||
|
||||
129
config/components/smtp/monitor.go
Normal file
129
config/components/smtp/monitor.go
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 smtp
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
)
|
||||
|
||||
func (o *componentSmtp) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.p = fct
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getMonitorPool() montps.Pool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.p == nil {
|
||||
return nil
|
||||
} else if p := o.p(); p == nil {
|
||||
return nil
|
||||
} else {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _registerMonitor(cfg *montps.Config) error {
|
||||
var (
|
||||
e error
|
||||
key = o._getKey()
|
||||
mon montps.Monitor
|
||||
vrs = o._getVersion()
|
||||
ctx = o._getContext
|
||||
)
|
||||
|
||||
if o._getMonitorPool() == nil {
|
||||
return nil
|
||||
} else if len(key) < 1 {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else if cfg == nil {
|
||||
return ErrorConfigInvalid.Error(nil)
|
||||
} else if !o.IsStarted() {
|
||||
return ErrorComponentStart.Error(nil)
|
||||
} else if ctx == nil {
|
||||
ctx = context.Background
|
||||
}
|
||||
|
||||
if mon = o._getMonitor(key); mon == nil {
|
||||
if mon, e = o._newMonitor(ctx, vrs); e != nil {
|
||||
return e
|
||||
} else if mon == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
mon.RegisterLoggerDefault(o.getLogger)
|
||||
|
||||
if e = mon.SetConfig(o.x.GetContext, *cfg); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if e = mon.Restart(o.x.GetContext()); e != nil {
|
||||
return e
|
||||
} else if e = o._setMonitor(mon); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _newMonitor(ctx libctx.FuncContext, vrs libver.Version) (montps.Monitor, error) {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
return o.s.Monitor(ctx, vrs)
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _getMonitor(key string) montps.Monitor {
|
||||
var (
|
||||
mon montps.Monitor
|
||||
pol = o._getMonitorPool()
|
||||
)
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mon = pol.MonitorGet(key)
|
||||
return mon
|
||||
}
|
||||
|
||||
func (o *componentSmtp) _setMonitor(mon montps.Monitor) error {
|
||||
var pol = o._getMonitorPool()
|
||||
|
||||
if pol == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pol.MonitorSet(mon)
|
||||
}
|
||||
188
config/components/tls/client.go
Normal file
188
config/components/tls/client.go
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 tls
|
||||
|
||||
import (
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentTls) _getKey() string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptKey); !l {
|
||||
return ""
|
||||
} else if i == nil {
|
||||
return ""
|
||||
} else if v, k := i.(string); !k {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _getFctVpr() libvpr.FuncViper {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctViper); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _getViper() libvpr.Viper {
|
||||
if f := o._getFctVpr(); f == nil {
|
||||
return nil
|
||||
} else if v := f(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _getSPFViper() *spfvbr.Viper {
|
||||
if f := o._getViper(); f == nil {
|
||||
return nil
|
||||
} else if v := f.Viper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _getFctCpt() cfgtps.FuncCptGet {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyFctGetCpt); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptGet); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _getVersion() libver.Version {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(keyCptVersion); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _getFct() (cfgtps.FuncCptEvent, cfgtps.FuncCptEvent) {
|
||||
if o.IsStarted() {
|
||||
return o._getFctEvt(keyFctRelBef), o._getFctEvt(keyFctRelAft)
|
||||
} else {
|
||||
return o._getFctEvt(keyFctStaBef), o._getFctEvt(keyFctStaAft)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _getFctEvt(key uint8) cfgtps.FuncCptEvent {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if i, l := o.x.Load(key); !l {
|
||||
return nil
|
||||
} else if i == nil {
|
||||
return nil
|
||||
} else if f, k := i.(cfgtps.FuncCptEvent); !k {
|
||||
return nil
|
||||
} else {
|
||||
return f
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) _runFct(fct func(cpt cfgtps.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(o)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentTls) _runCli() liberr.Error {
|
||||
var (
|
||||
err liberr.Error
|
||||
prt = ErrorComponentReload
|
||||
tls libtls.TLSConfig
|
||||
cfg *libtls.Config
|
||||
)
|
||||
|
||||
if !o.IsStarted() {
|
||||
prt = ErrorComponentStart
|
||||
}
|
||||
|
||||
if cfg, err = o._getConfig(); err != nil {
|
||||
return prt.Error(err)
|
||||
} else if tls, err = cfg.New(); err != nil {
|
||||
return prt.Error(err)
|
||||
}
|
||||
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.t = tls
|
||||
o.c = cfg
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentTls) _run() liberr.Error {
|
||||
fb, fa := o._getFct()
|
||||
|
||||
if err := o._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = o._runCli(); err != nil {
|
||||
return err
|
||||
} else if err = o._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
155
config/components/tls/component.go
Normal file
155
config/components/tls/component.go
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 tls
|
||||
|
||||
import (
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "tls"
|
||||
|
||||
keyCptKey = iota + 1
|
||||
keyCptDependencies
|
||||
keyFctViper
|
||||
keyFctGetCpt
|
||||
keyCptVersion
|
||||
keyCptLogger
|
||||
keyFctStaBef
|
||||
keyFctStaAft
|
||||
keyFctRelBef
|
||||
keyFctRelAft
|
||||
keyFctMonitorPool
|
||||
)
|
||||
|
||||
func (o *componentTls) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (o *componentTls) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if o.x == nil {
|
||||
o.x = libctx.NewConfig[uint8](ctx)
|
||||
} else {
|
||||
x := libctx.NewConfig[uint8](ctx)
|
||||
x.Merge(o.x)
|
||||
o.x = x
|
||||
}
|
||||
|
||||
o.x.Store(keyCptKey, key)
|
||||
o.x.Store(keyFctGetCpt, get)
|
||||
o.x.Store(keyFctViper, vpr)
|
||||
o.x.Store(keyCptVersion, vrs)
|
||||
o.x.Store(keyCptLogger, log)
|
||||
}
|
||||
|
||||
func (o *componentTls) RegisterFuncStart(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctStaBef, before)
|
||||
o.x.Store(keyFctStaAft, after)
|
||||
}
|
||||
|
||||
func (o *componentTls) RegisterFuncReload(before, after cfgtps.FuncCptEvent) {
|
||||
o.x.Store(keyFctRelBef, before)
|
||||
o.x.Store(keyFctRelAft, after)
|
||||
}
|
||||
|
||||
func (o *componentTls) IsStarted() bool {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
return o.t != nil
|
||||
}
|
||||
|
||||
func (o *componentTls) IsRunning() bool {
|
||||
return o.IsStarted()
|
||||
}
|
||||
|
||||
func (o *componentTls) Start() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentTls) Reload() liberr.Error {
|
||||
return o._run()
|
||||
}
|
||||
|
||||
func (o *componentTls) Stop() {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
o.t = nil
|
||||
return
|
||||
}
|
||||
|
||||
func (o *componentTls) Dependencies() []string {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
var def = make([]string, 0)
|
||||
|
||||
if o == nil {
|
||||
return def
|
||||
} else if o.x == nil {
|
||||
return def
|
||||
} else if i, l := o.x.Load(keyCptDependencies); !l {
|
||||
return def
|
||||
} else if v, k := i.([]string); !k {
|
||||
return def
|
||||
} else if len(v) > 0 {
|
||||
return v
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) SetDependencies(d []string) liberr.Error {
|
||||
o.m.RLock()
|
||||
defer o.m.RUnlock()
|
||||
|
||||
if o.x == nil {
|
||||
return ErrorComponentNotInitialized.Error(nil)
|
||||
} else {
|
||||
o.x.Store(keyCptDependencies, d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *componentTls) getLogger() liblog.Logger {
|
||||
if i, l := o.x.Load(keyCptLogger); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
63
config/components/tls/config.go
Normal file
63
config/components/tls/config.go
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 tls
|
||||
|
||||
import (
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (o *componentTls) RegisterFlag(Command *spfcbr.Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *componentTls) _getConfig() (*libtls.Config, liberr.Error) {
|
||||
var (
|
||||
key string
|
||||
cfg libtls.Config
|
||||
vpr *spfvpr.Viper
|
||||
err liberr.Error
|
||||
)
|
||||
|
||||
if vpr = o._getSPFViper(); vpr == nil {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
} else if key = o._getKey(); len(key) < 1 {
|
||||
return nil, ErrorComponentNotInitialized.Error(nil)
|
||||
}
|
||||
|
||||
if e := vpr.UnmarshalKey(key, &cfg); e != nil {
|
||||
return nil, ErrorParamInvalid.ErrorParent(e)
|
||||
}
|
||||
|
||||
if err = cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -30,11 +30,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvbr "github.com/spf13/viper"
|
||||
cfgtps "github.com/nabbar/golib/config/const"
|
||||
)
|
||||
|
||||
var _defaultConfig = []byte(`{
|
||||
@@ -100,31 +96,13 @@ func SetDefaultConfig(cfg []byte) {
|
||||
|
||||
func DefaultConfig(indent string) []byte {
|
||||
var res = bytes.NewBuffer(make([]byte, 0))
|
||||
if err := json.Indent(res, _defaultConfig, indent, libcfg.JSONIndent); err != nil {
|
||||
if err := json.Indent(res, _defaultConfig, indent, cfgtps.JSONIndent); err != nil {
|
||||
return _defaultConfig
|
||||
} else {
|
||||
return res.Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentTls) DefaultConfig(indent string) []byte {
|
||||
func (o *componentTls) DefaultConfig(indent string) []byte {
|
||||
return DefaultConfig(indent)
|
||||
}
|
||||
|
||||
func (c *componentTls) RegisterFlag(Command *spfcbr.Command, Viper *spfvbr.Viper) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentTls) _getConfig(getCfg libcfg.FuncComponentConfigGet) (*libtls.Config, liberr.Error) {
|
||||
cfg := libtls.Config{}
|
||||
|
||||
if err := getCfg(c.key, &cfg); err != nil {
|
||||
return nil, ErrorParamInvalid.Error(err)
|
||||
}
|
||||
|
||||
if err := cfg.Validate(); err != nil {
|
||||
return nil, ErrorConfigInvalid.Error(err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
@@ -27,24 +27,27 @@
|
||||
package tls
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
)
|
||||
|
||||
const (
|
||||
ComponentType = "tls"
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
)
|
||||
|
||||
type ComponentTlS interface {
|
||||
libcfg.Component
|
||||
cfgtps.Component
|
||||
Config() *libtls.Config
|
||||
GetTLS() libtls.TLSConfig
|
||||
SetTLS(tls libtls.TLSConfig)
|
||||
}
|
||||
|
||||
func New() ComponentTlS {
|
||||
func New(ctx libctx.FuncContext) ComponentTlS {
|
||||
return &componentTls{
|
||||
m: sync.RWMutex{},
|
||||
x: libctx.NewConfig[uint8](ctx),
|
||||
t: nil,
|
||||
c: nil,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,11 +55,11 @@ func Register(cfg libcfg.Config, key string, cpt ComponentTlS) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New())
|
||||
func RegisterNew(ctx libctx.FuncContext, cfg libcfg.Config, key string) {
|
||||
cfg.ComponentSet(key, New(ctx))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentTlS {
|
||||
func Load(getCpt cfgtps.FuncCptGet, key string) ComponentTlS {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentTlS); !ok {
|
||||
|
||||
@@ -30,158 +30,33 @@ import (
|
||||
"sync"
|
||||
|
||||
libtls "github.com/nabbar/golib/certificates"
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
)
|
||||
|
||||
type componentTls struct {
|
||||
ctx libcfg.FuncContext
|
||||
get libcfg.FuncComponentGet
|
||||
vpr libcfg.FuncComponentViper
|
||||
key string
|
||||
|
||||
fsa func(cpt libcfg.Component) liberr.Error
|
||||
fsb func(cpt libcfg.Component) liberr.Error
|
||||
fra func(cpt libcfg.Component) liberr.Error
|
||||
frb func(cpt libcfg.Component) liberr.Error
|
||||
|
||||
m sync.Mutex
|
||||
m sync.RWMutex
|
||||
x libctx.Config[uint8]
|
||||
t libtls.TLSConfig
|
||||
c *libtls.Config
|
||||
}
|
||||
|
||||
func (c *componentTls) _getFct() (func(cpt libcfg.Component) liberr.Error, func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentTls) Config() *libtls.Config {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
if c.t != nil {
|
||||
return c.frb, c.fra
|
||||
} else {
|
||||
return c.fsb, c.fsa
|
||||
}
|
||||
return o.c
|
||||
}
|
||||
|
||||
func (c *componentTls) _runFct(fct func(cpt libcfg.Component) liberr.Error) liberr.Error {
|
||||
if fct != nil {
|
||||
return fct(c)
|
||||
}
|
||||
func (o *componentTls) GetTLS() libtls.TLSConfig {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
return nil
|
||||
return o.t
|
||||
}
|
||||
|
||||
func (c *componentTls) _runCli(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
func (o *componentTls) SetTLS(tls libtls.TLSConfig) {
|
||||
o.m.Lock()
|
||||
defer o.m.Unlock()
|
||||
|
||||
var (
|
||||
err liberr.Error
|
||||
cfg *libtls.Config
|
||||
tls libtls.TLSConfig
|
||||
)
|
||||
|
||||
if cfg, err = c._getConfig(getCfg); err != nil {
|
||||
return err
|
||||
} else if tls, err = cfg.New(); err != nil {
|
||||
if c.t != nil {
|
||||
return ErrorComponentReload.Error(err)
|
||||
}
|
||||
return ErrorComponentStart.Error(err)
|
||||
} else {
|
||||
c.t = tls
|
||||
c.c = cfg
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentTls) _run(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
fb, fa := c._getFct()
|
||||
|
||||
if err := c._runFct(fb); err != nil {
|
||||
return err
|
||||
} else if err = c._runCli(getCfg); err != nil {
|
||||
return err
|
||||
} else if err = c._runFct(fa); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentTls) Type() string {
|
||||
return ComponentType
|
||||
}
|
||||
|
||||
func (c *componentTls) Init(key string, ctx libcfg.FuncContext, get libcfg.FuncComponentGet, vpr libcfg.FuncComponentViper, sts libcfg.FuncRouteStatus) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.key = key
|
||||
c.ctx = ctx
|
||||
c.get = get
|
||||
c.vpr = vpr
|
||||
}
|
||||
|
||||
func (c *componentTls) RegisterFuncStart(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fsb = before
|
||||
c.fsa = after
|
||||
}
|
||||
|
||||
func (c *componentTls) RegisterFuncReload(before, after func(cpt libcfg.Component) liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.frb = before
|
||||
c.fra = after
|
||||
}
|
||||
|
||||
func (c *componentTls) IsStarted() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.t != nil
|
||||
}
|
||||
|
||||
func (c *componentTls) IsRunning(atLeast bool) bool {
|
||||
return c.IsStarted()
|
||||
}
|
||||
|
||||
func (c *componentTls) Start(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentTls) Reload(getCfg libcfg.FuncComponentConfigGet) liberr.Error {
|
||||
return c._run(getCfg)
|
||||
}
|
||||
|
||||
func (c *componentTls) Stop() {
|
||||
return
|
||||
}
|
||||
|
||||
func (c *componentTls) Dependencies() []string {
|
||||
return make([]string, 0)
|
||||
}
|
||||
|
||||
func (c *componentTls) Config() *libtls.Config {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.c
|
||||
}
|
||||
|
||||
func (c *componentTls) GetTLS() libtls.TLSConfig {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.t
|
||||
}
|
||||
|
||||
func (c *componentTls) SetTLS(tls libtls.TLSConfig) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.t = tls
|
||||
o.t = tls
|
||||
}
|
||||
|
||||
34
config/components/tls/monitor.go
Normal file
34
config/components/tls/monitor.go
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 tls
|
||||
|
||||
import (
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
)
|
||||
|
||||
func (o *componentTls) RegisterMonitorPool(fct montps.FuncPool) {
|
||||
}
|
||||
31
config/const/const.go
Normal file
31
config/const/const.go
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 _const
|
||||
|
||||
const (
|
||||
JSONIndent = " "
|
||||
)
|
||||
65
config/context.go
Normal file
65
config/context.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 config
|
||||
|
||||
import (
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
)
|
||||
|
||||
func (c *configModel) Context() libctx.Config[string] {
|
||||
return c.ctx
|
||||
}
|
||||
|
||||
func (c *configModel) CancelAdd(fct ...func()) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fcnl = append(c.fcnl, fct...)
|
||||
}
|
||||
|
||||
func (c *configModel) CancelClean() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fcnl = make([]func(), 0)
|
||||
}
|
||||
|
||||
func (c *configModel) cancel() {
|
||||
if l := c.getCancelCustom(); len(l) > 0 {
|
||||
for _, f := range l {
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
c.Stop()
|
||||
}
|
||||
|
||||
func (c *configModel) getCancelCustom() []func() {
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
return c.fcnl
|
||||
}
|
||||
@@ -1,414 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const JSONIndent = " "
|
||||
|
||||
type ComponentList interface {
|
||||
// ComponentHas return true if the key is a registered Component
|
||||
ComponentHas(key string) bool
|
||||
|
||||
// ComponentType return the Component Type of the registered key.
|
||||
ComponentType(key string) string
|
||||
|
||||
// ComponentGet return the given component associated with the config Key.
|
||||
// The component can be transTyped to other interface to be exploited
|
||||
ComponentGet(key string) Component
|
||||
|
||||
// ComponentDel remove the given Component key from the config.
|
||||
ComponentDel(key string)
|
||||
|
||||
// ComponentSet stores the given Component with a key.
|
||||
ComponentSet(key string, cpt Component)
|
||||
|
||||
// ComponentList returns a map of stored couple keyType and Component
|
||||
ComponentList() map[string]Component
|
||||
|
||||
// ComponentKeys returns a slice of stored Component keys
|
||||
ComponentKeys() []string
|
||||
|
||||
// ComponentStart trigger the Start function of each Component.
|
||||
// This function will keep the dependencies of each Component.
|
||||
// This function will stop the Start sequence on any error triggered.
|
||||
ComponentStart(getCfg FuncComponentConfigGet) liberr.Error
|
||||
|
||||
// ComponentIsStarted will trigger the IsStarted function of all registered component.
|
||||
// If any component return false, this func return false.
|
||||
ComponentIsStarted() bool
|
||||
|
||||
// ComponentReload trigger the Reload function of each Component.
|
||||
// This function will keep the dependencies of each Component.
|
||||
// This function will stop the Reload sequence on any error triggered.
|
||||
ComponentReload(getCfg FuncComponentConfigGet) liberr.Error
|
||||
|
||||
// ComponentStop trigger the Stop function of each Component.
|
||||
// This function will not keep the dependencies of each Component.
|
||||
ComponentStop()
|
||||
|
||||
// ComponentIsRunning will trigger the IsRunning function of all registered component.
|
||||
// If any component return false, this func return false.
|
||||
ComponentIsRunning(atLeast bool) bool
|
||||
|
||||
// DefaultConfig aggregates all registered components' default config
|
||||
// Returns a filled buffer with a complete config json model
|
||||
DefaultConfig() io.Reader
|
||||
|
||||
// RegisterFlag can be called to register flag to a spf cobra command and link it with viper
|
||||
// to retrieve it into the config viper.
|
||||
// The key will be use to stay config organisation by compose flag as key.config_key.
|
||||
RegisterFlag(Command *spfcbr.Command, Viper *spfvpr.Viper) error
|
||||
}
|
||||
|
||||
func newComponentList() ComponentList {
|
||||
return &componentList{
|
||||
m: sync.Mutex{},
|
||||
l: make(map[string]*atomic.Value, 0),
|
||||
}
|
||||
}
|
||||
|
||||
type componentList struct {
|
||||
m sync.Mutex
|
||||
l map[string]*atomic.Value
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentHas(key string) bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
_, ok := c.l[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentType(key string) string {
|
||||
if !c.ComponentHas(key) {
|
||||
return ""
|
||||
} else if o := c.ComponentGet(key); o == nil {
|
||||
return ""
|
||||
} else {
|
||||
return o.Type()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentGet(key string) Component {
|
||||
if !c.ComponentHas(key) {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if len(c.l) < 1 {
|
||||
c.l = make(map[string]*atomic.Value, 0)
|
||||
}
|
||||
|
||||
if v := c.l[key]; v == nil {
|
||||
return nil
|
||||
} else if i := v.Load(); i == nil {
|
||||
return nil
|
||||
} else if o, ok := i.(Component); !ok {
|
||||
return nil
|
||||
} else {
|
||||
return o
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentDel(key string) {
|
||||
if !c.ComponentHas(key) {
|
||||
return
|
||||
}
|
||||
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if len(c.l) < 1 {
|
||||
c.l = make(map[string]*atomic.Value, 0)
|
||||
}
|
||||
|
||||
delete(c.l, key)
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentSet(key string, cpt Component) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if len(c.l) < 1 {
|
||||
c.l = make(map[string]*atomic.Value, 0)
|
||||
}
|
||||
|
||||
if v, ok := c.l[key]; !ok || v == nil {
|
||||
c.l[key] = new(atomic.Value)
|
||||
}
|
||||
|
||||
c.l[key].Store(cpt)
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentList() map[string]Component {
|
||||
var res = make(map[string]Component, 0)
|
||||
|
||||
for _, k := range c.ComponentKeys() {
|
||||
res[k] = c.ComponentGet(k)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentKeys() []string {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
var res = make([]string, 0)
|
||||
|
||||
for k := range c.l {
|
||||
res = append(res, k)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *componentList) startOne(key string, getCfg FuncComponentConfigGet) liberr.Error {
|
||||
var cpt Component
|
||||
|
||||
if !c.ComponentHas(key) {
|
||||
return ErrorComponentNotFound.ErrorParent(fmt.Errorf("component: %s", key))
|
||||
} else if cpt = c.ComponentGet(key); cpt == nil {
|
||||
return ErrorComponentNotFound.ErrorParent(fmt.Errorf("component: %s", key))
|
||||
} else if cpt.IsStarted() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if dep := cpt.Dependencies(); len(dep) > 0 {
|
||||
for _, k := range dep {
|
||||
|
||||
var err liberr.Error
|
||||
|
||||
for retry := 0; retry < 3; retry++ {
|
||||
|
||||
if err = c.startOne(k, getCfg); err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := cpt.Start(getCfg); err != nil {
|
||||
return err
|
||||
} else {
|
||||
c.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentStart(getCfg FuncComponentConfigGet) liberr.Error {
|
||||
for _, key := range c.ComponentKeys() {
|
||||
if err := c.startOne(key, getCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentIsStarted() bool {
|
||||
for _, k := range c.ComponentKeys() {
|
||||
if cpt := c.ComponentGet(k); cpt == nil {
|
||||
continue
|
||||
} else if ok := cpt.IsStarted(); !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *componentList) reloadOne(isReload []string, key string, getCfg FuncComponentConfigGet) ([]string, liberr.Error) {
|
||||
var (
|
||||
err = ErrorComponentReload.Error(nil)
|
||||
e liberr.Error
|
||||
cpt Component
|
||||
)
|
||||
|
||||
if !c.ComponentHas(key) {
|
||||
return isReload, ErrorComponentNotFound.ErrorParent(fmt.Errorf("component: %s", key))
|
||||
} else if cpt = c.ComponentGet(key); cpt == nil {
|
||||
return isReload, ErrorComponentNotFound.ErrorParent(fmt.Errorf("component: %s", key))
|
||||
} else if slices.Contains(isReload, key) {
|
||||
return isReload, nil
|
||||
}
|
||||
|
||||
if dep := cpt.Dependencies(); len(dep) > 0 {
|
||||
for _, k := range dep {
|
||||
if isReload, e = c.reloadOne(isReload, k, getCfg); e != nil {
|
||||
err.AddParentError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if e = cpt.Reload(getCfg); e != nil {
|
||||
er := ErrorComponentReload.ErrorParent(fmt.Errorf("component: %s", key))
|
||||
er.AddParentError(e)
|
||||
err.AddParentError(er)
|
||||
} else {
|
||||
c.ComponentSet(key, cpt)
|
||||
isReload = append(isReload, key)
|
||||
}
|
||||
|
||||
if !err.HasParent() {
|
||||
err = nil
|
||||
}
|
||||
|
||||
return isReload, err
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentReload(getCfg FuncComponentConfigGet) liberr.Error {
|
||||
var (
|
||||
err = ErrorComponentReload.Error(nil)
|
||||
e liberr.Error
|
||||
key string
|
||||
|
||||
isReload = make([]string, 0)
|
||||
)
|
||||
|
||||
for _, key = range c.ComponentKeys() {
|
||||
if isReload, e = c.reloadOne(isReload, key, getCfg); e != nil {
|
||||
err.AddParent(e)
|
||||
}
|
||||
}
|
||||
|
||||
if !err.HasParent() {
|
||||
err = nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentStop() {
|
||||
for _, key := range c.ComponentKeys() {
|
||||
if !c.ComponentHas(key) {
|
||||
continue
|
||||
}
|
||||
|
||||
cpt := c.ComponentGet(key)
|
||||
if cpt == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cpt.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *componentList) ComponentIsRunning(atLeast bool) bool {
|
||||
for _, k := range c.ComponentKeys() {
|
||||
if cpt := c.ComponentGet(k); cpt == nil {
|
||||
continue
|
||||
} else if ok := cpt.IsRunning(atLeast); !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *componentList) DefaultConfig() io.Reader {
|
||||
var buffer = bytes.NewBuffer(make([]byte, 0))
|
||||
|
||||
buffer.WriteString("{")
|
||||
buffer.WriteString("\n")
|
||||
|
||||
n := buffer.Len()
|
||||
|
||||
for _, k := range c.ComponentKeys() {
|
||||
if cpt := c.ComponentGet(k); cpt == nil {
|
||||
continue
|
||||
} else if p := cpt.DefaultConfig(JSONIndent); len(p) > 0 {
|
||||
if buffer.Len() > n {
|
||||
buffer.WriteString(",")
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
buffer.WriteString(fmt.Sprintf("%s\"%s\": ", JSONIndent, k))
|
||||
buffer.Write(p)
|
||||
}
|
||||
}
|
||||
|
||||
buffer.WriteString("\n")
|
||||
buffer.WriteString("}")
|
||||
|
||||
var (
|
||||
cmp = bytes.NewBuffer(make([]byte, 0))
|
||||
ind = bytes.NewBuffer(make([]byte, 0))
|
||||
)
|
||||
|
||||
if err := json.Compact(cmp, buffer.Bytes()); err != nil {
|
||||
return buffer
|
||||
} else if err = json.Indent(ind, cmp.Bytes(), "", JSONIndent); err != nil {
|
||||
return buffer
|
||||
}
|
||||
|
||||
return ind
|
||||
}
|
||||
|
||||
func (c *componentList) RegisterFlag(Command *spfcbr.Command, Viper *spfvpr.Viper) error {
|
||||
var err = ErrorComponentFlagError.Error(nil)
|
||||
|
||||
for _, k := range c.ComponentKeys() {
|
||||
if cpt := c.ComponentGet(k); cpt == nil {
|
||||
continue
|
||||
} else if e := cpt.RegisterFlag(Command, Viper); e != nil {
|
||||
err.AddParent(e)
|
||||
} else {
|
||||
c.ComponentSet(k, cpt)
|
||||
}
|
||||
}
|
||||
|
||||
if err.HasParent() {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -24,62 +24,53 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package natsServer
|
||||
package config
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"os"
|
||||
|
||||
libcfg "github.com/nabbar/golib/config"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libnat "github.com/nabbar/golib/nats"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultTlsKey = "tls"
|
||||
ComponentType = "natsServer"
|
||||
)
|
||||
|
||||
type ComponentNats interface {
|
||||
libcfg.Component
|
||||
|
||||
SetTLSKey(tlsKey string)
|
||||
GetServer() (libnat.Server, liberr.Error)
|
||||
SetStatusRouter(sts libsts.RouteStatus, prefix string)
|
||||
}
|
||||
|
||||
func New(tlsKey string) ComponentNats {
|
||||
if tlsKey == "" {
|
||||
tlsKey = DefaultTlsKey
|
||||
func (c *configModel) Start() liberr.Error {
|
||||
if err := c.runFuncStartBefore(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return &componentNats{
|
||||
ctx: nil,
|
||||
get: nil,
|
||||
fsa: nil,
|
||||
fsb: nil,
|
||||
fra: nil,
|
||||
frb: nil,
|
||||
m: sync.Mutex{},
|
||||
t: tlsKey,
|
||||
n: nil,
|
||||
if err := c.ComponentStart(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func Register(cfg libcfg.Config, key string, cpt ComponentNats) {
|
||||
cfg.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func RegisterNew(cfg libcfg.Config, key, tlsKey string) {
|
||||
cfg.ComponentSet(key, New(tlsKey))
|
||||
}
|
||||
|
||||
func Load(getCpt libcfg.FuncComponentGet, key string) ComponentNats {
|
||||
if c := getCpt(key); c == nil {
|
||||
return nil
|
||||
} else if h, ok := c.(ComponentNats); !ok {
|
||||
return nil
|
||||
} else {
|
||||
return h
|
||||
if err := c.runFuncStartAfter(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) Reload() liberr.Error {
|
||||
if err := c.runFuncReloadBefore(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.ComponentReload(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.runFuncReloadAfter(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) Stop() {
|
||||
_ = c.runFuncStopBefore()
|
||||
c.ComponentStop()
|
||||
_ = c.runFuncStopAfter()
|
||||
}
|
||||
|
||||
func (c *configModel) Shutdown(code int) {
|
||||
c.cancel()
|
||||
os.Exit(code)
|
||||
}
|
||||
@@ -33,102 +33,96 @@ import (
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
|
||||
cfgtps "github.com/nabbar/golib/config/types"
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libsts "github.com/nabbar/golib/status"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type FuncContext func() context.Context
|
||||
type FuncRouteStatus func() libsts.RouteStatus
|
||||
type FuncComponentGet func(key string) Component
|
||||
type FuncComponentViper func() *spfvpr.Viper
|
||||
type FuncComponentConfigGet func(key string, model interface{}) liberr.Error
|
||||
type FuncEvent func() liberr.Error
|
||||
|
||||
type Config interface {
|
||||
/*
|
||||
// Section Context : github.com/nabbar/golib/context
|
||||
*/
|
||||
|
||||
// Context return the current context pointer
|
||||
Context() context.Context
|
||||
// Context return the config context instance
|
||||
Context() libctx.Config[string]
|
||||
|
||||
// ContextMerge trigger the golib/context/config interface
|
||||
// and will merge the stored context value into current context
|
||||
ContextMerge(ctx libctx.Config) bool
|
||||
|
||||
// ContextStore trigger the golib/context/config interface
|
||||
// and will store a context value into current context
|
||||
ContextStore(key string, cfg interface{})
|
||||
|
||||
// ContextLoad trigger the golib/context/config interface
|
||||
// and will restore a context value or nil
|
||||
ContextLoad(key string) interface{}
|
||||
|
||||
// ContextSetCancel allow to register a custom function called on cancel context.
|
||||
// CancelAdd allow to register a slice of custom function called on cancel context.
|
||||
// On context cancel event or signal kill, term... this function will be called
|
||||
// before config stop and main context cancel function
|
||||
ContextSetCancel(fct func())
|
||||
CancelAdd(fct ...func())
|
||||
|
||||
// CancelClean allow clear the all Cancel func registered into slice
|
||||
CancelClean()
|
||||
|
||||
/*
|
||||
// Section Event : github.com/nabbar/golib/config
|
||||
// Section Manage : github.com/nabbar/golib/config
|
||||
*/
|
||||
|
||||
// RegisterFuncViper is used to expose golib Viper instance to all config component.
|
||||
// With this function, the component can load his own config part and start or reload.
|
||||
RegisterFuncViper(fct func() libvpr.Viper)
|
||||
|
||||
// RegisterFuncRouteStatus is used to expose golib Status Router instance to all config component.
|
||||
// With this function, the component can register component status for router status and expose his own health.
|
||||
RegisterFuncRouteStatus(fct FuncRouteStatus)
|
||||
|
||||
// Start will trigger the start function of all registered component.
|
||||
// If any component return an error, this func will stop the start
|
||||
// process and return the error.
|
||||
Start() liberr.Error
|
||||
|
||||
// RegisterFuncStartBefore allow to register a func to be call when the config Start
|
||||
// is trigger. This func is call before the start sequence.
|
||||
RegisterFuncStartBefore(fct func() liberr.Error)
|
||||
|
||||
// RegisterFuncStartAfter allow to register a func to be call when the config Start
|
||||
// is trigger. This func is call after the start sequence.
|
||||
RegisterFuncStartAfter(fct func() liberr.Error)
|
||||
|
||||
// Reload triggers the Reload function of each registered Component.
|
||||
Reload() liberr.Error
|
||||
|
||||
// RegisterFuncReloadBefore allow to register a func to be call when the config Reload
|
||||
// is trigger. This func is call before the reload sequence.
|
||||
RegisterFuncReloadBefore(fct func() liberr.Error)
|
||||
|
||||
// RegisterFuncReloadAfter allow to register a func to be call when the config Reload
|
||||
// is trigger. This func is call after the reload sequence.
|
||||
RegisterFuncReloadAfter(fct func() liberr.Error)
|
||||
|
||||
// Stop will trigger the stop function of all registered component.
|
||||
// All component must stop cleanly.
|
||||
Stop()
|
||||
|
||||
// RegisterFuncStopBefore allow to register a func to be call when the config Stop
|
||||
// is trigger. This func is call before the stop sequence.
|
||||
RegisterFuncStopBefore(fct func())
|
||||
|
||||
// RegisterFuncStopAfter allow to register a func to be call when the config Stop
|
||||
// is trigger. This func is call after the stop sequence.
|
||||
RegisterFuncStopAfter(fct func())
|
||||
|
||||
// Shutdown will trigger all stop function.
|
||||
// This function will call the Stop function and the private function cancel.
|
||||
// This will stop all process and do like a SIGTERM/SIGINT signal.
|
||||
// This will finish by an os.Exit with the given parameter code.
|
||||
Shutdown(code int)
|
||||
|
||||
/*
|
||||
// Section Events : github.com/nabbar/golib/config
|
||||
*/
|
||||
|
||||
// RegisterFuncViper is used to expose golib Viper instance to all config component.
|
||||
// With this function, the component can load his own config part and start or reload.
|
||||
RegisterFuncViper(fct libvpr.FuncViper)
|
||||
|
||||
// RegisterFuncStartBefore allow to register a func to be call when the config Start
|
||||
// is trigger. This func is call before the start sequence.
|
||||
RegisterFuncStartBefore(fct FuncEvent)
|
||||
|
||||
// RegisterFuncStartAfter allow to register a func to be call when the config Start
|
||||
// is trigger. This func is call after the start sequence.
|
||||
RegisterFuncStartAfter(fct FuncEvent)
|
||||
|
||||
// RegisterFuncReloadBefore allow to register a func to be call when the config Reload
|
||||
// is trigger. This func is call before the reload sequence.
|
||||
RegisterFuncReloadBefore(fct FuncEvent)
|
||||
|
||||
// RegisterFuncReloadAfter allow to register a func to be call when the config Reload
|
||||
// is trigger. This func is call after the reload sequence.
|
||||
RegisterFuncReloadAfter(fct FuncEvent)
|
||||
|
||||
// RegisterFuncStopBefore allow to register a func to be call when the config Stop
|
||||
// is trigger. This func is call before the stop sequence.
|
||||
RegisterFuncStopBefore(fct FuncEvent)
|
||||
|
||||
// RegisterFuncStopAfter allow to register a func to be call when the config Stop
|
||||
// is trigger. This func is call after the stop sequence.
|
||||
RegisterFuncStopAfter(fct FuncEvent)
|
||||
|
||||
// RegisterDefaultLogger allow to register a func to return a default logger.
|
||||
// This logger can be used by component to extend config ot to log message.
|
||||
RegisterDefaultLogger(fct liblog.FuncLog)
|
||||
|
||||
/*
|
||||
// Section Component : github.com/nabbar/golib/config
|
||||
*/
|
||||
ComponentList
|
||||
cfgtps.ComponentList
|
||||
cfgtps.ComponentMonitor
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -138,30 +132,42 @@ var (
|
||||
|
||||
func init() {
|
||||
ctx, cnl = context.WithCancel(context.Background())
|
||||
|
||||
go func() {
|
||||
// Wait for interrupt signal to gracefully shutdown the server with
|
||||
// a timeout of 5 seconds.
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT)
|
||||
signal.Notify(quit, syscall.SIGTERM)
|
||||
signal.Notify(quit, syscall.SIGQUIT)
|
||||
|
||||
select {
|
||||
case <-quit:
|
||||
cnl()
|
||||
case <-ctx.Done():
|
||||
cnl()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func New() Config {
|
||||
c := &configModel{
|
||||
m: sync.Mutex{},
|
||||
ctx: libctx.NewConfig(ctx),
|
||||
cpt: newComponentList(),
|
||||
func Shutdown() {
|
||||
cnl()
|
||||
}
|
||||
|
||||
func WaitNotify() {
|
||||
// Wait for interrupt signal to gracefully shutdown the server with
|
||||
// a timeout of 5 seconds.
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT)
|
||||
signal.Notify(quit, syscall.SIGTERM)
|
||||
signal.Notify(quit, syscall.SIGQUIT)
|
||||
|
||||
select {
|
||||
case <-quit:
|
||||
cnl()
|
||||
case <-ctx.Done():
|
||||
cnl()
|
||||
}
|
||||
}
|
||||
|
||||
func New(vrs libver.Version) Config {
|
||||
fct := func() context.Context {
|
||||
return ctx
|
||||
}
|
||||
|
||||
c := &configModel{
|
||||
m: sync.RWMutex{},
|
||||
ctx: libctx.NewConfig[string](fct),
|
||||
cpt: libctx.NewConfig[string](fct),
|
||||
fct: libctx.NewConfig[uint8](fct),
|
||||
fcnl: nil,
|
||||
}
|
||||
|
||||
c.RegisterVersion(vrs)
|
||||
|
||||
go func() {
|
||||
select {
|
||||
|
||||
216
config/manage.go
Normal file
216
config/manage.go
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 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 config
|
||||
|
||||
import (
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
liblog "github.com/nabbar/golib/logger"
|
||||
montps "github.com/nabbar/golib/monitor/types"
|
||||
libver "github.com/nabbar/golib/version"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func (c *configModel) RegisterVersion(vrs libver.Version) {
|
||||
c.fct.Store(fctVersion, vrs)
|
||||
}
|
||||
|
||||
func (c *configModel) getVersion() libver.Version {
|
||||
if i, l := c.fct.Load(fctVersion); !l {
|
||||
return nil
|
||||
} else if v, k := i.(libver.Version); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncViper(fct libvpr.FuncViper) {
|
||||
c.fct.Store(fctViper, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) getViper() libvpr.Viper {
|
||||
if i, l := c.fct.Load(fctViper); !l {
|
||||
return nil
|
||||
} else if v, k := i.(libvpr.FuncViper); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) getSPFViper() *spfvpr.Viper {
|
||||
if v := c.getViper(); v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v.Viper()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStartBefore(fct FuncEvent) {
|
||||
c.fct.Store(fctStartBefore, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) runFuncStartBefore() liberr.Error {
|
||||
if i, l := c.fct.Load(fctStartBefore); !l {
|
||||
return nil
|
||||
} else if v, k := i.(FuncEvent); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStartAfter(fct FuncEvent) {
|
||||
c.fct.Store(fctStartAfter, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) runFuncStartAfter() liberr.Error {
|
||||
if i, l := c.fct.Load(fctStartAfter); !l {
|
||||
return nil
|
||||
} else if v, k := i.(FuncEvent); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncReloadBefore(fct FuncEvent) {
|
||||
c.fct.Store(fctReloadBefore, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) runFuncReloadBefore() liberr.Error {
|
||||
if i, l := c.fct.Load(fctReloadBefore); !l {
|
||||
return nil
|
||||
} else if v, k := i.(FuncEvent); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncReloadAfter(fct FuncEvent) {
|
||||
c.fct.Store(fctReloadAfter, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) runFuncReloadAfter() liberr.Error {
|
||||
if i, l := c.fct.Load(fctReloadAfter); !l {
|
||||
return nil
|
||||
} else if v, k := i.(FuncEvent); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStopBefore(fct FuncEvent) {
|
||||
c.fct.Store(fctStopBefore, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) runFuncStopBefore() liberr.Error {
|
||||
if i, l := c.fct.Load(fctStopBefore); !l {
|
||||
return nil
|
||||
} else if v, k := i.(FuncEvent); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStopAfter(fct FuncEvent) {
|
||||
c.fct.Store(fctStopAfter, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) runFuncStopAfter() liberr.Error {
|
||||
if i, l := c.fct.Load(fctStopAfter); !l {
|
||||
return nil
|
||||
} else if v, k := i.(FuncEvent); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterDefaultLogger(fct liblog.FuncLog) {
|
||||
c.fct.Store(fctLoggerDef, fct)
|
||||
}
|
||||
|
||||
func (c *configModel) getDefaultLogger() liblog.Logger {
|
||||
if i, l := c.fct.Load(fctLoggerDef); !l {
|
||||
return nil
|
||||
} else if v, k := i.(liblog.FuncLog); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterMonitorPool(p montps.FuncPool) {
|
||||
c.fct.Store(fctMonitorPool, p)
|
||||
}
|
||||
|
||||
func (c *configModel) getFctMonitorPool() montps.FuncPool {
|
||||
if i, l := c.fct.Load(fctMonitorPool); !l {
|
||||
return nil
|
||||
} else if v, k := i.(montps.FuncPool); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) getMonitorPool() montps.Pool {
|
||||
if i, l := c.fct.Load(fctMonitorPool); !l {
|
||||
return nil
|
||||
} else if v, k := i.(montps.FuncPool); !k {
|
||||
return nil
|
||||
} else if v == nil {
|
||||
return nil
|
||||
} else {
|
||||
return v()
|
||||
}
|
||||
}
|
||||
284
config/model.go
284
config/model.go
@@ -27,279 +27,43 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
libctx "github.com/nabbar/golib/context"
|
||||
liberr "github.com/nabbar/golib/errors"
|
||||
libvpr "github.com/nabbar/golib/viper"
|
||||
spfcbr "github.com/spf13/cobra"
|
||||
spfvpr "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
fctViper uint8 = iota + 1
|
||||
fctStartBefore
|
||||
fctStartAfter
|
||||
fctReloadBefore
|
||||
fctReloadAfter
|
||||
fctStopBefore
|
||||
fctStopAfter
|
||||
fctVersion
|
||||
fctLoggerDef
|
||||
fctMonitorPool
|
||||
)
|
||||
|
||||
type configModel struct {
|
||||
m sync.Mutex
|
||||
m sync.RWMutex
|
||||
|
||||
ctx libctx.Config
|
||||
fcnl func()
|
||||
ctx libctx.Config[string]
|
||||
cpt libctx.Config[string]
|
||||
fct libctx.Config[uint8]
|
||||
|
||||
cpt ComponentList
|
||||
|
||||
fctGolibStatus FuncRouteStatus
|
||||
fctGolibViper func() libvpr.Viper
|
||||
fctStartBefore func() liberr.Error
|
||||
fctStartAfter func() liberr.Error
|
||||
fctReloadBefore func() liberr.Error
|
||||
fctReloadAfter func() liberr.Error
|
||||
fctStopBefore func()
|
||||
fctStopAfter func()
|
||||
fcnl []func()
|
||||
}
|
||||
|
||||
func (c *configModel) _ComponentGetConfig(key string, model interface{}) liberr.Error {
|
||||
var (
|
||||
err error
|
||||
vpr libvpr.Viper
|
||||
vip *spfvpr.Viper
|
||||
)
|
||||
|
||||
if c.cpt.ComponentHas(key) {
|
||||
if c.fctGolibViper == nil {
|
||||
return ErrorConfigMissingViper.Error(nil)
|
||||
} else if vpr = c.fctGolibViper(); vpr == nil {
|
||||
return ErrorConfigMissingViper.Error(nil)
|
||||
} else if vip = vpr.Viper(); vip == nil {
|
||||
return ErrorConfigMissingViper.Error(nil)
|
||||
}
|
||||
|
||||
err = vip.UnmarshalKey(key, model)
|
||||
} else {
|
||||
return ErrorComponentNotFound.ErrorParent(fmt.Errorf("component '%s'", key))
|
||||
}
|
||||
|
||||
return ErrorComponentConfigError.Iferror(err)
|
||||
}
|
||||
|
||||
func (c *configModel) Context() context.Context {
|
||||
return c.ctx
|
||||
}
|
||||
|
||||
func (c *configModel) ContextMerge(ctx libctx.Config) bool {
|
||||
return c.ctx.Merge(ctx)
|
||||
}
|
||||
|
||||
func (c *configModel) ContextStore(key string, cfg interface{}) {
|
||||
c.ctx.Store(key, cfg)
|
||||
}
|
||||
|
||||
func (c *configModel) ContextLoad(key string) interface{} {
|
||||
return c.ctx.Load(key)
|
||||
}
|
||||
|
||||
func (c *configModel) ContextSetCancel(fct func()) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.fcnl = fct
|
||||
}
|
||||
|
||||
func (c *configModel) cancel() {
|
||||
c.cancelCustom()
|
||||
c.Stop()
|
||||
}
|
||||
|
||||
func (c *configModel) cancelCustom() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.fcnl != nil {
|
||||
c.fcnl()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncViper(fct func() libvpr.Viper) {
|
||||
c.fctGolibViper = fct
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncRouteStatus(fct FuncRouteStatus) {
|
||||
c.fctGolibStatus = fct
|
||||
}
|
||||
|
||||
func (c *configModel) Start() liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.fctStartBefore != nil {
|
||||
if err := c.fctStartBefore(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.cpt.ComponentStart(c._ComponentGetConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.fctStartAfter != nil {
|
||||
if err := c.fctStartAfter(); err != nil {
|
||||
return err
|
||||
}
|
||||
if vpr := c.getViper(); vpr == nil {
|
||||
return ErrorConfigMissingViper.Error(nil)
|
||||
} else if vip := vpr.Viper(); vip == nil {
|
||||
return ErrorConfigMissingViper.Error(nil)
|
||||
} else if err := vpr.Viper().UnmarshalKey(key, model); err != nil {
|
||||
return ErrorComponentConfigError.ErrorParent(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStartBefore(fct func() liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.fctStartBefore = fct
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStartAfter(fct func() liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.fctStartAfter = fct
|
||||
}
|
||||
|
||||
func (c *configModel) Reload() liberr.Error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.fctReloadBefore != nil {
|
||||
if err := c.fctReloadBefore(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.cpt.ComponentReload(c._ComponentGetConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.fctReloadAfter != nil {
|
||||
if err := c.fctReloadAfter(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncReloadBefore(fct func() liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.fctReloadBefore = fct
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncReloadAfter(fct func() liberr.Error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.fctReloadAfter = fct
|
||||
}
|
||||
|
||||
func (c *configModel) Stop() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.fctStopBefore != nil {
|
||||
c.fctStopBefore()
|
||||
}
|
||||
|
||||
for _, k := range c.ComponentKeys() {
|
||||
cpt := c.ComponentGet(k)
|
||||
|
||||
if cpt == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cpt.Stop()
|
||||
}
|
||||
|
||||
if c.fctStopAfter != nil {
|
||||
c.fctStopAfter()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStopBefore(fct func()) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.fctStopBefore = fct
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFuncStopAfter(fct func()) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.fctStopAfter = fct
|
||||
}
|
||||
|
||||
func (c *configModel) Shutdown(code int) {
|
||||
c.cancel()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentHas(key string) bool {
|
||||
return c.cpt.ComponentHas(key)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentType(key string) string {
|
||||
return c.cpt.ComponentType(key)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentGet(key string) Component {
|
||||
return c.cpt.ComponentGet(key)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentDel(key string) {
|
||||
c.cpt.ComponentDel(key)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentSet(key string, cpt Component) {
|
||||
fv := func() *spfvpr.Viper {
|
||||
if c.fctGolibViper == nil {
|
||||
return nil
|
||||
} else if vpr := c.fctGolibViper(); vpr == nil {
|
||||
return nil
|
||||
} else {
|
||||
return vpr.Viper()
|
||||
}
|
||||
}
|
||||
|
||||
cpt.Init(key, c.Context, c.ComponentGet, fv, c.fctGolibStatus)
|
||||
c.cpt.ComponentSet(key, cpt)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentList() map[string]Component {
|
||||
return c.cpt.ComponentList()
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentKeys() []string {
|
||||
return c.cpt.ComponentKeys()
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentStart(getCfg FuncComponentConfigGet) liberr.Error {
|
||||
return c.cpt.ComponentStart(getCfg)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentIsStarted() bool {
|
||||
return c.cpt.ComponentIsStarted()
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentReload(getCfg FuncComponentConfigGet) liberr.Error {
|
||||
return c.cpt.ComponentReload(getCfg)
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentStop() {
|
||||
c.cpt.ComponentStop()
|
||||
}
|
||||
|
||||
func (c *configModel) ComponentIsRunning(atLeast bool) bool {
|
||||
return c.cpt.ComponentIsRunning(atLeast)
|
||||
}
|
||||
|
||||
func (c *configModel) DefaultConfig() io.Reader {
|
||||
return c.cpt.DefaultConfig()
|
||||
}
|
||||
|
||||
func (c *configModel) RegisterFlag(Command *spfcbr.Command, Viper *spfvpr.Viper) error {
|
||||
return c.cpt.RegisterFlag(Command, Viper)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user