Merge remote-tracking branch 'rem/v3' into v3

This commit is contained in:
Aleksandr Tolstikhin
2024-12-11 00:34:37 +07:00
23 changed files with 1470 additions and 23 deletions

View File

@@ -2,11 +2,21 @@ package handler
import (
// import required packages
<<<<<<< HEAD
_ "go.unistack.org/micro-proto/v4/openapiv3"
=======
_ "go.unistack.org/micro-proto/v3/openapiv3"
>>>>>>> rem/v3
)
//go:generate sh -c "curl -L https://github.com/swagger-api/swagger-ui/archive/refs/tags/v4.18.3.zip -o - | bsdtar -C swagger-ui --strip-components=2 -xv swagger-ui-4.18.3/dist && rm swagger-ui/*.map swagger-ui/*-es-*.js swagger-ui/swagger-ui.js swagger-ui/swagger-initializer.js"
<<<<<<< HEAD
//go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v4) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./meter/meter.proto"
//go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v4) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./health/health.proto"
=======
//go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./meter/meter.proto"
//go:generate sh -c "protoc -I./ -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out='components=micro|http|server',standalone=false,debug=true,paths=source_relative:./ ./health/health.proto"
>>>>>>> rem/v3

View File

@@ -0,0 +1,77 @@
//go:build ignore
package graphql_handler
import (
"context"
"fmt"
"github.com/99designs/gqlgen/graphql"
"go.unistack.org/micro/v3/logger"
"go.unistack.org/micro/v3/store"
)
var _ graphql.Cache = (*cacheWrapper)(nil)
type Handler struct {
opts Options
}
type Option func(*Options)
type Options struct {
cache *cacheWrapper
Path string
}
type cacheWrapper struct {
s store.Store
l logger.Logger
}
func (c *cacheWrapper) Get(ctx context.Context, key string) (interface{}, bool) {
var val interface{}
if err := c.s.Read(ctx, key, val); err != nil && err != store.ErrNotFound {
c.l.Error(ctx, fmt.Sprintf("cache.Get %s failed", key), err)
return nil, false
}
return val, true
}
func (c *cacheWrapper) Add(ctx context.Context, key string, val interface{}) {
if err := c.s.Write(ctx, key, val); err != nil {
c.l.Error(ctx, fmt.Sprintf("cache.Add %s failed", key), err)
}
}
func Store(s store.Store) Option {
return func(o *Options) {
if o.cache == nil {
o.cache = &cacheWrapper{}
}
o.cache.s = s
}
}
func Logger(l logger.Logger) Option {
return func(o *Options) {
if o.cache == nil {
o.cache = &cacheWrapper{}
}
o.cache.l = l
}
}
func Path(path string) Option {
return func(o *Options) {
o.Path = path
}
}
func NewHandler(opts ...Option) *Handler {
options := Options{}
for _, o := range opts {
o(&options)
}
return &Handler{opts: options}
}

View File

@@ -1,4 +1,8 @@
<<<<<<< HEAD
package health // import "go.unistack.org/micro-server-http/v4/handler/health"
=======
package health_handler
>>>>>>> rem/v3
import (
"context"
@@ -13,15 +17,30 @@ type Handler struct {
opts Options
}
type CheckFunc func(context.Context) error
type (
CheckFunc func(context.Context) error
Option func(*Options)
)
type Option func(*Options)
type Stater interface {
Live() bool
Ready() bool
Health() bool
}
type Options struct {
Version string
Name string
LiveChecks []CheckFunc
ReadyChecks []CheckFunc
Version string
Name string
Staters []Stater
LiveChecks []CheckFunc
ReadyChecks []CheckFunc
HealthChecks []CheckFunc
}
func Service(s ...Stater) Option {
return func(o *Options) {
o.Staters = append(o.Staters, s...)
}
}
func LiveChecks(fns ...CheckFunc) Option {
@@ -36,6 +55,12 @@ func ReadyChecks(fns ...CheckFunc) Option {
}
}
func HealthChecks(fns ...CheckFunc) Option {
return func(o *Options) {
o.HealthChecks = append(o.HealthChecks, fns...)
}
}
func Name(name string) Option {
return func(o *Options) {
o.Name = name
@@ -56,18 +81,51 @@ func NewHandler(opts ...Option) *Handler {
return &Handler{opts: options}
}
func (h *Handler) Healthy(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
var err error
for _, s := range h.opts.Staters {
if !s.Health() {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
}
}
for _, fn := range h.opts.HealthChecks {
if err = fn(ctx); err != nil {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
}
}
return nil
}
func (h *Handler) Live(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
var err error
for _, s := range h.opts.Staters {
if !s.Live() {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
}
}
for _, fn := range h.opts.LiveChecks {
if err = fn(ctx); err != nil {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
}
}
return nil
}
func (h *Handler) Ready(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
var err error
for _, s := range h.opts.Staters {
if !s.Ready() {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)
}
}
for _, fn := range h.opts.ReadyChecks {
if err = fn(ctx); err != nil {
return errors.ServiceUnavailable(h.opts.Name, "%v", err)

View File

@@ -1,13 +1,34 @@
syntax = "proto3";
<<<<<<< HEAD
package micro.server.http.v4.handler.health;
option go_package = "go.unistack.org/micro-server-http/v4/handler/health;health";
=======
package micro.server.http.v3.handler.health;
option go_package = "go.unistack.org/micro-server-http/v3/handler/health;health_handler";
>>>>>>> rem/v3
import "api/annotations.proto";
import "openapiv3/annotations.proto";
import "codec/frame.proto";
service HealthService {
rpc Healthy(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {
operation_id: "Healthy";
responses: {
default: {
reference: {
_ref: "micro.codec.Frame";
};
};
};
};
option (micro.api.http) = {
get: "/health";
additional_bindings: { get: "/healthz"; }
};
};
rpc Live(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {
operation_id: "Live";
@@ -19,7 +40,10 @@ service HealthService {
};
};
};
option (micro.api.http) = { get: "/live"; };
option (micro.api.http) = {
get: "/live";
additional_bindings: { get: "/livez"; }
};
};
rpc Ready(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {
@@ -32,7 +56,9 @@ service HealthService {
};
};
};
option (micro.api.http) = { get: "/ready"; };
option (micro.api.http) = { get: "/ready";
additional_bindings: { get: "/readyz"; }
};
};
rpc Version(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv3.openapiv3_operation) = {

View File

@@ -1,21 +1,42 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
// versions:
<<<<<<< HEAD
// - protoc-gen-go-micro v4.0.2
// - protoc v4.23.4
=======
// - protoc-gen-go-micro v3.10.4
// - protoc v5.28.3
>>>>>>> rem/v3
// source: health/health.proto
package health
package health_handler
import (
context "context"
<<<<<<< HEAD
codec "go.unistack.org/micro-proto/v4/codec"
=======
codec "go.unistack.org/micro-proto/v3/codec"
client "go.unistack.org/micro/v3/client"
>>>>>>> rem/v3
)
var (
HealthServiceName = "HealthService"
)
<<<<<<< HEAD
=======
type HealthServiceClient interface {
Healthy(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error)
Live(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error)
Ready(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error)
Version(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error)
}
>>>>>>> rem/v3
type HealthServiceServer interface {
Healthy(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error

View File

@@ -1,11 +1,16 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
<<<<<<< HEAD
// protoc-gen-go-micro version: v4.0.2
=======
// protoc-gen-go-micro version: v3.10.4
>>>>>>> rem/v3
// source: health/health.proto
package health
package health_handler
import (
context "context"
<<<<<<< HEAD
codec "go.unistack.org/micro-proto/v4/codec"
v4 "go.unistack.org/micro-server-http/v4"
options "go.unistack.org/micro/v4/options"
@@ -36,12 +41,159 @@ var (
Stream: false,
},
}
=======
v31 "go.unistack.org/micro-client-http/v3"
codec "go.unistack.org/micro-proto/v3/codec"
v3 "go.unistack.org/micro-server-http/v3"
client "go.unistack.org/micro/v3/client"
server "go.unistack.org/micro/v3/server"
http "net/http"
>>>>>>> rem/v3
)
var (
HealthServiceServerEndpoints = []v3.EndpointMetadata{
{
Name: "HealthService.Healthy",
Path: "/health",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Healthy",
Path: "/healthz",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Live",
Path: "/live",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Live",
Path: "/livez",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Ready",
Path: "/ready",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Ready",
Path: "/readyz",
Method: "GET",
Body: "",
Stream: false,
},
{
Name: "HealthService.Version",
Path: "/version",
Method: "GET",
Body: "",
Stream: false,
},
}
)
type healthServiceClient struct {
c client.Client
name string
}
func NewHealthServiceClient(name string, c client.Client) HealthServiceClient {
return &healthServiceClient{c: c, name: name}
}
func (c *healthServiceClient) Healthy(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) {
errmap := make(map[string]interface{}, 1)
errmap["default"] = &codec.Frame{}
opts = append(opts,
v31.ErrorMap(errmap),
)
opts = append(opts,
v31.Method(http.MethodGet),
v31.Path("/health"),
)
rsp := &codec.Frame{}
err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Healthy", req), rsp, opts...)
if err != nil {
return nil, err
}
return rsp, nil
}
func (c *healthServiceClient) Live(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) {
errmap := make(map[string]interface{}, 1)
errmap["default"] = &codec.Frame{}
opts = append(opts,
v31.ErrorMap(errmap),
)
opts = append(opts,
v31.Method(http.MethodGet),
v31.Path("/live"),
)
rsp := &codec.Frame{}
err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Live", req), rsp, opts...)
if err != nil {
return nil, err
}
return rsp, nil
}
func (c *healthServiceClient) Ready(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) {
errmap := make(map[string]interface{}, 1)
errmap["default"] = &codec.Frame{}
opts = append(opts,
v31.ErrorMap(errmap),
)
opts = append(opts,
v31.Method(http.MethodGet),
v31.Path("/ready"),
)
rsp := &codec.Frame{}
err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Ready", req), rsp, opts...)
if err != nil {
return nil, err
}
return rsp, nil
}
func (c *healthServiceClient) Version(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) {
errmap := make(map[string]interface{}, 1)
errmap["default"] = &codec.Frame{}
opts = append(opts,
v31.ErrorMap(errmap),
)
opts = append(opts,
v31.Method(http.MethodGet),
v31.Path("/version"),
)
rsp := &codec.Frame{}
err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Version", req), rsp, opts...)
if err != nil {
return nil, err
}
return rsp, nil
}
type healthServiceServer struct {
HealthServiceServer
}
func (h *healthServiceServer) Healthy(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
return h.HealthServiceServer.Healthy(ctx, req, rsp)
}
func (h *healthServiceServer) Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
return h.HealthServiceServer.Live(ctx, req, rsp)
}
@@ -56,6 +208,7 @@ func (h *healthServiceServer) Version(ctx context.Context, req *codec.Frame, rsp
func RegisterHealthServiceServer(s server.Server, sh HealthServiceServer, opts ...options.Option) error {
type healthService interface {
Healthy(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error

View File

@@ -1,4 +1,8 @@
<<<<<<< HEAD
package meter // import "go.unistack.org/micro-server-http/v4/handler/meter"
=======
package meter_handler
>>>>>>> rem/v3
import (
"bytes"
@@ -8,11 +12,18 @@ import (
"strings"
"sync"
<<<<<<< HEAD
codecpb "go.unistack.org/micro-proto/v4/codec"
"go.unistack.org/micro/v4/logger"
"go.unistack.org/micro/v4/metadata"
"go.unistack.org/micro/v4/meter"
"go.unistack.org/micro/v4/options"
=======
codecpb "go.unistack.org/micro-proto/v3/codec"
"go.unistack.org/micro/v3/logger"
"go.unistack.org/micro/v3/metadata"
"go.unistack.org/micro/v3/meter"
>>>>>>> rem/v3
)
const (
@@ -36,7 +47,7 @@ var bufPool = sync.Pool{
var _ MeterServiceServer = (*Handler)(nil)
type Handler struct {
opts Options
Options Options
}
type Option func(*Options)
@@ -44,7 +55,11 @@ type Option func(*Options)
type Options struct {
Meter meter.Meter
Name string
<<<<<<< HEAD
MeterOptions []options.Option
=======
MeterOptions []meter.Option
>>>>>>> rem/v3
DisableCompress bool
}
@@ -66,7 +81,11 @@ func DisableCompress(g bool) Option {
}
}
<<<<<<< HEAD
func MeterOptions(opts ...options.Option) Option {
=======
func MeterOptions(opts ...meter.Option) Option {
>>>>>>> rem/v3
return func(o *Options) {
o.MeterOptions = append(o.MeterOptions, opts...)
}
@@ -82,7 +101,7 @@ func NewOptions(opts ...Option) Options {
func NewHandler(opts ...Option) *Handler {
options := NewOptions(opts...)
return &Handler{opts: options}
return &Handler{Options: options}
}
func (h *Handler) Metrics(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error {
@@ -97,7 +116,11 @@ func (h *Handler) Metrics(ctx context.Context, req *codecpb.Frame, rsp *codecpb.
w := io.Writer(buf)
<<<<<<< HEAD
if md, ok := metadata.FromIncomingContext(ctx); gzipAccepted(md) && ok && !h.opts.DisableCompress {
=======
if md, ok := metadata.FromOutgoingContext(ctx); gzipAccepted(md) && ok && !h.Options.DisableCompress {
>>>>>>> rem/v3
omd, _ := metadata.FromOutgoingContext(ctx)
omd.Set(contentEncodingHeader, "gzip")
gz := gzipPool.Get().(*gzip.Writer)
@@ -110,8 +133,13 @@ func (h *Handler) Metrics(ctx context.Context, req *codecpb.Frame, rsp *codecpb.
gz.Flush()
}
<<<<<<< HEAD
if err := h.opts.Meter.Write(w, h.opts.MeterOptions...); err != nil {
log.Error(ctx, "http/meter: write failed", err)
=======
if err := h.Options.Meter.Write(w, h.Options.MeterOptions...); err != nil {
log.Error(ctx, "http/meter write failed", err)
>>>>>>> rem/v3
return nil
}

View File

@@ -1,7 +1,12 @@
syntax = "proto3";
<<<<<<< HEAD
package micro.server.http.v4.handler.meter;
option go_package = "go.unistack.org/micro-server-http/v4/handler/meter;meter";
=======
package micro.server.http.v3.handler.meter;
option go_package = "go.unistack.org/micro-server-http/v3/handler/meter;meter_handler";
>>>>>>> rem/v3
import "api/annotations.proto";
import "openapiv3/annotations.proto";

View File

@@ -1,19 +1,36 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
// versions:
<<<<<<< HEAD
// - protoc-gen-go-micro v4.0.2
// - protoc v4.23.4
=======
// - protoc-gen-go-micro v3.10.4
// - protoc v5.28.3
>>>>>>> rem/v3
// source: meter/meter.proto
package meter
package meter_handler
import (
context "context"
<<<<<<< HEAD
codec "go.unistack.org/micro-proto/v4/codec"
=======
codec "go.unistack.org/micro-proto/v3/codec"
client "go.unistack.org/micro/v3/client"
>>>>>>> rem/v3
)
var (
MeterServiceName = "MeterService"
)
<<<<<<< HEAD
=======
type MeterServiceClient interface {
Metrics(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error)
}
>>>>>>> rem/v3
type MeterServiceServer interface {
Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error

View File

@@ -1,11 +1,16 @@
// Code generated by protoc-gen-go-micro. DO NOT EDIT.
<<<<<<< HEAD
// protoc-gen-go-micro version: v4.0.2
=======
// protoc-gen-go-micro version: v3.10.4
>>>>>>> rem/v3
// source: meter/meter.proto
package meter
package meter_handler
import (
context "context"
<<<<<<< HEAD
codec "go.unistack.org/micro-proto/v4/codec"
v4 "go.unistack.org/micro-server-http/v4"
options "go.unistack.org/micro/v4/options"
@@ -22,8 +27,55 @@ var (
Stream: false,
},
}
=======
v31 "go.unistack.org/micro-client-http/v3"
codec "go.unistack.org/micro-proto/v3/codec"
v3 "go.unistack.org/micro-server-http/v3"
client "go.unistack.org/micro/v3/client"
server "go.unistack.org/micro/v3/server"
http "net/http"
>>>>>>> rem/v3
)
var (
MeterServiceServerEndpoints = []v3.EndpointMetadata{
{
Name: "MeterService.Metrics",
Path: "/metrics",
Method: "GET",
Body: "",
Stream: false,
},
}
)
type meterServiceClient struct {
c client.Client
name string
}
func NewMeterServiceClient(name string, c client.Client) MeterServiceClient {
return &meterServiceClient{c: c, name: name}
}
func (c *meterServiceClient) Metrics(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) {
errmap := make(map[string]interface{}, 1)
errmap["default"] = &codec.Frame{}
opts = append(opts,
v31.ErrorMap(errmap),
)
opts = append(opts,
v31.Method(http.MethodGet),
v31.Path("/metrics"),
)
rsp := &codec.Frame{}
err := c.c.Call(ctx, c.c.NewRequest(c.name, "MeterService.Metrics", req), rsp, opts...)
if err != nil {
return nil, err
}
return rsp, nil
}
type meterServiceServer struct {
MeterServiceServer
}

46
handler/pprof/pprof.go Normal file
View File

@@ -0,0 +1,46 @@
package pprof_handler
import (
"expvar"
"net/http"
"net/http/pprof"
"path"
"strings"
)
func NewHandler(prefixPath string, initFuncs ...func()) http.HandlerFunc {
for _, fn := range initFuncs {
fn()
}
return func(w http.ResponseWriter, r *http.Request) {
switch {
case strings.EqualFold(r.RequestURI, prefixPath) && r.RequestURI[len(r.RequestURI)-1] != '/':
http.Redirect(w, r, r.RequestURI+"/", http.StatusMovedPermanently)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "cmdline")):
pprof.Cmdline(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "profile")):
pprof.Profile(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "symbol")):
pprof.Symbol(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "trace")):
pprof.Trace(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "goroutine")):
pprof.Handler("goroutine").ServeHTTP(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "threadcreate")):
pprof.Handler("threadcreate").ServeHTTP(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "mutex")):
pprof.Handler("mutex").ServeHTTP(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "heap")):
pprof.Handler("heap").ServeHTTP(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "block")):
pprof.Handler("block").ServeHTTP(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "allocs")):
pprof.Handler("allocs").ServeHTTP(w, r)
case strings.HasPrefix(r.RequestURI, path.Join(prefixPath, "vars")):
expvar.Handler().ServeHTTP(w, r)
default:
pprof.Index(w, r)
}
}
}

View File

@@ -1,4 +1,8 @@
<<<<<<< HEAD
package swaggerui // import "go.unistack.org/micro-server-http/v4/handler/swagger-ui"
=======
package swaggerui_handler
>>>>>>> rem/v3
import (
"embed"

View File

@@ -1,4 +1,8 @@
<<<<<<< HEAD
package swaggerui
=======
package swaggerui_handler
>>>>>>> rem/v3
import (
"net/http"

View File

@@ -1,11 +1,20 @@
<<<<<<< HEAD
package swagger
=======
package swagger_handler
>>>>>>> rem/v3
import (
"io/fs"
"net/http"
<<<<<<< HEAD
yamlcodec "go.unistack.org/micro-codec-yaml/v4"
rutil "go.unistack.org/micro/v4/util/reflect"
=======
yamlcodec "go.unistack.org/micro-codec-yaml/v3"
rutil "go.unistack.org/micro/v3/util/reflect"
>>>>>>> rem/v3
)
// Handler append to generated swagger data from dst map[string]interface{}