#2 - add swaggerset
This commit is contained in:
84
pkg/protoset/protoset.go
Normal file
84
pkg/protoset/protoset.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package protoset
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
protocodec "go.unistack.org/micro-codec-proto/v3"
|
||||
"google.golang.org/protobuf/reflect/protodesc"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/descriptorpb"
|
||||
"google.golang.org/protobuf/types/dynamicpb"
|
||||
)
|
||||
|
||||
var errNotFound = errors.New("file descriptor not found")
|
||||
|
||||
type ProtoSet struct {
|
||||
mu sync.Mutex
|
||||
files map[string]*protoregistry.Files
|
||||
}
|
||||
|
||||
func NewProtoSet() *ProtoSet {
|
||||
return &ProtoSet{
|
||||
mu: sync.Mutex{},
|
||||
files: make(map[string]*protoregistry.Files, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ProtoSet) GetMessage(addr, pkg, svc, mth string) (protoreflect.Message, protoreflect.Message, error) {
|
||||
if addr == "" || svc == "" || mth == "" || pkg == "" {
|
||||
return nil, nil, errors.New("addr or service name is empty")
|
||||
}
|
||||
p.mu.Lock()
|
||||
pfile, ok := p.files[addr+"|"+svc]
|
||||
p.mu.Unlock()
|
||||
if !ok || pfile == nil {
|
||||
return nil, nil, errNotFound
|
||||
}
|
||||
|
||||
pdesc, err := pfile.FindDescriptorByName(protoreflect.FullName(pkg + "." + svc))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to find service %s.%s, err: %w", pkg, svc, err)
|
||||
}
|
||||
|
||||
sdesc, ok := pdesc.(protoreflect.ServiceDescriptor)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("failed to find service " + pkg + "." + svc)
|
||||
}
|
||||
|
||||
mdesc := sdesc.Methods().ByName(protoreflect.Name(mth))
|
||||
if mdesc == nil {
|
||||
return nil, nil, fmt.Errorf("unknown method " + mth)
|
||||
}
|
||||
|
||||
req := dynamicpb.NewMessageType(mdesc.Input()).New()
|
||||
rsp := dynamicpb.NewMessageType(mdesc.Output()).New()
|
||||
|
||||
return req, rsp, nil
|
||||
}
|
||||
|
||||
func (p *ProtoSet) AddProtoset(addr, svc string, data []byte) error {
|
||||
fdset := &descriptorpb.FileDescriptorSet{}
|
||||
if err := protocodec.NewCodec().Unmarshal(data, fdset); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal protoset file: %w", err)
|
||||
}
|
||||
|
||||
pfileoptions := protodesc.FileOptions{AllowUnresolvable: true}
|
||||
pfiles, err := pfileoptions.NewFiles(fdset)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to use protoset file, err: %w", err)
|
||||
}
|
||||
|
||||
p.mu.Lock()
|
||||
p.files[addr+"|"+svc] = pfiles
|
||||
p.mu.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ProtoSet) AddReflection(ctx context.Context, service string, addr string) error {
|
||||
return nil
|
||||
}
|
49
pkg/protoset/protoset_test.go
Normal file
49
pkg/protoset/protoset_test.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package protoset
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestProtoSet_1(t *testing.T) {
|
||||
p := NewProtoSet()
|
||||
data, err := os.ReadFile("path to .protoset")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = p.AddProtoset("localhost:9090", "CardService", data)
|
||||
assert.Nil(t, err)
|
||||
|
||||
req, rsp, err := p.GetMessage("localhost:9090", "card_proto", "CardService", "GetCardList")
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, req)
|
||||
assert.NotNil(t, rsp)
|
||||
fmt.Printf("req: %v, rsp: %v \n", req, rsp)
|
||||
}
|
||||
|
||||
func TestProtoSet_2_bad(t *testing.T) {
|
||||
p := NewProtoSet()
|
||||
data, err := os.ReadFile("path to .protoset")
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = p.AddProtoset("localhost:9090", "CardService", data)
|
||||
assert.Nil(t, err)
|
||||
|
||||
req, rsp, err := p.GetMessage("localhost:9090", "card_proto", "Card", "GetCardList")
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, req)
|
||||
assert.Nil(t, rsp)
|
||||
fmt.Printf("req: %v, rsp: %v \n", req, rsp)
|
||||
}
|
||||
|
||||
func TestProtoSet_3_not_found(t *testing.T) {
|
||||
p := NewProtoSet()
|
||||
|
||||
req, rsp, err := p.GetMessage("localhost:9090", "card_proto", "CardService", "GetCardList")
|
||||
assert.ErrorIs(t, err, errNotFound)
|
||||
assert.Nil(t, req)
|
||||
assert.Nil(t, rsp)
|
||||
fmt.Printf("req: %v, rsp: %v \n", req, rsp)
|
||||
}
|
Reference in New Issue
Block a user