Skip to content

Commit b6b6d06

Browse files
feat: Invoke will extract querystring from method (#127)
Co-authored-by: 李锐 <[email protected]>
1 parent f2b03d2 commit b6b6d06

File tree

3 files changed

+100
-12
lines changed

3 files changed

+100
-12
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
# IDE
99
.vscode
10+
.idea
1011

1112
# Test binary, build with `go test -c`
1213
*.test

client/invoke.go

+28-8
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,16 @@ func (c *GRPCClient) invokeServiceWithRequest(ctx context.Context, req *pb.Invok
3939
return
4040
}
4141

42-
func verbToHTTPExtension(verb string) *v1.HTTPExtension {
42+
func queryAndVerbToHTTPExtension(query string, verb string) *v1.HTTPExtension {
43+
var queryMap = map[string]string{}
44+
for _, item := range strings.Split(query, "&") {
45+
kv := strings.Split(item, "=")
46+
if len(kv) == 2 {
47+
queryMap[kv[0]] = kv[1]
48+
}
49+
}
4350
if v, ok := v1.HTTPExtension_Verb_value[strings.ToUpper(verb)]; ok {
44-
return &v1.HTTPExtension{Verb: v1.HTTPExtension_Verb(v)}
51+
return &v1.HTTPExtension{Verb: v1.HTTPExtension_Verb(v), Querystring: queryMap}
4552
}
4653
return &v1.HTTPExtension{Verb: v1.HTTPExtension_NONE}
4754
}
@@ -64,11 +71,12 @@ func (c *GRPCClient) InvokeMethod(ctx context.Context, appID, methodName, verb s
6471
if err := hasRequiredInvokeArgs(appID, methodName, verb); err != nil {
6572
return nil, errors.Wrap(err, "missing required parameter")
6673
}
74+
method, query := extractMethodAndQuery(methodName)
6775
req := &pb.InvokeServiceRequest{
6876
Id: appID,
6977
Message: &v1.InvokeRequest{
70-
Method: methodName,
71-
HttpExtension: verbToHTTPExtension(verb),
78+
Method: method,
79+
HttpExtension: queryAndVerbToHTTPExtension(query, verb),
7280
},
7381
}
7482
return c.invokeServiceWithRequest(ctx, req)
@@ -82,13 +90,14 @@ func (c *GRPCClient) InvokeMethodWithContent(ctx context.Context, appID, methodN
8290
if content == nil {
8391
return nil, errors.New("content required")
8492
}
93+
method, query := extractMethodAndQuery(methodName)
8594
req := &pb.InvokeServiceRequest{
8695
Id: appID,
8796
Message: &v1.InvokeRequest{
88-
Method: methodName,
97+
Method: method,
8998
Data: &anypb.Any{Value: content.Data},
9099
ContentType: content.ContentType,
91-
HttpExtension: verbToHTTPExtension(verb),
100+
HttpExtension: queryAndVerbToHTTPExtension(query, verb),
92101
},
93102
}
94103
return c.invokeServiceWithRequest(ctx, req)
@@ -111,15 +120,26 @@ func (c *GRPCClient) InvokeMethodWithCustomContent(ctx context.Context, appID, m
111120
return nil, errors.WithMessage(err, "error serializing input struct")
112121
}
113122

123+
method, query := extractMethodAndQuery(methodName)
124+
114125
req := &pb.InvokeServiceRequest{
115126
Id: appID,
116127
Message: &v1.InvokeRequest{
117-
Method: methodName,
128+
Method: method,
118129
Data: &anypb.Any{Value: contentData},
119130
ContentType: contentType,
120-
HttpExtension: verbToHTTPExtension(verb),
131+
HttpExtension: queryAndVerbToHTTPExtension(query, verb),
121132
},
122133
}
123134

124135
return c.invokeServiceWithRequest(ctx, req)
125136
}
137+
138+
func extractMethodAndQuery(name string) (method, query string) {
139+
splitStr := strings.SplitN(name, "?", 2)
140+
method = splitStr[0]
141+
if len(splitStr) == 2 {
142+
query = splitStr[1]
143+
}
144+
return
145+
}

client/invoke_test.go

+71-4
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,23 @@ func TestInvokeMethodWithContent(t *testing.T) {
3535
assert.Nil(t, err)
3636
assert.NotNil(t, resp)
3737
assert.Equal(t, string(resp), data)
38+
})
3839

40+
t.Run("with content, method contains querystring", func(t *testing.T) {
41+
content := &DataContent{
42+
ContentType: "text/plain",
43+
Data: []byte(data),
44+
}
45+
resp, err := testClient.InvokeMethodWithContent(ctx, "test", "fn?foo=bar&url=http://dapr.io", "get", content)
46+
assert.Nil(t, err)
47+
assert.NotNil(t, resp)
48+
assert.Equal(t, string(resp), data)
3949
})
4050

4151
t.Run("without content", func(t *testing.T) {
4252
resp, err := testClient.InvokeMethod(ctx, "test", "fn", "get")
4353
assert.Nil(t, err)
4454
assert.Nil(t, resp)
45-
4655
})
4756

4857
t.Run("without service ID", func(t *testing.T) {
@@ -87,20 +96,78 @@ func TestInvokeMethodWithContent(t *testing.T) {
8796

8897
func TestVerbParsing(t *testing.T) {
8998
t.Run("valid lower case", func(t *testing.T) {
90-
v := verbToHTTPExtension("post")
99+
v := queryAndVerbToHTTPExtension("", "post")
91100
assert.NotNil(t, v)
92101
assert.Equal(t, v1.HTTPExtension_POST, v.Verb)
102+
assert.Len(t, v.Querystring, 0)
93103
})
94104

95105
t.Run("valid upper case", func(t *testing.T) {
96-
v := verbToHTTPExtension("GET")
106+
v := queryAndVerbToHTTPExtension("", "GET")
97107
assert.NotNil(t, v)
98108
assert.Equal(t, v1.HTTPExtension_GET, v.Verb)
99109
})
100110

101111
t.Run("invalid verb", func(t *testing.T) {
102-
v := verbToHTTPExtension("BAD")
112+
v := queryAndVerbToHTTPExtension("", "BAD")
103113
assert.NotNil(t, v)
104114
assert.Equal(t, v1.HTTPExtension_NONE, v.Verb)
105115
})
116+
117+
t.Run("valid query", func(t *testing.T) {
118+
v := queryAndVerbToHTTPExtension("foo=bar&url=http://dapr.io", "post")
119+
assert.NotNil(t, v)
120+
assert.Equal(t, v1.HTTPExtension_POST, v.Verb)
121+
assert.Len(t, v.Querystring, 2)
122+
assert.Equal(t, "bar", v.Querystring["foo"])
123+
assert.Equal(t, "http://dapr.io", v.Querystring["url"])
124+
})
125+
}
126+
127+
func TestExtractMethodAndQuery(t *testing.T) {
128+
type args struct {
129+
name string
130+
}
131+
tests := []struct {
132+
name string
133+
args args
134+
wantMethod string
135+
wantQuery string
136+
}{
137+
{
138+
"pure uri",
139+
args{name: "method"},
140+
"method",
141+
"",
142+
},
143+
{
144+
"root route method",
145+
args{name: "/"},
146+
"/",
147+
"",
148+
},
149+
{
150+
"uri with one query",
151+
args{name: "method?foo=bar"},
152+
"method",
153+
"foo=bar",
154+
},
155+
{
156+
"uri with two query",
157+
args{name: "method?foo=bar&url=http://dapr.io"},
158+
"method",
159+
"foo=bar&url=http://dapr.io",
160+
},
161+
}
162+
for _, tt := range tests {
163+
t.Run(tt.name, func(t *testing.T) {
164+
gotMethod, gotQuery := extractMethodAndQuery(tt.args.name)
165+
if gotMethod != tt.wantMethod {
166+
t.Errorf("extractMethodAndQuery() gotMethod = %v, want %v", gotMethod, tt.wantMethod)
167+
}
168+
if gotQuery != tt.wantQuery {
169+
t.Errorf("extractMethodAndQuery() gotQuery = %v, want %v", gotQuery, tt.wantQuery)
170+
}
171+
})
172+
}
106173
}

0 commit comments

Comments
 (0)