From d75308b1fe9caab44e470bd5d15b242dcb832969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Jochum?= Date: Tue, 30 Aug 2022 02:57:47 +0200 Subject: [PATCH] Add versioning, serve routes over an internal service --- Taskfile.yml | 7 ++- cmd/microrouterd/main.go | 71 ++++++++++++++++++----- config/config.go | 11 ++-- config/load.go | 1 + docker/go-micro-router/Dockerfile | 4 +- handler/handler.go | 21 +++---- proto/routerclientpb/routerclientpb.proto | 2 +- proto/routerserverpb/routerserverpb.proto | 20 +++++++ 8 files changed, 102 insertions(+), 35 deletions(-) create mode 100644 proto/routerserverpb/routerserverpb.proto diff --git a/Taskfile.yml b/Taskfile.yml index 12e8e0f..1cf678d 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -4,7 +4,7 @@ vars: GIT_TAG: sh: git tag --points-at HEAD GIT_COMMIT: - sh: git rev-parse HEAD + sh: git rev-parse --short HEAD GIT_DIRTY: sh: git status -s VERSION: @@ -54,12 +54,15 @@ tasks: - task: builder vars: CLI_ARGS: /bin/sh -c 'cd ./proto/routerclientpb; protoc --proto_path=/go/bin:. --micro_out=paths=source_relative:. --go_out=paths=source_relative:. routerclientpb.proto' + - task: builder + vars: + CLI_ARGS: /bin/sh -c 'cd ./proto/routerserverpb; protoc --proto_path=/go/bin:. --micro_out=paths=source_relative:. --go_out=paths=source_relative:. routerserverpb.proto' build:podman: deps: - protoc cmds: - - podman build -v "$PWD:/code:rw" -v "{{.VOLUME_PATH}}:/go:rw" --build-arg CACHEBUST={{.DATE}} --build-arg=VERSION={{.VERSION}} -t docker.io/pcdummy/go-micro-router:latest -f ./docker/go-micro-router/Dockerfile . + - podman build -v "$PWD:/code:rw" -v "{{.VOLUME_PATH}}:/go:rw" --build-arg CACHEBUST={{.DATE}} --build-arg VERSION={{.VERSION}} -t docker.io/pcdummy/go-micro-router:latest -f ./docker/go-micro-router/Dockerfile . vars: DATE: sh: date +%s diff --git a/cmd/microrouterd/main.go b/cmd/microrouterd/main.go index a7c5d70..e34e2b3 100644 --- a/cmd/microrouterd/main.go +++ b/cmd/microrouterd/main.go @@ -1,17 +1,67 @@ package main import ( + "net/http" + "github.com/urfave/cli/v2" "go-micro.dev/v4" "go-micro.dev/v4/logger" "github.com/gin-gonic/gin" httpServer "github.com/go-micro/plugins/v4/server/http" + "github.com/go-micro/router" "github.com/go-micro/router/config" "github.com/go-micro/router/handler" + "github.com/go-micro/router/proto/routerclientpb" + "github.com/go-micro/router/proto/routerserverpb" ) +func internalService(engine *gin.Engine) { + srv := micro.NewService() + + routerHandler, err := handler.NewHandler(srv, engine) + if err != nil { + logger.Fatal(err) + } + + opts := []micro.Option{ + micro.Name(config.Name + "-internal"), + micro.Version(config.Version), + micro.Action(func(c *cli.Context) error { + if err := routerHandler.Start(); err != nil { + logger.Fatal(err) + } + + routerserverpb.RegisterRouterServerServiceHandler(srv.Server(), routerHandler) + + routerHandler := router.NewHandler( + config.GetServerConfig().RouterURI, + router.NewRoute( + router.RouteMethod(http.MethodGet), + router.RoutePath("/routes"), + router.RouteEndpoint(routerserverpb.RouterServerService.Routes), + ), + ) + routerclientpb.RegisterRouterClientServiceHandler(srv.Server(), routerHandler) + + return nil + }), + } + + srv.Init(opts...) + + // Run server + if err := srv.Run(); err != nil { + logger.Fatal(err) + } + + if err := routerHandler.Stop(); err != nil { + logger.Fatal(err) + } + +} + func main() { srv := micro.NewService( micro.Server(httpServer.NewServer()), @@ -25,24 +75,15 @@ func main() { gin.SetMode(gin.ReleaseMode) } - router := gin.New() - routerHandler, err := handler.NewHandler(srv, router) - if err != nil { - logger.Fatal(err) - } - + r := gin.New() opts := []micro.Option{ micro.Name(config.Name), micro.Version(config.Version), micro.Address(config.GetServerConfig().Address), micro.Action(func(c *cli.Context) error { - router.Use(gin.Logger(), gin.Recovery()) - - if err := micro.RegisterHandler(srv.Server(), router); err != nil { - logger.Fatal(err) - } + r.Use(gin.Logger(), gin.Recovery()) - if err := routerHandler.Start(); err != nil { + if err := micro.RegisterHandler(srv.Server(), r); err != nil { logger.Fatal(err) } @@ -51,12 +92,10 @@ func main() { } srv.Init(opts...) + go internalService(r) + // Run server if err := srv.Run(); err != nil { logger.Fatal(err) } - - if err := routerHandler.Stop(); err != nil { - logger.Fatal(err) - } } diff --git a/config/config.go b/config/config.go index f0a693c..af6d9a7 100644 --- a/config/config.go +++ b/config/config.go @@ -1,10 +1,12 @@ package config +var ( + Version = "0.0.1-dev0" +) + const ( - Name = "go.micro.router" - Version = "0.0.1-dev0" - RouterURI = "router" - PkgPath = "github.com/go-micro/router" + Name = "go.micro.router" + PkgPath = "github.com/go-micro/router" ) const ( @@ -19,6 +21,7 @@ type Config struct { type ServerConfig struct { Env string Address string + RouterURI string RefreshSeconds int } diff --git a/config/load.go b/config/load.go index 3ddb44d..d90b91a 100644 --- a/config/load.go +++ b/config/load.go @@ -21,6 +21,7 @@ var _cfg *Config = &Config{ Server: ServerConfig{ Env: EnvProd, Address: ":8080", + RouterURI: "router", RefreshSeconds: 10, }, } diff --git a/docker/go-micro-router/Dockerfile b/docker/go-micro-router/Dockerfile index 8346ca4..091cb17 100644 --- a/docker/go-micro-router/Dockerfile +++ b/docker/go-micro-router/Dockerfile @@ -12,8 +12,8 @@ WORKDIR /code ENV GOPATH="/go" ARG CACHEBUST=1 -ARG VERSION=0.0.1-dev0 -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -installsuffix cgo -ldflags='-w -s -X "github.com/go-micro/router/config.Version='$VERSION'"' -o /usr/local/bin/microrouterd github.com/go-micro/router/cmd/microrouterd +ARG VERSION +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -installsuffix cgo -ldflags="-w -s -X 'github.com/go-micro/router/config.Version=$VERSION'" -o /usr/local/bin/microrouterd github.com/go-micro/router/cmd/microrouterd # STEP 2 build a small image # start from busybox diff --git a/handler/handler.go b/handler/handler.go index e49da24..8c4b276 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -12,6 +12,7 @@ import ( "github.com/gin-gonic/gin" "github.com/go-micro/router/config" "github.com/go-micro/router/proto/routerclientpb" + "github.com/go-micro/router/proto/routerserverpb" "github.com/go-micro/router/util" "go-micro.dev/v4" "go-micro.dev/v4/client" @@ -42,20 +43,20 @@ func NewHandler(service micro.Service, engine *gin.Engine) (*Handler, error) { func (h *Handler) Start() error { globalGroup := h.engine.Group("") - globalGroup.Handle("GET", fmt.Sprintf("/%s/routes", config.RouterURI), h.ginRoutes) // Refresh routes for the proxy every 10 seconds go func() { ctx := context.Background() for { - services, err := util.FindByEndpoint(h.service, "RouterClient.Routes") + services, err := util.FindByEndpoint(h.service, "RouterClientService.Routes") if err != nil { logger.Error(err) continue } for _, s := range services { + logger.Debug("Found service ", s.Name) client := routerclientpb.NewRouterClientService(s.Name, h.service.Client()) resp, err := client.Routes(ctx, &emptypb.Empty{}) if err != nil { @@ -67,6 +68,7 @@ func (h *Handler) Start() error { serviceGroup := globalGroup.Group(fmt.Sprintf("/%s", resp.GetRouterURI())) for _, route := range resp.Routes { + logger.Debug("Found endpoint ", route.Endpoint) var g *gin.RouterGroup = nil if route.IsGlobal { @@ -189,16 +191,15 @@ func (h *Handler) proxy(serviceName string, route *routerclientpb.RoutesReply_Ro } } -func (h *Handler) ginRoutes(c *gin.Context) { +func (h *Handler) Routes(ctx context.Context, in *emptypb.Empty, out *routerserverpb.RoutesReply) error { ginRoutes := h.engine.Routes() - rRoutes := []JSONRoute{} + for _, route := range ginRoutes { - rRoutes = append(rRoutes, JSONRoute{Method: route.Method, Path: route.Path}) + out.Routes = append(out.Routes, &routerserverpb.RoutesReply_Route{ + Method: route.Method, + Path: route.Path, + }) } - c.JSON(http.StatusOK, gin.H{ - "status": 200, - "message": "Dumping the routes", - "data": rRoutes, - }) + return nil } diff --git a/proto/routerclientpb/routerclientpb.proto b/proto/routerclientpb/routerclientpb.proto index 7a61580..f23dbe2 100644 --- a/proto/routerclientpb/routerclientpb.proto +++ b/proto/routerclientpb/routerclientpb.proto @@ -6,7 +6,7 @@ option go_package = "github.com/go-micro/router/proto/routerclientpb;routerclien import "google/protobuf/empty.proto"; -service RouterClient { +service RouterClientService { rpc Routes (google.protobuf.Empty) returns (RoutesReply) {} } diff --git a/proto/routerserverpb/routerserverpb.proto b/proto/routerserverpb/routerserverpb.proto new file mode 100644 index 0000000..9685d17 --- /dev/null +++ b/proto/routerserverpb/routerserverpb.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package routerserverpb; + +option go_package = "github.com/go-micro/router/proto/routerserverpb;routerserverpb"; + +import "google/protobuf/empty.proto"; + +service RouterServerService { + rpc Routes (google.protobuf.Empty) returns (RoutesReply) {} +} + +message RoutesReply { + message Route { + string method = 1; + string path = 2; + } + + repeated Route routes = 1; +} \ No newline at end of file