import related code from micro repo

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
Василий Толстов 2020-11-05 23:45:50 +03:00
parent 31c35661ae
commit 241e452ecf
3 changed files with 105 additions and 3 deletions

View File

@ -21,7 +21,6 @@ import (
meta "github.com/unistack-org/micro/v3/metadata"
"github.com/unistack-org/micro/v3/registry"
"github.com/unistack-org/micro/v3/server"
mgrpc "github.com/unistack-org/micro/v3/util/grpc"
"golang.org/x/net/netutil"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
@ -252,7 +251,7 @@ func (g *grpcServer) handler(srv interface{}, stream grpc.ServerStream) (err err
return status.Errorf(codes.Internal, "method does not exist in context")
}
serviceName, methodName, err := mgrpc.ServiceMethod(fullMethod)
serviceName, methodName, err := serviceMethod(fullMethod)
if err != nil {
return status.New(codes.InvalidArgument, err.Error()).Err()
}
@ -319,7 +318,7 @@ func (g *grpcServer) handler(srv interface{}, stream grpc.ServerStream) (err err
// create a client.Request
request := &rpcRequest{
service: mgrpc.ServiceFromMethod(fullMethod),
service: serviceFromMethod(fullMethod),
contentType: ct,
method: fmt.Sprintf("%s.%s", serviceName, methodName),
codec: codec,

57
util.go Normal file
View File

@ -0,0 +1,57 @@
package grpc
import (
"fmt"
"strings"
)
// ServiceMethod converts a gRPC method to a Go method
// Input:
// Foo.Bar, /Foo/Bar, /package.Foo/Bar, /a.package.Foo/Bar
// Output:
// [Foo, Bar]
func serviceMethod(m string) (string, string, error) {
if len(m) == 0 {
return "", "", fmt.Errorf("malformed method name: %q", m)
}
// grpc method
if m[0] == '/' {
// [ , Foo, Bar]
// [ , package.Foo, Bar]
// [ , a.package.Foo, Bar]
parts := strings.Split(m, "/")
if len(parts) != 3 || len(parts[1]) == 0 || len(parts[2]) == 0 {
return "", "", fmt.Errorf("malformed method name: %q", m)
}
service := strings.Split(parts[1], ".")
return service[len(service)-1], parts[2], nil
}
// non grpc method
parts := strings.Split(m, ".")
// expect [Foo, Bar]
if len(parts) != 2 {
return "", "", fmt.Errorf("malformed method name: %q", m)
}
return parts[0], parts[1], nil
}
// ServiceFromMethod returns the service
// /service.Foo/Bar => service
func serviceFromMethod(m string) string {
if len(m) == 0 {
return m
}
if m[0] != '/' {
return m
}
parts := strings.Split(m, "/")
if len(parts) < 3 {
return m
}
parts = strings.Split(parts[1], ".")
return strings.Join(parts[:len(parts)-1], ".")
}

46
util_test.go Normal file
View File

@ -0,0 +1,46 @@
package grpc
import (
"testing"
)
func TestServiceMethod(t *testing.T) {
type testCase struct {
input string
service string
method string
err bool
}
methods := []testCase{
{"Foo.Bar", "Foo", "Bar", false},
{"/Foo/Bar", "Foo", "Bar", false},
{"/package.Foo/Bar", "Foo", "Bar", false},
{"/a.package.Foo/Bar", "Foo", "Bar", false},
{"a.package.Foo/Bar", "", "", true},
{"/Foo/Bar/Baz", "", "", true},
{"Foo.Bar.Baz", "", "", true},
}
for _, test := range methods {
service, method, err := serviceMethod(test.input)
if err != nil && test.err == true {
continue
}
// unexpected error
if err != nil && test.err == false {
t.Fatalf("unexpected err %v for %+v", err, test)
}
// expecter error
if test.err == true && err == nil {
t.Fatalf("expected error for %+v: got service: %s method: %s", test, service, method)
}
if service != test.service {
t.Fatalf("wrong service for %+v: got service: %s method: %s", test, service, method)
}
if method != test.method {
t.Fatalf("wrong method for %+v: got service: %s method: %s", test, service, method)
}
}
}