mirror of
https://github.com/linka-cloud/grpc.git
synced 2024-12-23 01:10:46 +00:00
92 lines
2.7 KiB
Go
92 lines
2.7 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
greflectsvc "google.golang.org/grpc/reflection/grpc_reflection_v1"
|
||
|
"google.golang.org/protobuf/proto"
|
||
|
"google.golang.org/protobuf/types/descriptorpb"
|
||
|
|
||
|
"go.linka.cloud/grpc-toolkit/client"
|
||
|
"go.linka.cloud/grpc-toolkit/logger"
|
||
|
)
|
||
|
|
||
|
func readSvcs(ctx context.Context, c client.Client) (err error) {
|
||
|
log := logger.C(ctx)
|
||
|
rc := greflectsvc.NewServerReflectionClient(c)
|
||
|
rstream, err := rc.ServerReflectionInfo(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer func() {
|
||
|
if err2 := rstream.CloseSend(); err2 != nil && err == nil {
|
||
|
err = err2
|
||
|
}
|
||
|
}()
|
||
|
if err = rstream.Send(&greflectsvc.ServerReflectionRequest{MessageRequest: &greflectsvc.ServerReflectionRequest_ListServices{}}); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
var rres *greflectsvc.ServerReflectionResponse
|
||
|
rres, err = rstream.Recv()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
rlist, ok := rres.MessageResponse.(*greflectsvc.ServerReflectionResponse_ListServicesResponse)
|
||
|
if !ok {
|
||
|
return fmt.Errorf("unexpected reflection response type: %T", rres.MessageResponse)
|
||
|
}
|
||
|
for _, v := range rlist.ListServicesResponse.Service {
|
||
|
if v.Name == "grpc.reflection.v1alpha.ServerReflection" || v.Name == "grpc.reflection.v1.ServerReflection" || v.Name == "grpc.health.v1.Health" {
|
||
|
continue
|
||
|
}
|
||
|
parts := strings.Split(v.Name, ".")
|
||
|
if len(parts) < 2 {
|
||
|
return fmt.Errorf("malformed service name: %s", v.Name)
|
||
|
}
|
||
|
pkg := strings.Join(parts[:len(parts)-1], ".")
|
||
|
svc := parts[len(parts)-1]
|
||
|
if err = rstream.Send(&greflectsvc.ServerReflectionRequest{MessageRequest: &greflectsvc.ServerReflectionRequest_FileContainingSymbol{
|
||
|
FileContainingSymbol: v.Name,
|
||
|
}}); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
rres, err = rstream.Recv()
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
rfile, ok := rres.MessageResponse.(*greflectsvc.ServerReflectionResponse_FileDescriptorResponse)
|
||
|
if !ok {
|
||
|
return fmt.Errorf("unexpected reflection response type: %T", rres.MessageResponse)
|
||
|
}
|
||
|
fdps := make(map[string]*descriptorpb.DescriptorProto)
|
||
|
var sdp *descriptorpb.ServiceDescriptorProto
|
||
|
for _, v := range rfile.FileDescriptorResponse.FileDescriptorProto {
|
||
|
fdp := &descriptorpb.FileDescriptorProto{}
|
||
|
if err = proto.Unmarshal(v, fdp); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
for _, s := range fdp.GetService() {
|
||
|
if fdp.GetPackage() == pkg && s.GetName() == svc {
|
||
|
if sdp != nil {
|
||
|
log.Warnf("service already found: %s.%s", fdp.GetPackage(), s.GetName())
|
||
|
continue
|
||
|
}
|
||
|
sdp = s
|
||
|
}
|
||
|
}
|
||
|
for _, m := range fdp.GetMessageType() {
|
||
|
fdps[fdp.GetPackage()+"."+m.GetName()] = m
|
||
|
}
|
||
|
}
|
||
|
if sdp == nil {
|
||
|
return fmt.Errorf("%s: service not found", v.Name)
|
||
|
}
|
||
|
for _, m := range sdp.GetMethod() {
|
||
|
log.Infof("%s: %s", v.Name, m.GetName())
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|