support runtime.ServeMux opts for grpc-gateway
This commit is contained in:
parent
1e481627e3
commit
f201ac1fca
10
app.go
10
app.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/app"
|
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/app"
|
||||||
grpcopts "gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/grpc/opts"
|
grpcopts "gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/grpc/opts"
|
||||||
@ -38,11 +39,13 @@ func prepareApp(ctx context.Context, aw *ambient.AmbientWeather) *app.App {
|
|||||||
CustomListener: ambienthttp.NewAWNMutatingListener(ctx,
|
CustomListener: ambienthttp.NewAWNMutatingListener(ctx,
|
||||||
aw.Config.HTTP.Listen), // Necessary to fix certain bad AWN firmware
|
aw.Config.HTTP.Listen), // Necessary to fix certain bad AWN firmware
|
||||||
|
|
||||||
// Health check funcs
|
|
||||||
HealthChecks: []httpopts.HealthCheckFunc{
|
HealthChecks: []httpopts.HealthCheckFunc{
|
||||||
// TODO: Implement
|
// Check recorder health
|
||||||
|
// Only redis implements this
|
||||||
func(ctx context.Context) error {
|
func(ctx context.Context) error {
|
||||||
return nil
|
var errs error
|
||||||
|
errs = errors.Join(errs, aw.GetRecorder().Ping(ctx))
|
||||||
|
return errs
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -52,6 +55,7 @@ func prepareApp(ctx context.Context, aw *ambient.AmbientWeather) *app.App {
|
|||||||
GRPCDialOpts: []grpc.DialOption{
|
GRPCDialOpts: []grpc.DialOption{
|
||||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||||
},
|
},
|
||||||
|
GRPCGatewayOpts: aw.GetGatewayOpts(),
|
||||||
Services: []*grpcopts.GRPCService{
|
Services: []*grpcopts.GRPCService{
|
||||||
{
|
{
|
||||||
Name: "Weather Service",
|
Name: "Weather Service",
|
||||||
|
6
go.mod
6
go.mod
@ -3,7 +3,7 @@ module gitea.libretechconsulting.com/rmcguire/ambient-local-exporter
|
|||||||
go 1.24.1
|
go 1.24.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitea.libretechconsulting.com/rmcguire/go-app v0.8.1
|
gitea.libretechconsulting.com/rmcguire/go-app v0.9.0
|
||||||
github.com/go-resty/resty/v2 v2.16.5
|
github.com/go-resty/resty/v2 v2.16.5
|
||||||
github.com/gorilla/schema v1.4.1
|
github.com/gorilla/schema v1.4.1
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3
|
||||||
@ -13,7 +13,7 @@ require (
|
|||||||
go.opentelemetry.io/otel/metric v1.35.0
|
go.opentelemetry.io/otel/metric v1.35.0
|
||||||
go.opentelemetry.io/otel/trace v1.35.0
|
go.opentelemetry.io/otel/trace v1.35.0
|
||||||
golang.org/x/sys v0.31.0
|
golang.org/x/sys v0.31.0
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4
|
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463
|
||||||
google.golang.org/grpc v1.71.0
|
google.golang.org/grpc v1.71.0
|
||||||
google.golang.org/protobuf v1.36.6
|
google.golang.org/protobuf v1.36.6
|
||||||
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e
|
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e
|
||||||
@ -57,7 +57,7 @@ require (
|
|||||||
golang.org/x/net v0.37.0 // indirect
|
golang.org/x/net v0.37.0 // indirect
|
||||||
golang.org/x/text v0.23.0 // indirect
|
golang.org/x/text v0.23.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
google.golang.org/genproto v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
|
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
6
go.sum
6
go.sum
@ -6,6 +6,8 @@ gitea.libretechconsulting.com/rmcguire/go-app v0.8.0 h1:PC8vlpr8tLoRwIHsq5nvOYzz
|
|||||||
gitea.libretechconsulting.com/rmcguire/go-app v0.8.0/go.mod h1:W6YHFSGf4nJrgs9DqEaw+3J6ufIARsr1zpOs/V6gRTQ=
|
gitea.libretechconsulting.com/rmcguire/go-app v0.8.0/go.mod h1:W6YHFSGf4nJrgs9DqEaw+3J6ufIARsr1zpOs/V6gRTQ=
|
||||||
gitea.libretechconsulting.com/rmcguire/go-app v0.8.1 h1:pnmFJnY77dsh84zvVcHqFuQgkxy3hjCQ8tFRGv/aJOw=
|
gitea.libretechconsulting.com/rmcguire/go-app v0.8.1 h1:pnmFJnY77dsh84zvVcHqFuQgkxy3hjCQ8tFRGv/aJOw=
|
||||||
gitea.libretechconsulting.com/rmcguire/go-app v0.8.1/go.mod h1:W6YHFSGf4nJrgs9DqEaw+3J6ufIARsr1zpOs/V6gRTQ=
|
gitea.libretechconsulting.com/rmcguire/go-app v0.8.1/go.mod h1:W6YHFSGf4nJrgs9DqEaw+3J6ufIARsr1zpOs/V6gRTQ=
|
||||||
|
gitea.libretechconsulting.com/rmcguire/go-app v0.9.0 h1:ZOBdVk2EehGCX6K3pdT5Dy07bMiUR7VTifE+n0ODfak=
|
||||||
|
gitea.libretechconsulting.com/rmcguire/go-app v0.9.0/go.mod h1:W6YHFSGf4nJrgs9DqEaw+3J6ufIARsr1zpOs/V6gRTQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
@ -204,8 +206,12 @@ google.golang.org/genproto v0.0.0-20250313205543-e70fdf4c4cb4 h1:kCjWYliqPA8g5z8
|
|||||||
google.golang.org/genproto v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:SqIx1NV9hcvqdLHo7uNZDS5lrUJybQ3evo3+z/WBfA0=
|
google.golang.org/genproto v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:SqIx1NV9hcvqdLHo7uNZDS5lrUJybQ3evo3+z/WBfA0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 h1:IFnXJq3UPB3oBREOodn1v1aGQeZYQclEmvWRMN0PSsY=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 h1:IFnXJq3UPB3oBREOodn1v1aGQeZYQclEmvWRMN0PSsY=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:c8q6Z6OCqnfVIqUFJkCzKcrj8eCvUrz+K4KRzSTuANg=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:c8q6Z6OCqnfVIqUFJkCzKcrj8eCvUrz+K4KRzSTuANg=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
@ -318,6 +318,18 @@ func (aw *AmbientWeather) enrichStation(update *weather.WeatherUpdate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (aw *AmbientWeather) GetLogger() *zerolog.Logger {
|
||||||
|
aw.RLock()
|
||||||
|
defer aw.RUnlock()
|
||||||
|
return aw.l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aw *AmbientWeather) GetCtx() context.Context {
|
||||||
|
aw.RLock()
|
||||||
|
defer aw.RUnlock()
|
||||||
|
return aw.appCtx
|
||||||
|
}
|
||||||
|
|
||||||
func (aw *AmbientWeather) GetRecorder() *recorder.WeatherRecorder {
|
func (aw *AmbientWeather) GetRecorder() *recorder.WeatherRecorder {
|
||||||
aw.RLock()
|
aw.RLock()
|
||||||
defer aw.RUnlock()
|
defer aw.RUnlock()
|
||||||
|
33
pkg/ambient/app.go
Normal file
33
pkg/ambient/app.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package ambient
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (aw *AmbientWeather) GetGatewayOpts() []runtime.ServeMuxOption {
|
||||||
|
return []runtime.ServeMuxOption{
|
||||||
|
runtime.WithMiddlewares(func(hf runtime.HandlerFunc) runtime.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
||||||
|
aw.GetLogger().Trace().
|
||||||
|
Any("pathParams", pathParams).
|
||||||
|
Msg("inbound request called")
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
runtime.WithRoutingErrorHandler(
|
||||||
|
func(
|
||||||
|
ctx context.Context, mux *runtime.ServeMux, mshl runtime.Marshaler,
|
||||||
|
w http.ResponseWriter, r *http.Request, code int,
|
||||||
|
) {
|
||||||
|
aw.GetLogger().Trace().
|
||||||
|
Int("code", code).
|
||||||
|
Str("pattern", r.Pattern).
|
||||||
|
Msg("requesting grpc-gateway route")
|
||||||
|
|
||||||
|
// Pass back to default
|
||||||
|
runtime.DefaultRoutingErrorHandler(ctx, mux, mshl, w, r, code)
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,10 @@ type Opts struct {
|
|||||||
KeepLast int
|
KeepLast int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *WeatherRecorder) Ping(ctx context.Context) error {
|
||||||
|
return r.recorder.Ping(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func MustNewWeatherRecorder(opts *Opts) *WeatherRecorder {
|
func MustNewWeatherRecorder(opts *Opts) *WeatherRecorder {
|
||||||
if opts.KeepLast < 1 {
|
if opts.KeepLast < 1 {
|
||||||
opts.KeepLast = 1
|
opts.KeepLast = 1
|
||||||
|
@ -25,6 +25,11 @@ type MemoryRecorder struct {
|
|||||||
*sync.RWMutex
|
*sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No meaningful health check to do here
|
||||||
|
func (r *MemoryRecorder) Ping(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *MemoryRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts) {
|
func (r *MemoryRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts) {
|
||||||
if opts.RetainLast < 1 {
|
if opts.RetainLast < 1 {
|
||||||
opts.RetainLast = DEF_RETAIN_LAST
|
opts.RetainLast = DEF_RETAIN_LAST
|
||||||
|
@ -20,4 +20,6 @@ func (n *NoopRecorder) Get(context.Context, *pb.GetWeatherRequest) ([]*weather.W
|
|||||||
|
|
||||||
func (n *NoopRecorder) Count(context.Context) int { return 0 }
|
func (n *NoopRecorder) Count(context.Context) int { return 0 }
|
||||||
|
|
||||||
|
func (n *NoopRecorder) Ping(context.Context) error { return nil }
|
||||||
|
|
||||||
func (r *NoopRecorder) Name() string { return "no-op recorder" }
|
func (r *NoopRecorder) Name() string { return "no-op recorder" }
|
||||||
|
@ -19,5 +19,6 @@ type Recorder interface {
|
|||||||
Set(context.Context, *weather.WeatherUpdate) error
|
Set(context.Context, *weather.WeatherUpdate) error
|
||||||
Get(context.Context, *pb.GetWeatherRequest) ([]*weather.WeatherUpdate, error)
|
Get(context.Context, *pb.GetWeatherRequest) ([]*weather.WeatherUpdate, error)
|
||||||
Count(context.Context) int // Best Effort
|
Count(context.Context) int // Best Effort
|
||||||
|
Ping(context.Context) error
|
||||||
Name() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,11 @@ type RedisRecorder struct {
|
|||||||
*sync.RWMutex
|
*sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *RedisRecorder) Ping(ctx context.Context) error {
|
||||||
|
_, err := r.redis.Ping(ctx).Result()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (r *RedisRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts) {
|
func (r *RedisRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts) {
|
||||||
if opts.AppConfig.RecorderConfig.RedisConfig == nil {
|
if opts.AppConfig.RecorderConfig.RedisConfig == nil {
|
||||||
panic("refusing to init redis recorder with no redisConfig")
|
panic("refusing to init redis recorder with no redisConfig")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user