Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
b44b6a331c | |||
adfedc9239 | |||
89f016ed9d | |||
7f60a59d42 |
1
TODO.md
1
TODO.md
@ -1,5 +1,6 @@
|
||||
# TODO
|
||||
|
||||
- [ ] Test and troubleshoot GRPC Gateway supprot
|
||||
- [ ] Finish implementing GRPC service support
|
||||
- [ ] Expand config test case to cover GRPC config
|
||||
- [ ] Expand tracing
|
||||
|
@ -9,9 +9,6 @@ import (
|
||||
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/config"
|
||||
)
|
||||
|
||||
// TODO: Make Configurable
|
||||
const GRPC_GW_API_PATH = "/api"
|
||||
|
||||
func (a *App) Done() <-chan any {
|
||||
return a.appDone
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ func (a *App) runGRPC(ctx context.Context) {
|
||||
}
|
||||
|
||||
a.HTTP.Handlers = append(a.HTTP.Handlers, opts.HTTPHandler{
|
||||
Prefix: GRPC_GW_API_PATH,
|
||||
Prefix: a.cfg.GRPC.GRPCGatewayPath,
|
||||
StripPrefix: true,
|
||||
Handler: a.GRPC.GetGatewayMux(),
|
||||
})
|
||||
|
@ -15,4 +15,6 @@ type GRPCConfig struct {
|
||||
LogRequests bool `yaml:"logRequests" env:"APP_GRPC_LOG_REQUESTS" json:"logRequests,omitempty"`
|
||||
EnableReflection bool `yaml:"enableReflection" env:"APP_GRPC_ENABLE_REFLECTION" json:"enableReflection,omitempty"`
|
||||
EnableInstrumentation bool `yaml:"enableInstrumentation" env:"APP_GRPC_ENABLE_INSTRUMENTATION" json:"enableInstrumentation,omitempty"` // requires OTEL
|
||||
EnableGRPCGateway bool `yaml:"enableGRPCGateway" json:"enableGRPCGateway,omitempty" env:"APP_GRPC_ENABLE_GATEWAY" default:"true"`
|
||||
GRPCGatewayPath string `yaml:"grpcGatewayPath" json:"grpcGatewayPath,omitempty" env:"APP_GRPC_GATEWAY_PATH" default:"/grpc-api"`
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
@ -18,7 +18,7 @@ func (a *appGRPCServer) registerServiceGatewayHandlers(ctx context.Context, serv
|
||||
if len(service.GwRegistrationFuncs) < 1 {
|
||||
return
|
||||
} else if a.gatewayMux == nil {
|
||||
a.gatewayMux = runtime.NewServeMux()
|
||||
a.gatewayMux = runtime.NewServeMux(a.opts.GRPCGatewayOpts...)
|
||||
}
|
||||
|
||||
ctx, span := a.tracer.Start(ctx, "appgrpc.init.prepare.service.gwHandlers", trace.WithAttributes(
|
||||
@ -50,6 +50,7 @@ func (a *appGRPCServer) GetClientConn(ctx context.Context) *grpc.ClientConn {
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return clientConn
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/rs/zerolog"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
|
@ -3,7 +3,7 @@ package opts
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/config"
|
||||
@ -19,18 +19,21 @@ type AppGRPC struct {
|
||||
UnaryInterceptors []grpc.UnaryServerInterceptor
|
||||
StreamInterceptors []grpc.StreamServerInterceptor
|
||||
GRPCOpts []grpc.ServerOption
|
||||
GRPCDialOpts []grpc.DialOption // Map ServerOptions to DialOpts for GRPC Gateway support
|
||||
GRPCDialOpts []grpc.DialOption // Map ServerOptions to DialOpts for GRPC Gateway support
|
||||
GRPCGatewayOpts []runtime.ServeMuxOption // Configure grpc-gateway ServeMux
|
||||
GRPCDone <-chan error
|
||||
gatewayMux *runtime.ServeMux
|
||||
}
|
||||
|
||||
type GRPCService struct {
|
||||
Name string // Descriptive name of service
|
||||
Type *grpc.ServiceDesc // Type (from protoc generated code)
|
||||
Service any // Implementation of GRPCService.Type (ptr)
|
||||
GwRegistrationFuncs []func(context.Context, *runtime.ServeMux, *grpc.ClientConn) error // Gateway regustration handler funcs
|
||||
Name string // Descriptive name of service
|
||||
Type *grpc.ServiceDesc // Type (from protoc generated code)
|
||||
Service any // Implementation of GRPCService.Type (ptr)
|
||||
GwRegistrationFuncs []GwRegistrationFunc // Gateway regustration handler funcs
|
||||
}
|
||||
|
||||
type GwRegistrationFunc func(context.Context, *runtime.ServeMux, *grpc.ClientConn) error
|
||||
|
||||
func (a *AppGRPC) SetGatewayMux(mux *runtime.ServeMux) {
|
||||
a.gatewayMux = mux
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"
|
||||
)
|
||||
|
||||
// TODO: Implement
|
||||
func (a *appGRPCServer) runGRPCServer(spanCtx context.Context) error {
|
||||
_, span := a.tracer.Start(spanCtx, "appgrpc.init.start")
|
||||
defer span.End()
|
||||
|
@ -19,7 +19,9 @@ func (a *appGRPCServer) registerGRPCServices(ctx context.Context) {
|
||||
|
||||
for _, service := range a.opts.Services {
|
||||
a.registerGRPCService(ctx, service)
|
||||
a.registerServiceGatewayHandlers(ctx, service)
|
||||
if a.opts.EnableGRPCGateway {
|
||||
a.registerServiceGatewayHandlers(ctx, service)
|
||||
}
|
||||
}
|
||||
|
||||
span.SetStatus(codes.Ok, "")
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
@ -60,6 +61,13 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server {
|
||||
// Inject extra handlers if given
|
||||
// Used for grpc-gateway runtime.ServeMux handlers
|
||||
for _, h := range opts.Handlers {
|
||||
// prefix must end in / to route sub-paths
|
||||
if !strings.HasSuffix(h.Prefix, "/") {
|
||||
h.Prefix = h.Prefix + "/"
|
||||
}
|
||||
|
||||
// if enabled, the path prefix is stripped before
|
||||
// requests are sent to the handler
|
||||
if h.StripPrefix {
|
||||
h.Handler = http.StripPrefix(h.Prefix, h.Handler)
|
||||
}
|
||||
|
Reference in New Issue
Block a user