implement grpc gateway and addl handler support
This commit is contained in:
@ -2,20 +2,18 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/grpc/opts"
|
||||
)
|
||||
|
||||
const API_PATH = "/api" // TODO: Make Configurable
|
||||
|
||||
// TODO: Add GetClientConn method to appGRPCServer that supports TLS, auth, etc..
|
||||
// Will probably have to convert server opts to client opts
|
||||
func (a *appGRPCServer) registerServiceGatewayHandlers(ctx context.Context, service *opts.GRPCService) {
|
||||
if len(service.GwRegistrationFuncs) < 1 {
|
||||
return
|
||||
@ -29,15 +27,30 @@ func (a *appGRPCServer) registerServiceGatewayHandlers(ctx context.Context, serv
|
||||
))
|
||||
defer span.End()
|
||||
|
||||
// TODO: move to GetClientConn method which doesn't exist yet
|
||||
clientConn, _ := grpc.NewClient(a.opts.Listen)
|
||||
clientConn := a.GetClientConn(ctx)
|
||||
|
||||
for _, registerGW := range service.GwRegistrationFuncs {
|
||||
registerGW(ctx, a.gatewayMux, clientConn)
|
||||
}
|
||||
}
|
||||
|
||||
// Add our gateway mux to an existing http.ServeMux
|
||||
func (a *appGRPCServer) mergeGatewayMuxWithHTTPMux(mux *http.ServeMux) {
|
||||
mux.Handle(API_PATH, http.StripPrefix(API_PATH, a.gatewayMux))
|
||||
func (a *appGRPCServer) GetClientConn(ctx context.Context) *grpc.ClientConn {
|
||||
span := trace.SpanFromContext(ctx)
|
||||
|
||||
host, port, err := net.SplitHostPort(a.opts.Listen)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if host == "" || host == "0.0.0.0" {
|
||||
host = "localhost"
|
||||
}
|
||||
|
||||
clientConn, err := grpc.NewClient(fmt.Sprintf("%s:%s", host, port), a.opts.GRPCDialOpts...)
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
}
|
||||
|
||||
return clientConn
|
||||
}
|
||||
|
@ -29,10 +29,6 @@ type appGRPCServer struct {
|
||||
doneChan chan error
|
||||
}
|
||||
|
||||
func (g *appGRPCServer) GetMux() *runtime.ServeMux {
|
||||
return g.gatewayMux
|
||||
}
|
||||
|
||||
// Returns a shutdown func, a channel indicating done / error,
|
||||
// and an up-front error if server fails to start
|
||||
func InitGRPCServer(ctx context.Context, opts *opts.GRPCOpts) (
|
||||
|
@ -19,7 +19,9 @@ type AppGRPC struct {
|
||||
UnaryInterceptors []grpc.UnaryServerInterceptor
|
||||
StreamInterceptors []grpc.StreamServerInterceptor
|
||||
GRPCOpts []grpc.ServerOption
|
||||
GRPCDialOpts []grpc.DialOption // Map ServerOptions to DialOpts for GRPC Gateway support
|
||||
GRPCDone <-chan error
|
||||
gatewayMux *runtime.ServeMux
|
||||
}
|
||||
|
||||
type GRPCService struct {
|
||||
@ -28,3 +30,11 @@ type GRPCService struct {
|
||||
Service any // Implementation of GRPCService.Type (ptr)
|
||||
GwRegistrationFuncs []func(context.Context, *runtime.ServeMux, *grpc.ClientConn) error // Gateway regustration handler funcs
|
||||
}
|
||||
|
||||
func (a *AppGRPC) SetGatewayMux(mux *runtime.ServeMux) {
|
||||
a.gatewayMux = mux
|
||||
}
|
||||
|
||||
func (a *AppGRPC) GetGatewayMux() *runtime.ServeMux {
|
||||
return a.gatewayMux
|
||||
}
|
||||
|
@ -50,6 +50,15 @@ func (a *appGRPCServer) prepGRPCServer(spanCtx context.Context) error {
|
||||
a.registerGRPCServices(ctx)
|
||||
span.SetAttributes(attribute.Int("grpc.server.grpcservices", len(a.opts.Services)))
|
||||
|
||||
// If a grpc-gateway mux was created, store it in opts
|
||||
// so it can be used by AppHTTP
|
||||
if a.gatewayMux != nil {
|
||||
a.opts.SetGatewayMux(a.gatewayMux)
|
||||
span.SetAttributes(attribute.Bool("grpc.server.grpcgateway.enabled", true))
|
||||
} else {
|
||||
span.SetAttributes(attribute.Bool("grpc.server.grpcgateway.enabled", false))
|
||||
}
|
||||
|
||||
// Enable reflection if desired
|
||||
if a.opts.EnableReflection {
|
||||
reflection.Register(a.server)
|
||||
|
Reference in New Issue
Block a user