mirror of https://github.com/dapr/go-sdk.git
Pub, service invocation methods support structs without serialization (#104)
* added PublishEventfromStruct to client * PublishEventfromStruct refactor * updated PublishEventfromStruct description * fixed unit tests for PublicEventfromStruct * added InvokeServiceWithCustomContent service invocation method supporting structs * renamed PublishEventfromStruct to PublishEventfromCustomContent Co-authored-by: Mark Chmarny <mchmarny@users.noreply.github.com>
This commit is contained in:
parent
32dbe98dc7
commit
bd7d126b4f
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${fileDirname}",
|
||||
"env": {},
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -45,9 +45,15 @@ type Client interface {
|
|||
// InvokeServiceWithContent invokes service with content
|
||||
InvokeServiceWithContent(ctx context.Context, serviceID, method string, content *DataContent) (out []byte, err error)
|
||||
|
||||
// InvokeServiceWithCustomContent invokes service with custom content (struct + content type).
|
||||
InvokeServiceWithCustomContent(ctx context.Context, serviceID, method string, contentType string, content interface{}) (out []byte, err error)
|
||||
|
||||
// PublishEvent pubishes data onto topic in specific pubsub component.
|
||||
PublishEvent(ctx context.Context, component, topic string, in []byte) error
|
||||
|
||||
// PublishEventfromCustomContent serializes an struct and pubishes its contents as data (JSON) onto topic in specific pubsub component.
|
||||
PublishEventfromCustomContent(ctx context.Context, component, topic string, in interface{}) error
|
||||
|
||||
// GetSecret retreaves preconfigred secret from specified store using key.
|
||||
GetSecret(ctx context.Context, store, key string, meta map[string]string) (out map[string]string, err error)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package client
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
v1 "github.com/dapr/go-sdk/dapr/proto/common/v1"
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
|
|
@ -83,3 +84,39 @@ func (c *GRPCClient) InvokeServiceWithContent(ctx context.Context, serviceID, me
|
|||
|
||||
return c.invokeServiceWithRequest(ctx, req)
|
||||
}
|
||||
|
||||
// InvokeServiceWithCustomContent invokes service with custom content (struct + content type).
|
||||
func (c *GRPCClient) InvokeServiceWithCustomContent(ctx context.Context, serviceID, method string, contentType string, content interface{}) (out []byte, err error) {
|
||||
if serviceID == "" {
|
||||
return nil, errors.New("serviceID is required")
|
||||
}
|
||||
if method == "" {
|
||||
return nil, errors.New("method name is required")
|
||||
}
|
||||
if contentType == "" {
|
||||
return nil, errors.New("content type required")
|
||||
}
|
||||
if content == nil {
|
||||
return nil, errors.New("content required")
|
||||
}
|
||||
|
||||
contentData, err := json.Marshal(content)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(err, "error serializing input struct")
|
||||
}
|
||||
|
||||
req := &pb.InvokeServiceRequest{
|
||||
Id: serviceID,
|
||||
Message: &v1.InvokeRequest{
|
||||
Method: method,
|
||||
Data: &anypb.Any{Value: contentData},
|
||||
ContentType: contentType,
|
||||
HttpExtension: &v1.HTTPExtension{
|
||||
Verb: v1.HTTPExtension_POST,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return c.invokeServiceWithRequest(ctx, req)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,20 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type _testStructwithText struct {
|
||||
Key1, Key2 string
|
||||
}
|
||||
|
||||
type _testStructwithTextandNumbers struct {
|
||||
Key1 string
|
||||
Key2 int
|
||||
}
|
||||
|
||||
type _testStructwithSlices struct {
|
||||
Key1 []string
|
||||
Key2 []int
|
||||
}
|
||||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestInvokeServiceWithContent$
|
||||
|
||||
func TestInvokeServiceWithContent(t *testing.T) {
|
||||
|
|
@ -31,4 +45,31 @@ func TestInvokeServiceWithContent(t *testing.T) {
|
|||
assert.Nil(t, resp)
|
||||
|
||||
})
|
||||
|
||||
t.Run("from struct with text", func(t *testing.T) {
|
||||
testdata := _testCustomContentwithText{
|
||||
Key1: "value1",
|
||||
Key2: "value2",
|
||||
}
|
||||
_, err := testClient.InvokeServiceWithCustomContent(ctx, "test", "fn", "text/plain", testdata)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("from struct with text and numbers", func(t *testing.T) {
|
||||
testdata := _testCustomContentwithTextandNumbers{
|
||||
Key1: "value1",
|
||||
Key2: 2500,
|
||||
}
|
||||
_, err := testClient.InvokeServiceWithCustomContent(ctx, "test", "fn", "text/plain", testdata)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("from struct with slices", func(t *testing.T) {
|
||||
testdata := _testCustomContentwithSlices{
|
||||
Key1: []string{"value1", "value2", "value3"},
|
||||
Key2: []int{25, 40, 600},
|
||||
}
|
||||
_, err := testClient.InvokeServiceWithCustomContent(ctx, "test", "fn", "text/plain", testdata)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package client
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
pb "github.com/dapr/go-sdk/dapr/proto/runtime/v1"
|
||||
"github.com/pkg/errors"
|
||||
|
|
@ -29,3 +30,34 @@ func (c *GRPCClient) PublishEvent(ctx context.Context, component, topic string,
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PublishEventfromCustomContent serializes an struct and pubishes its contents as data (JSON) onto topic in specific pubsub component.
|
||||
func (c *GRPCClient) PublishEventfromCustomContent(ctx context.Context, component, topic string, in interface{}) error {
|
||||
|
||||
if topic == "" {
|
||||
return errors.New("topic name required")
|
||||
}
|
||||
if component == "" {
|
||||
return errors.New("component name required")
|
||||
}
|
||||
|
||||
bytes, err := json.Marshal(in)
|
||||
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "error serializing input struct")
|
||||
}
|
||||
|
||||
envelop := &pb.PublishEventRequest{
|
||||
PubsubName: component,
|
||||
Topic: topic,
|
||||
Data: bytes,
|
||||
}
|
||||
|
||||
_, err = c.protoClient.PublishEvent(c.withAuthToken(ctx), envelop)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error publishing event unto %s topic", topic)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,20 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type _testCustomContentwithText struct {
|
||||
Key1, Key2 string
|
||||
}
|
||||
|
||||
type _testCustomContentwithTextandNumbers struct {
|
||||
Key1 string
|
||||
Key2 int
|
||||
}
|
||||
|
||||
type _testCustomContentwithSlices struct {
|
||||
Key1 []string
|
||||
Key2 []int
|
||||
}
|
||||
|
||||
// go test -timeout 30s ./client -count 1 -run ^TestPublishEvent$
|
||||
func TestPublishEvent(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
|
@ -25,4 +39,31 @@ func TestPublishEvent(t *testing.T) {
|
|||
err := testClient.PublishEvent(ctx, "messagebus", "", []byte("ping"))
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
|
||||
t.Run("from struct with text", func(t *testing.T) {
|
||||
testdata := _testStructwithText{
|
||||
Key1: "value1",
|
||||
Key2: "value2",
|
||||
}
|
||||
err := testClient.PublishEventfromCustomContent(ctx, "messagebus", "test", testdata)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("from struct with text and numbers", func(t *testing.T) {
|
||||
testdata := _testStructwithTextandNumbers{
|
||||
Key1: "value1",
|
||||
Key2: 2500,
|
||||
}
|
||||
err := testClient.PublishEventfromCustomContent(ctx, "messagebus", "test", testdata)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("from struct with slices", func(t *testing.T) {
|
||||
testdata := _testStructwithSlices{
|
||||
Key1: []string{"value1", "value2", "value3"},
|
||||
Key2: []int{25, 40, 600},
|
||||
}
|
||||
err := testClient.PublishEventfromCustomContent(ctx, "messagebus", "test", testdata)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue