Use components in Handler, pt2
continuous-integration/drone/tag Build is failing Details

master v0.4.0
René Jochum 1 year ago
parent 341239a874
commit fdf42b5e26
Signed by: jochum
GPG Key ID: F7D906F5E51E8E5E

@ -18,12 +18,14 @@ import (
sredis "github.com/ulule/limiter/v3/drivers/store/redis"
"github.com/gin-gonic/gin"
"go-micro.dev/v4"
"go-micro.dev/v4/client"
"go-micro.dev/v4/errors"
"go-micro.dev/v4/logger"
"google.golang.org/protobuf/types/known/emptypb"
"jochum.dev/jo-micro/auth2"
"jochum.dev/jo-micro/router/internal/ilogger"
"jochum.dev/jo-micro/components"
"jochum.dev/jo-micro/logruscomponent"
"jochum.dev/jo-micro/router"
"jochum.dev/jo-micro/router/internal/proto/routerclientpb"
"jochum.dev/jo-micro/router/internal/proto/routerserverpb"
"jochum.dev/jo-micro/router/internal/util"
@ -36,23 +38,21 @@ type JSONRoute struct {
// Handler is the handler for the proxy
type Handler struct {
service micro.Service
engine *gin.Engine
routerAuth auth2.RouterPlugin
routes map[string]*routerclientpb.RoutesReply_Route
rlStore limiter.Store
cReg *components.Registry
engine *gin.Engine
routes map[string]*routerclientpb.RoutesReply_Route
rlStore limiter.Store
}
func NewHandler() (*Handler, error) {
func New() *Handler {
return &Handler{
routes: make(map[string]*routerclientpb.RoutesReply_Route),
}, nil
}
}
func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth auth2.RouterPlugin, refreshSeconds int, rlStoreURL string) error {
h.service = service
func (h *Handler) Init(r *components.Registry, engine *gin.Engine, refreshSeconds int, rlStoreURL string) error {
h.cReg = r
h.engine = engine
h.routerAuth = routerAuth
globalGroup := h.engine.Group("")
if strings.HasPrefix(rlStoreURL, "redis://") {
@ -78,26 +78,28 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
// Refresh routes for the proxy every 10 seconds
go func() {
logger := logruscomponent.MustReg(h.cReg).Logger()
for {
ctx := context.Background()
services, err := util.FindByEndpoint(h.service, "RouterClientService.Routes")
services, err := util.FindByEndpoint(h.cReg.Service(), "RouterClientService.Routes")
if err != nil {
ilogger.Logrus().Error(err)
logger.Error(err)
continue
}
for _, s := range services {
ilogger.Logrus().WithField("service", s.Name).Tracef("Found service")
client := routerclientpb.NewRouterClientService(s.Name, h.service.Client())
sCtx, err := auth2.ClientAuthRegistry().Plugin().ServiceContext(ctx)
logger.WithField("service", s.Name).Tracef("Found service")
client := routerclientpb.NewRouterClientService(s.Name, h.cReg.Service().Client())
sCtx, err := auth2.ClientAuthMustReg(h.cReg).Plugin().ServiceContext(ctx)
if err != nil {
ilogger.Logrus().Error(err)
logger.Error(err)
continue
}
resp, err := client.Routes(sCtx, &emptypb.Empty{})
if err != nil {
ilogger.Logrus().Error(err)
logger.Error(err)
// failure in getting routes, silently ignore
continue
}
@ -117,7 +119,7 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
pathMethod := fmt.Sprintf("%s:%s%s", route.Method, g.BasePath(), route.Path)
path := fmt.Sprintf("%s%s", g.BasePath(), route.Path)
if _, ok := h.routes[pathMethod]; !ok {
ilogger.Logrus().
logger.
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
@ -128,7 +130,7 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
clientIPRatelimiter := make([]*limiter.Limiter, len(route.RatelimitClientIP))
if len(route.RatelimitClientIP) > 0 {
if h.rlStore == nil {
ilogger.Logrus().
logger.
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
@ -142,7 +144,7 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
for idx, rate := range route.RatelimitClientIP {
rate, err := limiter.NewRateFromFormatted(rate)
if err != nil {
ilogger.Logrus().
logger.
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
@ -164,7 +166,7 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
userRatelimiter := make([]*limiter.Limiter, len(route.RatelimitUser))
if route.AuthRequired && len(route.RatelimitUser) > 0 {
if h.rlStore == nil {
ilogger.Logrus().
logger.
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
@ -178,7 +180,7 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
for idx, rate := range route.RatelimitUser {
rate, err := limiter.NewRateFromFormatted(rate)
if err != nil {
ilogger.Logrus().
logger.
WithField("service", s.Name).
WithField("endpoint", route.Endpoint).
WithField("method", route.Method).
@ -208,6 +210,16 @@ func (h *Handler) Init(service micro.Service, engine *gin.Engine, routerAuth aut
}
}()
r2 := router.MustReg(h.cReg)
r2.Add(
router.NewRoute(
router.Method(router.MethodGet),
router.Path("/routes"),
router.Endpoint(routerserverpb.RouterServerService.Routes),
router.RatelimitClientIP("1-S", "50-M", "1000-H"),
),
)
return nil
}
@ -324,10 +336,10 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
request[pn] = p
}
req := h.service.Client().NewRequest(serviceName, route.Endpoint, request, client.WithContentType("application/json"))
req := h.cReg.Service().Client().NewRequest(serviceName, route.Endpoint, request, client.WithContentType("application/json"))
// Auth
u, authErr := h.routerAuth.Inspect(c.Request)
u, authErr := auth2.RouterAuthMust(c).Plugin().Inspect(c.Request)
var (
ctx context.Context
err error
@ -344,7 +356,7 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
c.Abort()
return
} else if authErr != nil {
ctx, err = h.routerAuth.ForwardContext(auth2.AnonUser, c.Request, c)
ctx, err = auth2.RouterAuthMust(c).Plugin().ForwardContext(auth2.AnonUser, c.Request, c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"errors": []gin.H{
@ -356,7 +368,7 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
})
}
} else {
ctx, err = h.routerAuth.ForwardContext(u, c.Request, c)
ctx, err = auth2.RouterAuthMust(c).Plugin().ForwardContext(u, c.Request, c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"errors": []gin.H{
@ -406,9 +418,9 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro
// remote call
var response json.RawMessage
err = h.service.Client().Call(ctx, req, &response)
err = h.cReg.Service().Client().Call(ctx, req, &response)
if err != nil {
ilogger.Logrus().Error(err)
logger.Error(err)
pErr := errors.FromError(err)
code := int(http.StatusInternalServerError)

@ -12,32 +12,43 @@ import (
"github.com/gin-gonic/gin"
httpServer "github.com/go-micro/plugins/v4/server/http"
"jochum.dev/jo-micro/auth2"
jwtClient "jochum.dev/jo-micro/auth2/plugins/client/jwt"
jwtRouter "jochum.dev/jo-micro/auth2/plugins/router/jwt"
"jochum.dev/jo-micro/auth2/plugins/verifier/endpointroles"
"jochum.dev/jo-micro/components"
"jochum.dev/jo-micro/logruscomponent"
"jochum.dev/jo-micro/router"
"jochum.dev/jo-micro/router/cmd/microrouterd/config"
"jochum.dev/jo-micro/router/cmd/microrouterd/handler"
"jochum.dev/jo-micro/router/internal/ilogger"
"jochum.dev/jo-micro/router/internal/proto/routerserverpb"
"jochum.dev/jo-micro/router/internal/util"
)
func internalService(routerHandler *handler.Handler) {
srv := micro.NewService()
func internalService(cReg *components.Registry, r *gin.Engine) {
routerHandler := handler.New()
opts := []micro.Option{
micro.Name(config.Name + "-internal"),
micro.Version(config.Version),
micro.WrapHandler(auth2.ClientAuthRegistry().Wrapper()),
micro.WrapHandler(cReg.WrapHandler()),
micro.Action(func(c *cli.Context) error {
if err := auth2.ClientAuthRegistry().Init(auth2.CliContext(c), auth2.Service(srv), auth2.Logrus(ilogger.Logrus())); err != nil {
ilogger.Logrus().Fatal(err)
// Start the components
if err := cReg.Init(c); err != nil {
log.Fatal(err)
return err
}
routerserverpb.RegisterRouterServerServiceHandler(srv.Server(), routerHandler)
// Initalize the Handler
if err := routerHandler.Init(cReg, r, c.Int("router_refresh"), c.String("router_ratelimiter_store_url")); err != nil {
logger.Fatal(err)
return err
}
routerserverpb.RegisterRouterServerServiceHandler(cReg.Service().Server(), routerHandler)
authVerifier := endpointroles.NewVerifier(
endpointroles.WithLogrus(ilogger.Logrus()),
endpointroles.WithLogrus(logruscomponent.MustReg(cReg).Logger()),
)
authVerifier.AddRules(
endpointroles.RouterRule,
@ -46,49 +57,51 @@ func internalService(routerHandler *handler.Handler) {
endpointroles.RolesAllow(auth2.RolesServiceAndAdmin),
),
)
auth2.ClientAuthRegistry().Plugin().SetVerifier(authVerifier)
r := router.NewHandler(
c.String("router_basepath"),
router.NewRoute(
router.Method(router.MethodGet),
router.Path("/routes"),
router.Endpoint(routerserverpb.RouterServerService.Routes),
router.RatelimitClientIP("1-S", "50-M", "1000-H"),
),
)
r.RegisterWithServer(srv.Server())
auth2.ClientAuthMustReg(cReg).Plugin().SetVerifier(authVerifier)
return nil
}),
}
srv.Init(opts...)
cReg.Service().Init(opts...)
// Run server
if err := srv.Run(); err != nil {
ilogger.Logrus().Fatal(err)
if err := cReg.Service().Run(); err != nil {
logger.Fatal(err)
return
}
// Stop the handler
if err := routerHandler.Stop(); err != nil {
ilogger.Logrus().Fatal(err)
logger.Fatal(err)
return
}
// Stop the client/service auth plugin
if err := auth2.ClientAuthRegistry().Stop(); err != nil {
ilogger.Logrus().Fatal(err)
if err := cReg.Stop(); err != nil {
logger.Fatal(err)
return
}
}
func main() {
srv := micro.NewService(
service := micro.NewService(
micro.Server(httpServer.NewServer()),
)
routerAuthReg := auth2.RouterAuthRegistry()
cReg := components.New(service, "router", logruscomponent.New(), auth2.RouterAuthComponent())
auth2RouterReg := auth2.RouterAuthMustReg(cReg)
auth2RouterReg.Register(jwtRouter.New())
iService := micro.NewService()
iCReg := components.New(iService, "router", logruscomponent.New(), auth2.ClientAuthComponent(), router.New())
auth2ClientReg := auth2.ClientAuthMustReg(iCReg)
auth2ClientReg.Register(jwtClient.New())
var r *gin.Engine
flags := ilogger.MergeFlags(routerAuthReg.MergeFlags(auth2.ClientAuthRegistry().MergeFlags([]cli.Flag{
flags := components.FilterDuplicateFlags(iCReg.AppendFlags(cReg.AppendFlags([]cli.Flag{
// General
&cli.BoolFlag{
Name: "router_debugmode",
@ -122,76 +135,56 @@ func main() {
},
})))
routerHandler, err := handler.NewHandler()
if err != nil {
logger.Fatal(err)
}
opts := []micro.Option{
micro.Name(config.Name),
micro.Version(config.Version),
micro.Address(util.GetEnvDefault("MICRO_ROUTER_LISTEN", ":8080")),
micro.Flags(flags...),
micro.Action(func(c *cli.Context) error {
// Start the logger
if err := ilogger.Start(c); err != nil {
// Start the components
if err := cReg.Init(c); err != nil {
log.Fatal(err)
return err
}
// Initialize the Auth Plugin over RouterAuthRegistry
if err := routerAuthReg.Init(auth2.CliContext(c), auth2.Service(srv), auth2.Logrus(ilogger.Logrus())); err != nil {
ilogger.Logrus().Fatal(err)
return err
}
// Initialize GIN
if c.Bool("router_debugmode") {
gin.SetMode(gin.DebugMode)
} else {
gin.SetMode(gin.ReleaseMode)
}
r := gin.New()
r = gin.New()
r.ForwardedByClientIP = true
// Initalize the Handler
if err := routerHandler.Init(srv, r, routerAuthReg.Plugin(), c.Int("router_refresh"), c.String("router_ratelimiter_store_url")); err != nil {
ilogger.Logrus().Fatal(err)
return err
}
// Add middlewares to gin
r.Use(ginlogrus.Logger(ilogger.Logrus()), gin.Recovery())
r.Use(ginlogrus.Logger(logruscomponent.MustReg(cReg).Logger()), gin.Recovery())
r.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{"errors": []gin.H{{"id": "NOT_FOUND", "message": "page not found"}}})
})
// Register gin with micro
if err := micro.RegisterHandler(srv.Server(), r); err != nil {
ilogger.Logrus().Fatal(err)
if err := micro.RegisterHandler(service.Server(), r); err != nil {
logger.Fatal(err)
return err
}
return nil
}),
}
srv.Init(opts...)
service.Init(opts...)
go internalService(routerHandler)
go internalService(iCReg, r)
// Run server
if err := srv.Run(); err != nil {
ilogger.Logrus().Fatal(err)
if err := service.Run(); err != nil {
logger.Fatal(err)
return
}
// Stop the plugin in RouterAuthRegistry
if err := routerAuthReg.Stop(); err != nil {
ilogger.Logrus().Fatal(err)
}
// Stop the logger
if err := ilogger.Stop(); err != nil {
ilogger.Logrus().Fatal(err)
if err := cReg.Stop(); err != nil {
logger.Fatal(err)
return
}
}

@ -5,7 +5,4 @@ import (
_ "github.com/go-micro/plugins/v4/registry/nats"
_ "github.com/go-micro/plugins/v4/transport/grpc"
_ "github.com/go-micro/plugins/v4/transport/nats"
_ "jochum.dev/jo-micro/auth2/plugins/client/jwt"
_ "jochum.dev/jo-micro/auth2/plugins/router/jwt"
)

@ -32,6 +32,7 @@ require (
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
@ -47,15 +48,25 @@ require (
github.com/gobwas/ws v1.1.0 // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
github.com/golang-migrate/migrate/v4 v4.15.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgx-logrus v0.0.0-20220919124836-b099d8ce75da // indirect
github.com/jackc/pgx/v5 v5.0.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lib/pq v1.10.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/miekg/dns v1.1.50 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
@ -71,9 +82,16 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
github.com/uptrace/bun v1.1.8 // indirect
github.com/uptrace/bun/dialect/pgdialect v1.1.8 // indirect
github.com/uptrace/bun/extra/bundebug v1.1.8 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xanzy/ssh-agent v0.3.2 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/crypto v0.0.0-20220924013350-4ba4fb4dd9e7 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220923203811-8be639271d50 // indirect
@ -86,5 +104,7 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
jochum.dev/jo-micro/components v0.0.11 // indirect
jochum.dev/jo-micro/buncomponent v0.0.1 // indirect
jochum.dev/jo-micro/components v0.1.0 // indirect
jochum.dev/jo-micro/logruscomponent v0.0.2 // indirect
)

1724
go.sum

File diff suppressed because it is too large Load Diff

@ -31,7 +31,7 @@ func Must(ctx context.Context) *Handler {
return components.Must(ctx).Must(Name).(*Handler)
}
func MustReg(cReg *components.Components) *Handler {
func MustReg(cReg *components.Registry) *Handler {
return cReg.Must(Name).(*Handler)
}
@ -47,7 +47,7 @@ func (h *Handler) Initialized() bool {
return h.initialized
}
func (h *Handler) Init(r *components.Components, cli *cli.Context) error {
func (h *Handler) Init(r *components.Registry, cli *cli.Context) error {
if h.initialized {
return nil
}
@ -64,7 +64,7 @@ func (h *Handler) Stop() error {
return nil
}
func (h *Handler) Flags(r *components.Components) []cli.Flag {
func (h *Handler) Flags(r *components.Registry) []cli.Flag {
return []cli.Flag{
&cli.StringFlag{
Name: fmt.Sprintf("%s_router_basepath", strings.ToLower(r.FlagPrefix())),

@ -1,78 +0,0 @@
package ilogger
import (
"fmt"
"os"
"runtime"
microLogrus "github.com/go-micro/plugins/v4/logger/logrus"
microLogger "go-micro.dev/v4/logger"
"jochum.dev/jo-micro/router/internal/util"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
var myLogger *logrus.Logger = nil
var initialized = false
func MergeFlags(flags []cli.Flag) []cli.Flag {
return util.MergeFlag(flags, &cli.StringFlag{
Name: "router_loglevel",
Value: "info",
Usage: "Logrus log level default 'info', {panic,fatal,error,warn,info,debug,trace} available",
EnvVars: []string{"MICRO_ROUTER_LOG_LEVEL"},
})
}
func Intialized() bool {
return initialized
}
// caller returns string presentation of log caller which is formatted as
// `/path/to/file.go:line_number`. e.g. `/internal/app/api.go:25`
func caller() func(*runtime.Frame) (function string, file string) {
return func(f *runtime.Frame) (function string, file string) {
return "", fmt.Sprintf("%s:%d", f.File, f.Line)
}
}
func Start(cli *cli.Context) error {
if initialized {
return nil
}
lvl, err := logrus.ParseLevel(cli.String("router_loglevel"))
if err != nil {
return err
}
myLogger = logrus.New()
myLogger.Out = os.Stdout
myLogger.Level = lvl
myLogger.SetReportCaller(true)
myLogger.SetFormatter(&logrus.JSONFormatter{
CallerPrettyfier: caller(),
FieldMap: logrus.FieldMap{
logrus.FieldKeyFile: "caller",
},
})
microLogger.DefaultLogger = microLogrus.NewLogger(microLogrus.WithLogger(myLogger))
initialized = true
return nil
}
func Stop() error {
initialized = false
myLogger = nil
return nil
}
func Logrus() *logrus.Logger {
return myLogger
}
Loading…
Cancel
Save