diff --git a/api/gql_ev/resolver.go b/api/gql_ev/resolver.go deleted file mode 100644 index e44e8f3..0000000 --- a/api/gql_ev/resolver.go +++ /dev/null @@ -1,55 +0,0 @@ -package gql_ev - -import ( - "context" - "net/http" - "reflect" - - "github.com/sour-is/ev/app/msgbus" - "github.com/sour-is/ev/app/salty" - "github.com/sour-is/ev/internal/graph/generated" - "github.com/sour-is/ev/internal/logz" -) - -type Resolver struct { - msgbus.MsgbusResolver - salty.SaltyResolver -} - -func New(ctx context.Context, m msgbus.MsgbusResolver, s salty.SaltyResolver) (*Resolver, error) { - _, span := logz.Span(ctx) - defer span.End() - - r := &Resolver{m, s} - - return r, nil -} - -// Query returns generated.QueryResolver implementation. -func (r *Resolver) Query() generated.QueryResolver { return r } - -// Query returns generated.QueryResolver implementation. -func (r *Resolver) Mutation() generated.MutationResolver { return r } - -// Subscription returns generated.SubscriptionResolver implementation. -func (r *Resolver) Subscription() generated.SubscriptionResolver { return r } - -// ChainMiddlewares will check all embeded resolvers for a GetMiddleware func and add to handler. -func (r *Resolver) ChainMiddlewares(h http.Handler) http.Handler { - v := reflect.ValueOf(r) // Get reflected value of *Resolver - v = reflect.Indirect(v) // Get the pointed value (returns a zero value on nil) - n := v.NumField() // Get number of fields to iterate over. - for i := 0; i < n; i++ { - f := v.Field(i) - if !f.CanInterface() { // Skip non-interface types. - continue - } - if iface, ok := f.Interface().(interface { - GetMiddleware() func(http.Handler) http.Handler - }); ok { - h = iface.GetMiddleware()(h) // Append only items that fulfill the interface. - } - } - - return h -} diff --git a/app/msgbus/service.go b/app/msgbus/service.go index 852a186..c2e9aff 100644 --- a/app/msgbus/service.go +++ b/app/msgbus/service.go @@ -70,6 +70,9 @@ var upgrader = websocket.Upgrader{ }, } +func (s *service) RegisterHTTP(mux *http.ServeMux) { + mux.Handle("/inbox/", logz.Htrace(http.StripPrefix("/inbox/", s), "inbox")) +} func (s *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctx, span := logz.Span(ctx) diff --git a/app/salty/service.go b/app/salty/service.go index 197cb98..5b796d6 100644 --- a/app/salty/service.go +++ b/app/salty/service.go @@ -69,6 +69,9 @@ func (s *service) BaseURL() string { } return s.baseURL } +func(s *service) RegisterHTTP(mux *http.ServeMux) { + mux.Handle("/.well-known/salty/", logz.Htrace(s, "lookup")) +} func (s *service) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctx, span := logz.Span(ctx) diff --git a/internal/logz/metric.go b/internal/logz/metric.go index b1df359..e72b2cb 100644 --- a/internal/logz/metric.go +++ b/internal/logz/metric.go @@ -31,11 +31,9 @@ func Meter(ctx context.Context) metric.Meter { } return global.Meter("") } -func PromHTTP(ctx context.Context) http.Handler { - if t := fromContext[contextKey, *prometheus.Exporter](ctx, promHTTPKey); t != nil { - return t - } - return http.NotFoundHandler() +func NewHTTP(ctx context.Context) *httpHandle { + t := fromContext[contextKey, *prometheus.Exporter](ctx, promHTTPKey) + return &httpHandle{t} } func initMetrics(ctx context.Context, name string) (context.Context, func() error) { @@ -88,3 +86,14 @@ func initMetrics(ctx context.Context, name string) (context.Context, func() erro return cont.Stop(ctx) } } + +type httpHandle struct { + exp *prometheus.Exporter +} + +func (h *httpHandle) RegisterHTTP(mux *http.ServeMux) { + if h.exp == nil { + return + } + mux.Handle("/metrics", h.exp) +} diff --git a/main.go b/main.go index e9dab38..f598e27 100644 --- a/main.go +++ b/main.go @@ -9,16 +9,12 @@ import ( "path" "time" - "github.com/99designs/gqlgen/graphql/handler" - "github.com/ravilushqa/otelgqlgen" "github.com/rs/cors" "golang.org/x/sync/errgroup" - "github.com/sour-is/ev/api/gql_ev" + "github.com/sour-is/ev/app/gql" "github.com/sour-is/ev/app/msgbus" - "github.com/sour-is/ev/app/playground" "github.com/sour-is/ev/app/salty" - "github.com/sour-is/ev/internal/graph/generated" "github.com/sour-is/ev/internal/logz" "github.com/sour-is/ev/pkg/es" diskstore "github.com/sour-is/ev/pkg/es/driver/disk-store" @@ -38,12 +34,6 @@ func main() { ctx, stop := logz.Init(ctx, AppName) defer stop() - Mup, err := logz.Meter(ctx).SyncInt64().UpDownCounter("up") - if err != nil { - log.Fatal(err) - } - Mup.Add(ctx, 1) - if err := run(ctx); err != nil && err != http.ErrServerClosed { log.Fatal(err) } @@ -67,41 +57,35 @@ func run(ctx context.Context) error { Addr: env("EV_HTTP", ":8080"), } - saltySVC, err := salty.New(ctx, es, path.Join(env("EV_BASE_URL", "http://localhost" + s.Addr), "inbox")) + salty, err := salty.New(ctx, es, path.Join(env("EV_BASE_URL", "http://localhost"+s.Addr), "inbox")) if err != nil { span.RecordError(err) return err } - msgbusSVC, err := msgbus.New(ctx, es) + msgbus, err := msgbus.New(ctx, es) if err != nil { span.RecordError(err) return err } - res, err := gql_ev.New(ctx, msgbusSVC, saltySVC) + gql, err := gql.New(ctx, msgbus, salty) if err != nil { span.RecordError(err) return err } - gql := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: res})) - gql.Use(otelgqlgen.Middleware()) - - mux := http.NewServeMux() - - mux.Handle("/", playground.Handler("GraphQL playground", "/gql")) - mux.Handle("/gql", logz.Htrace(res.ChainMiddlewares(gql), "gql")) - mux.Handle("/metrics", logz.PromHTTP(ctx)) - - mux.Handle("/inbox/", logz.Htrace(http.StripPrefix("/inbox/", msgbusSVC), "inbox")) - mux.Handle("/.well-known/salty/", logz.Htrace(saltySVC, "lookup")) - - s.Handler = cors.AllowAll().Handler(mux) + s.Handler = httpMux(logz.NewHTTP(ctx), msgbus, salty, gql) log.Print("Listen on ", s.Addr) span.AddEvent("begin listen and serve") + Mup, err := logz.Meter(ctx).SyncInt64().UpDownCounter("up") + if err != nil { + return err + } + Mup.Add(ctx, 1) + g.Go(s.ListenAndServe) g.Go(func() error { @@ -113,7 +97,11 @@ func run(ctx context.Context) error { span.End() } - return g.Wait() + + if err := g.Wait(); err != nil && err != http.ErrServerClosed { + return err + } + return nil } func env(name, defaultValue string) string { if v := os.Getenv(name); v != "" { @@ -122,3 +110,10 @@ func env(name, defaultValue string) string { } return defaultValue } +func httpMux(fns ...interface{ RegisterHTTP(*http.ServeMux) }) http.Handler { + mux := http.NewServeMux() + for _, fn := range fns { + fn.RegisterHTTP(mux) + } + return cors.AllowAll().Handler(mux) +}