Compare commits

...

8 Commits

Author SHA1 Message Date
eb2a450a7b meter/handler: fix func signature
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-25 12:36:48 +03:00
Renovate Bot
d2a30a5da1 fix(deps): update golang.org/x/net commit hash to d1beb07 2021-03-24 23:28:38 +00:00
65889c66f6 meter/wrapper: add DefaultSkipEndpoints
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-25 00:06:38 +03:00
dcdf133d5b server: mask router
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-24 13:26:36 +03:00
8742b55305 auth: fix Init method
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-24 13:12:03 +03:00
4a64ee72f7 meter/handler: provide default metrics handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-23 17:26:29 +03:00
881d7afeea meter/handler: provide initial meter handler
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-23 17:12:13 +03:00
8c95448535 util/reflect: add IsZero helper
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2021-03-21 16:17:50 +03:00
14 changed files with 227 additions and 10 deletions

View File

@@ -30,7 +30,7 @@ var (
// Auth provides authentication and authorization
type Auth interface {
// Init the auth
Init(opts ...Option)
Init(opts ...Option) error
// Options set for auth
Options() Options
// Generate a new account

View File

@@ -14,10 +14,11 @@ func (n *noopAuth) String() string {
}
// Init the auth
func (n *noopAuth) Init(opts ...Option) {
func (n *noopAuth) Init(opts ...Option) error {
for _, o := range opts {
o(&n.opts)
}
return nil
}
// Options set for auth

2
go.mod
View File

@@ -9,5 +9,5 @@ require (
github.com/imdario/mergo v0.3.12
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/silas/dag v0.0.0-20210121180416-41cf55125c34
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4
golang.org/x/net v0.0.0-20210324205630-d1beb07c2056
)

6
go.sum
View File

@@ -10,10 +10,10 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/silas/dag v0.0.0-20210121180416-41cf55125c34 h1:vBfVmA5mZhsQa2jr1FOL9nfA37N/jnbBmi5XUfviVTI=
github.com/silas/dag v0.0.0-20210121180416-41cf55125c34/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210324205630-d1beb07c2056 h1:sANdAef76Ioam9aQUUdcAqricwY/WUaMc4+7LY4eGg8=
golang.org/x/net v0.0.0-20210324205630-d1beb07c2056/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

3
meter/generate.go Normal file
View File

@@ -0,0 +1,3 @@
package meter
//go:generate protoc -I./handler -I../ -I/home/vtolstov/.cache/go-path/pkg/mod/github.com/unistack-org/micro-proto@v0.0.1 --micro_out=components=micro|http|server,standalone=false,debug=true,paths=source_relative:./handler handler/handler.proto

36
meter/handler/handler.go Normal file
View File

@@ -0,0 +1,36 @@
package pb
import (
"bytes"
"context"
"github.com/unistack-org/micro/v3/codec"
"github.com/unistack-org/micro/v3/meter"
)
var (
// guard to fail early
_ MeterServer = &handler{}
)
type Empty struct{}
type handler struct {
meter meter.Meter
opts []meter.Option
}
func NewHandler(meter meter.Meter, opts ...meter.Option) *handler {
return &handler{meter: meter, opts: opts}
}
func (h *handler) Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
buf := bytes.NewBuffer(nil)
if err := h.meter.Write(buf, h.opts...); err != nil {
return err
}
rsp.Data = buf.Bytes()
return nil
}

View File

@@ -0,0 +1,28 @@
syntax = "proto3";
package meter;
option go_package = "github.com/unistack-org/micro/v3/meter/handler;pb";
import "api/annotations.proto";
import "openapiv2/annotations.proto";
import "codec/frame.proto";
service Meter {
rpc Metrics(micro.codec.Frame) returns (micro.codec.Frame) {
option (micro.openapiv2.openapiv2_operation) = {
operation_id: "Metrics";
responses: {
key: "default";
value: {
description: "Error response";
schema: {
json_schema: {
ref: "Empty";
}
}
}
}
};
option (micro.api.http) = { get: "/metrics"; };
};
};

View File

@@ -0,0 +1,24 @@
// Code generated by protoc-gen-micro
// source: handler.proto
package pb
import (
context "context"
api "github.com/unistack-org/micro/v3/api"
codec "github.com/unistack-org/micro/v3/codec"
)
func NewMeterEndpoints() []*api.Endpoint {
return []*api.Endpoint{
&api.Endpoint{
Name: "Meter.Metrics",
Path: []string{"/metrics"},
Method: []string{"GET"},
Handler: "rpc",
},
}
}
type MeterServer interface {
Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
}

View File

@@ -0,0 +1,32 @@
// Code generated by protoc-gen-micro
// source: handler.proto
package pb
import (
context "context"
api "github.com/unistack-org/micro/v3/api"
codec "github.com/unistack-org/micro/v3/codec"
server "github.com/unistack-org/micro/v3/server"
)
type meterServer struct {
MeterServer
}
func (h *meterServer) Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error {
return h.MeterServer.Metrics(ctx, req, rsp)
}
func RegisterMeterServer(s server.Server, sh MeterServer, opts ...server.HandlerOption) error {
type meter interface {
Metrics(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error
}
type Meter struct {
meter
}
h := &meterServer{sh}
for _, endpoint := range NewMeterEndpoints() {
opts = append(opts, api.WithEndpoint(endpoint))
}
return s.Handle(s.NewHandler(&Meter{h}, opts...))
}

View File

@@ -28,6 +28,9 @@ var (
labelFailure = "failure"
labelStatus = "status"
labelEndpoint = "endpoint"
// DefaultSkipEndpoints contains list of endpoints that not evaluted by wrapper
DefaultSkipEndpoints = []string{"Meter.Metrics"}
)
type Options struct {
@@ -100,7 +103,11 @@ func NewCallWrapper(opts ...Option) client.CallWrapper {
func (w *wrapper) CallFunc(ctx context.Context, addr string, req client.Request, rsp interface{}, opts client.CallOptions) error {
endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
for _, ep := range DefaultSkipEndpoints {
if ep == endpoint {
return w.callFunc(ctx, addr, req, rsp, opts)
}
}
ts := time.Now()
err := w.callFunc(ctx, addr, req, rsp, opts)
te := time.Since(ts)
@@ -123,6 +130,11 @@ func (w *wrapper) CallFunc(ctx context.Context, addr string, req client.Request,
func (w *wrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
for _, ep := range DefaultSkipEndpoints {
if ep == endpoint {
return w.Client.Call(ctx, req, rsp, opts...)
}
}
ts := time.Now()
err := w.Client.Call(ctx, req, rsp, opts...)
@@ -146,6 +158,11 @@ func (w *wrapper) Call(ctx context.Context, req client.Request, rsp interface{},
func (w *wrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) {
endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
for _, ep := range DefaultSkipEndpoints {
if ep == endpoint {
return w.Client.Stream(ctx, req, opts...)
}
}
ts := time.Now()
stream, err := w.Client.Stream(ctx, req, opts...)
@@ -200,6 +217,11 @@ func NewHandlerWrapper(opts ...Option) server.HandlerWrapper {
func (w *wrapper) HandlerFunc(fn server.HandlerFunc) server.HandlerFunc {
return func(ctx context.Context, req server.Request, rsp interface{}) error {
endpoint := req.Endpoint()
for _, ep := range DefaultSkipEndpoints {
if ep == endpoint {
return fn(ctx, req, rsp)
}
}
ts := time.Now()
err := fn(ctx, req, rsp)

View File

@@ -39,8 +39,12 @@ type Options struct {
Meter meter.Meter
// Transport holds the transport
Transport transport.Transport
// Router for requests
Router Router
/*
// Router for requests
Router Router
*/
// Listener may be passed if already created
Listener net.Listener
// Wait group
@@ -262,12 +266,14 @@ func TLSConfig(t *tls.Config) Option {
}
}
/*
// WithRouter sets the request router
func WithRouter(r Router) Option {
return func(o *Options) {
o.Router = r
}
}
*/
// Wait tells the server to wait for requests to finish before exiting
// If `wg` is nil, server only wait for completion of rpc handler.

View File

@@ -65,6 +65,7 @@ type Server interface {
String() string
}
/*
// Router handle serving messages
type Router interface {
// ProcessMessage processes a message
@@ -72,6 +73,7 @@ type Router interface {
// ServeRequest processes a request to completion
ServeRequest(ctx context.Context, req Request, rsp Response) error
}
*/
// Message is an async message interface
type Message interface {

View File

@@ -65,8 +65,24 @@ func IsEmpty(v reflect.Value) bool {
return v.IsNil()
case reflect.Invalid:
return true
case reflect.Struct:
var ok bool
for i := 0; i < v.NumField(); i++ {
ok = IsEmpty(v.FieldByIndex([]int{i}))
if !ok {
return false
}
}
default:
return false
}
return false
return true
}
// IsZero returns true if struct is zero (not have any defined values)
func IsZero(src interface{}) bool {
v := reflect.ValueOf(src)
return IsEmpty(v)
}
// Zero creates new zero interface

View File

@@ -43,3 +43,50 @@ func TestURLVars(t *testing.T) {
}
_ = mp
}
func TestIsZero(t *testing.T) {
testStr1 := struct {
Name string
Value string
Nested struct {
NestedName string
}
}{
Name: "test_name",
Value: "test_value",
}
testStr1.Nested.NestedName = "nested_name"
if ok := IsZero(testStr1); ok {
t.Fatalf("zero ret on non zero struct: %#+v", testStr1)
}
testStr1.Name = ""
testStr1.Value = ""
testStr1.Nested.NestedName = ""
if ok := IsZero(testStr1); !ok {
t.Fatalf("non zero ret on zero struct: %#+v", testStr1)
}
type testStr3 struct {
Nested string
}
type testStr2 struct {
Name string
Nested *testStr3
}
vtest := &testStr2{
Name: "test_name",
Nested: &testStr3{Nested: "nested_name"},
}
if ok := IsZero(vtest); ok {
t.Fatalf("zero ret on non zero struct: %#+v", vtest)
}
vtest.Nested = nil
vtest.Name = ""
if ok := IsZero(vtest); !ok {
t.Fatalf("non zero ret on zero struct: %#+v", vtest)
}
//t.Logf("XX %#+v\n", ok)
}