mirror of https://github.com/dapr/go-sdk.git
feat: Invoke will extract querystring from method (#127)
Co-authored-by: 李锐 <lirui@meican.com>
This commit is contained in:
parent
f2b03d2b4f
commit
b6b6d06110
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
# IDE
|
# IDE
|
||||||
.vscode
|
.vscode
|
||||||
|
.idea
|
||||||
|
|
||||||
# Test binary, build with `go test -c`
|
# Test binary, build with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|
|
@ -39,9 +39,16 @@ func (c *GRPCClient) invokeServiceWithRequest(ctx context.Context, req *pb.Invok
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func verbToHTTPExtension(verb string) *v1.HTTPExtension {
|
func queryAndVerbToHTTPExtension(query string, verb string) *v1.HTTPExtension {
|
||||||
|
var queryMap = map[string]string{}
|
||||||
|
for _, item := range strings.Split(query, "&") {
|
||||||
|
kv := strings.Split(item, "=")
|
||||||
|
if len(kv) == 2 {
|
||||||
|
queryMap[kv[0]] = kv[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
if v, ok := v1.HTTPExtension_Verb_value[strings.ToUpper(verb)]; ok {
|
if v, ok := v1.HTTPExtension_Verb_value[strings.ToUpper(verb)]; ok {
|
||||||
return &v1.HTTPExtension{Verb: v1.HTTPExtension_Verb(v)}
|
return &v1.HTTPExtension{Verb: v1.HTTPExtension_Verb(v), Querystring: queryMap}
|
||||||
}
|
}
|
||||||
return &v1.HTTPExtension{Verb: v1.HTTPExtension_NONE}
|
return &v1.HTTPExtension{Verb: v1.HTTPExtension_NONE}
|
||||||
}
|
}
|
||||||
|
@ -64,11 +71,12 @@ func (c *GRPCClient) InvokeMethod(ctx context.Context, appID, methodName, verb s
|
||||||
if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil {
|
if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil {
|
||||||
return nil, errors.Wrap(err, "missing required parameter")
|
return nil, errors.Wrap(err, "missing required parameter")
|
||||||
}
|
}
|
||||||
|
method, query := extractMethodAndQuery(methodName)
|
||||||
req := &pb.InvokeServiceRequest{
|
req := &pb.InvokeServiceRequest{
|
||||||
Id: appID,
|
Id: appID,
|
||||||
Message: &v1.InvokeRequest{
|
Message: &v1.InvokeRequest{
|
||||||
Method: methodName,
|
Method: method,
|
||||||
HttpExtension: verbToHTTPExtension(verb),
|
HttpExtension: queryAndVerbToHTTPExtension(query, verb),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return c.invokeServiceWithRequest(ctx, req)
|
return c.invokeServiceWithRequest(ctx, req)
|
||||||
|
@ -82,13 +90,14 @@ func (c *GRPCClient) InvokeMethodWithContent(ctx context.Context, appID, methodN
|
||||||
if content == nil {
|
if content == nil {
|
||||||
return nil, errors.New("content required")
|
return nil, errors.New("content required")
|
||||||
}
|
}
|
||||||
|
method, query := extractMethodAndQuery(methodName)
|
||||||
req := &pb.InvokeServiceRequest{
|
req := &pb.InvokeServiceRequest{
|
||||||
Id: appID,
|
Id: appID,
|
||||||
Message: &v1.InvokeRequest{
|
Message: &v1.InvokeRequest{
|
||||||
Method: methodName,
|
Method: method,
|
||||||
Data: &anypb.Any{Value: content.Data},
|
Data: &anypb.Any{Value: content.Data},
|
||||||
ContentType: content.ContentType,
|
ContentType: content.ContentType,
|
||||||
HttpExtension: verbToHTTPExtension(verb),
|
HttpExtension: queryAndVerbToHTTPExtension(query, verb),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return c.invokeServiceWithRequest(ctx, req)
|
return c.invokeServiceWithRequest(ctx, req)
|
||||||
|
@ -111,15 +120,26 @@ func (c *GRPCClient) InvokeMethodWithCustomContent(ctx context.Context, appID, m
|
||||||
return nil, errors.WithMessage(err, "error serializing input struct")
|
return nil, errors.WithMessage(err, "error serializing input struct")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
method, query := extractMethodAndQuery(methodName)
|
||||||
|
|
||||||
req := &pb.InvokeServiceRequest{
|
req := &pb.InvokeServiceRequest{
|
||||||
Id: appID,
|
Id: appID,
|
||||||
Message: &v1.InvokeRequest{
|
Message: &v1.InvokeRequest{
|
||||||
Method: methodName,
|
Method: method,
|
||||||
Data: &anypb.Any{Value: contentData},
|
Data: &anypb.Any{Value: contentData},
|
||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
HttpExtension: verbToHTTPExtension(verb),
|
HttpExtension: queryAndVerbToHTTPExtension(query, verb),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.invokeServiceWithRequest(ctx, req)
|
return c.invokeServiceWithRequest(ctx, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractMethodAndQuery(name string) (method, query string) {
|
||||||
|
splitStr := strings.SplitN(name, "?", 2)
|
||||||
|
method = splitStr[0]
|
||||||
|
if len(splitStr) == 2 {
|
||||||
|
query = splitStr[1]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -35,14 +35,23 @@ func TestInvokeMethodWithContent(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotNil(t, resp)
|
assert.NotNil(t, resp)
|
||||||
assert.Equal(t, string(resp), data)
|
assert.Equal(t, string(resp), data)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("with content, method contains querystring", func(t *testing.T) {
|
||||||
|
content := &DataContent{
|
||||||
|
ContentType: "text/plain",
|
||||||
|
Data: []byte(data),
|
||||||
|
}
|
||||||
|
resp, err := testClient.InvokeMethodWithContent(ctx, "test", "fn?foo=bar&url=http://dapr.io", "get", content)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.NotNil(t, resp)
|
||||||
|
assert.Equal(t, string(resp), data)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("without content", func(t *testing.T) {
|
t.Run("without content", func(t *testing.T) {
|
||||||
resp, err := testClient.InvokeMethod(ctx, "test", "fn", "get")
|
resp, err := testClient.InvokeMethod(ctx, "test", "fn", "get")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Nil(t, resp)
|
assert.Nil(t, resp)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("without service ID", func(t *testing.T) {
|
t.Run("without service ID", func(t *testing.T) {
|
||||||
|
@ -87,20 +96,78 @@ func TestInvokeMethodWithContent(t *testing.T) {
|
||||||
|
|
||||||
func TestVerbParsing(t *testing.T) {
|
func TestVerbParsing(t *testing.T) {
|
||||||
t.Run("valid lower case", func(t *testing.T) {
|
t.Run("valid lower case", func(t *testing.T) {
|
||||||
v := verbToHTTPExtension("post")
|
v := queryAndVerbToHTTPExtension("", "post")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, v1.HTTPExtension_POST, v.Verb)
|
assert.Equal(t, v1.HTTPExtension_POST, v.Verb)
|
||||||
|
assert.Len(t, v.Querystring, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("valid upper case", func(t *testing.T) {
|
t.Run("valid upper case", func(t *testing.T) {
|
||||||
v := verbToHTTPExtension("GET")
|
v := queryAndVerbToHTTPExtension("", "GET")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, v1.HTTPExtension_GET, v.Verb)
|
assert.Equal(t, v1.HTTPExtension_GET, v.Verb)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("invalid verb", func(t *testing.T) {
|
t.Run("invalid verb", func(t *testing.T) {
|
||||||
v := verbToHTTPExtension("BAD")
|
v := queryAndVerbToHTTPExtension("", "BAD")
|
||||||
assert.NotNil(t, v)
|
assert.NotNil(t, v)
|
||||||
assert.Equal(t, v1.HTTPExtension_NONE, v.Verb)
|
assert.Equal(t, v1.HTTPExtension_NONE, v.Verb)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("valid query", func(t *testing.T) {
|
||||||
|
v := queryAndVerbToHTTPExtension("foo=bar&url=http://dapr.io", "post")
|
||||||
|
assert.NotNil(t, v)
|
||||||
|
assert.Equal(t, v1.HTTPExtension_POST, v.Verb)
|
||||||
|
assert.Len(t, v.Querystring, 2)
|
||||||
|
assert.Equal(t, "bar", v.Querystring["foo"])
|
||||||
|
assert.Equal(t, "http://dapr.io", v.Querystring["url"])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExtractMethodAndQuery(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantMethod string
|
||||||
|
wantQuery string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"pure uri",
|
||||||
|
args{name: "method"},
|
||||||
|
"method",
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"root route method",
|
||||||
|
args{name: "/"},
|
||||||
|
"/",
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri with one query",
|
||||||
|
args{name: "method?foo=bar"},
|
||||||
|
"method",
|
||||||
|
"foo=bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri with two query",
|
||||||
|
args{name: "method?foo=bar&url=http://dapr.io"},
|
||||||
|
"method",
|
||||||
|
"foo=bar&url=http://dapr.io",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotMethod, gotQuery := extractMethodAndQuery(tt.args.name)
|
||||||
|
if gotMethod != tt.wantMethod {
|
||||||
|
t.Errorf("extractMethodAndQuery() gotMethod = %v, want %v", gotMethod, tt.wantMethod)
|
||||||
|
}
|
||||||
|
if gotQuery != tt.wantQuery {
|
||||||
|
t.Errorf("extractMethodAndQuery() gotQuery = %v, want %v", gotQuery, tt.wantQuery)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue