feat(contrib/opensergo): add opensergo reportMetadata fields (#1996)

* add fields descriptor
pull/2035/head
Kagaya 3 years ago committed by GitHub
parent 79497dd3a5
commit 643caa6df9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      contrib/opensergo/README.md
  2. 2
      contrib/opensergo/go.mod
  3. 69
      contrib/opensergo/opensergo.go

@ -0,0 +1,32 @@
# OpenSergo
## Usage
```go
osServer, err := opensergo.New(opensergo.WithEndpoint("localhost:9090"))
if err != nil {
panic("init opensergo error")
}
s := &server{}
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
recovery.Recovery(),
),
)
helloworld.RegisterGreeterServer(grpcSrv, s)
app := kratos.New(
kratos.Name(Name),
kratos.Server(
grpcSrv,
),
)
osServer.ReportMetadata(context.Background(), app)
if err := app.Run(); err != nil {
log.Fatal(err)
}
```

@ -6,6 +6,7 @@ require (
github.com/go-kratos/kratos/v2 v2.2.2 github.com/go-kratos/kratos/v2 v2.2.2
github.com/opensergo/opensergo-go v0.0.0-20220331070310-e5b01fee4d1c github.com/opensergo/opensergo-go v0.0.0-20220331070310-e5b01fee4d1c
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd
google.golang.org/grpc v1.46.2 google.golang.org/grpc v1.46.2
google.golang.org/protobuf v1.28.0 google.golang.org/protobuf v1.28.0
) )
@ -17,6 +18,5 @@ require (
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
gopkg.in/yaml.v3 v3.0.0 // indirect gopkg.in/yaml.v3 v3.0.0 // indirect
) )

@ -12,8 +12,10 @@ import (
"github.com/go-kratos/kratos/v2" "github.com/go-kratos/kratos/v2"
v1 "github.com/opensergo/opensergo-go/proto/service_contract/v1" v1 "github.com/opensergo/opensergo-go/proto/service_contract/v1"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/genproto/googleapis/api/annotations"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/reflect/protoregistry"
) )
@ -73,15 +75,18 @@ func New(opts ...Option) (*OpenSergo, error) {
} }
func (s *OpenSergo) ReportMetadata(ctx context.Context, app kratos.AppInfo) error { func (s *OpenSergo) ReportMetadata(ctx context.Context, app kratos.AppInfo) error {
services, err := s.listServiceDescriptors() services, types, err := listDescriptors()
if err != nil { if err != nil {
return err return err
} }
serviceMetadata := &v1.ServiceMetadata{ serviceMetadata := &v1.ServiceMetadata{
ServiceContract: &v1.ServiceContract{ ServiceContract: &v1.ServiceContract{
Services: services, Services: services,
Types: types,
}, },
} }
for _, endpoint := range app.Endpoint() { for _, endpoint := range app.Endpoint() {
u, err := url.Parse(endpoint) //nolint u, err := url.Parse(endpoint) //nolint
if err != nil { if err != nil {
@ -104,11 +109,12 @@ func (s *OpenSergo) ReportMetadata(ctx context.Context, app kratos.AppInfo) erro
_, err = s.mdClient.ReportMetadata(ctx, &v1.ReportMetadataRequest{ _, err = s.mdClient.ReportMetadata(ctx, &v1.ReportMetadataRequest{
AppName: app.Name(), AppName: app.Name(),
ServiceMetadata: []*v1.ServiceMetadata{serviceMetadata}, ServiceMetadata: []*v1.ServiceMetadata{serviceMetadata},
// TODO: Node: *v1.Node,
}) })
return err return err
} }
func (s *OpenSergo) listServiceDescriptors() (services []*v1.ServiceDescriptor, err error) { func listDescriptors() (services []*v1.ServiceDescriptor, types []*v1.TypeDescriptor, err error) {
protoregistry.GlobalFiles.RangeFiles(func(fd protoreflect.FileDescriptor) bool { protoregistry.GlobalFiles.RangeFiles(func(fd protoreflect.FileDescriptor) bool {
for i := 0; i < fd.Services().Len(); i++ { for i := 0; i < fd.Services().Len(); i++ {
var ( var (
@ -120,19 +126,78 @@ func (s *OpenSergo) listServiceDescriptors() (services []*v1.ServiceDescriptor,
mName := string(md.Name()) mName := string(md.Name())
inputType := string(md.Input().FullName()) inputType := string(md.Input().FullName())
outputType := string(md.Output().FullName()) outputType := string(md.Output().FullName())
isClientStreaming := md.IsStreamingClient()
isServerStreaming := md.IsStreamingServer()
pattern := proto.GetExtension(md.Options(), annotations.E_Http).(*annotations.HttpRule).GetPattern()
var httpPath, httpMethod string
if pattern != nil {
httpPath, httpMethod = HTTPPatternInfo(pattern)
}
methodDesc := v1.MethodDescriptor{ methodDesc := v1.MethodDescriptor{
Name: mName, Name: mName,
InputTypes: []string{inputType}, InputTypes: []string{inputType},
OutputTypes: []string{outputType}, OutputTypes: []string{outputType},
ClientStreaming: &isClientStreaming,
ServerStreaming: &isServerStreaming,
HttpPaths: []string{httpPath},
HttpMethods: []string{httpMethod},
// TODO: Description: *string,
} }
methods = append(methods, &methodDesc) methods = append(methods, &methodDesc)
} }
services = append(services, &v1.ServiceDescriptor{ services = append(services, &v1.ServiceDescriptor{
Name: string(sd.Name()), Name: string(sd.Name()),
Methods: methods, Methods: methods,
// TODO: Description: *string,
}) })
} }
for i := 0; i < fd.Messages().Len(); i++ {
var (
fields []*v1.FieldDescriptor
md = fd.Messages().Get(i)
)
for j := 0; j < md.Fields().Len(); j++ {
fd := md.Fields().Get(j)
kind := fd.Kind()
typeName := kind.String()
fields = append(fields, &v1.FieldDescriptor{
Name: string(fd.Name()),
Number: int32(fd.Number()),
Type: v1.FieldDescriptor_Type(kind),
TypeName: &typeName,
// TODO: Description: *string,
})
}
types = append(types, &v1.TypeDescriptor{
Name: string(md.Name()),
Fields: fields,
})
}
return true return true
}) })
return return
} }
func HTTPPatternInfo(pattern interface{}) (method string, path string) {
switch p := pattern.(type) {
case *annotations.HttpRule_Get:
return "GET", p.Get
case *annotations.HttpRule_Post:
return "POST", p.Post
case *annotations.HttpRule_Delete:
return "DELETE", p.Delete
case *annotations.HttpRule_Patch:
return "PATCH", p.Patch
case *annotations.HttpRule_Put:
return "PUT", p.Put
case *annotations.HttpRule_Custom:
return p.Custom.Kind, p.Custom.Path
default:
return "", ""
}
}

Loading…
Cancel
Save