move JSON marshalling into cmd, add `-emit-defaults` flag

Signed-off-by: Stephan Renatus <srenatus@chef.io>
This commit is contained in:
Stephan Renatus 2018-02-05 15:22:38 +01:00
parent c7bfc60d53
commit 3621f4c2d7
3 changed files with 26 additions and 50 deletions

View File

@ -12,6 +12,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
"github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/grpcreflect" "github.com/jhump/protoreflect/grpcreflect"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -64,6 +66,8 @@ var (
`The maximum total time the operation can take. This is useful for `The maximum total time the operation can take. This is useful for
preventing batch jobs that use grpcurl from hanging due to slow or bad preventing batch jobs that use grpcurl from hanging due to slow or bad
network links or due to incorrect stream method usage.`) network links or due to incorrect stream method usage.`)
emitDefaults = flag.Bool("emit-defaults", false,
`Emit default values from JSON-encoded responses.`)
verbose = flag.Bool("v", false, verbose = flag.Bool("v", false,
`Enable verbose output.`) `Enable verbose output.`)
) )
@ -442,12 +446,17 @@ func (*handler) OnReceiveHeaders(md metadata.MD) {
} }
} }
func (h *handler) OnReceiveResponse(rsp json.RawMessage) { func (h *handler) OnReceiveResponse(resp proto.Message) {
h.respCount++ h.respCount++
if *verbose { if *verbose {
fmt.Print("\nResponse contents:\n") fmt.Print("\nResponse contents:\n")
} }
fmt.Println(string(rsp)) jsm := jsonpb.Marshaler{EmitDefaults: *emitDefaults, Indent: " "}
respStr, err := jsm.MarshalToString(resp)
if err != nil {
fail(err, "failed to generate JSON form of response message")
}
fmt.Println(respStr)
} }
func (h *handler) OnReceiveTrailers(stat *status.Status, md metadata.MD) { func (h *handler) OnReceiveTrailers(stat *status.Status, md metadata.MD) {

View File

@ -263,7 +263,7 @@ type InvocationEventHandler interface {
// OnReceiveHeaders is called when response headers have been received. // OnReceiveHeaders is called when response headers have been received.
OnReceiveHeaders(metadata.MD) OnReceiveHeaders(metadata.MD)
// OnReceiveResponse is called for each response message received. // OnReceiveResponse is called for each response message received.
OnReceiveResponse(json.RawMessage) OnReceiveResponse(proto.Message)
// OnReceiveTrailers is called when response trailers and final RPC status have been received. // OnReceiveTrailers is called when response trailers and final RPC status have been received.
OnReceiveTrailers(*status.Status, metadata.MD) OnReceiveTrailers(*status.Status, metadata.MD)
} }
@ -384,14 +384,8 @@ func invokeUnary(ctx context.Context, stub grpcdynamic.Stub, md *desc.MethodDesc
handler.OnReceiveHeaders(respHeaders) handler.OnReceiveHeaders(respHeaders)
var respStr string
if stat.Code() == codes.OK { if stat.Code() == codes.OK {
jsm := jsonpb.Marshaler{EmitDefaults: true, Indent: " "} handler.OnReceiveResponse(resp)
respStr, err = jsm.MarshalToString(resp)
if err != nil {
return fmt.Errorf("failed to generate JSON form of response message: %v", err)
}
handler.OnReceiveResponse(json.RawMessage(respStr))
} }
handler.OnReceiveTrailers(stat, respTrailers) handler.OnReceiveTrailers(stat, respTrailers)
@ -447,14 +441,8 @@ func invokeClientStream(ctx context.Context, stub grpcdynamic.Stub, md *desc.Met
handler.OnReceiveHeaders(respHeaders) handler.OnReceiveHeaders(respHeaders)
} }
var respStr string
if stat.Code() == codes.OK { if stat.Code() == codes.OK {
jsm := jsonpb.Marshaler{EmitDefaults: true, Indent: " "} handler.OnReceiveResponse(resp)
respStr, err = jsm.MarshalToString(resp)
if err != nil {
return fmt.Errorf("failed to generate JSON form of response message: %v", err)
}
handler.OnReceiveResponse(json.RawMessage(respStr))
} }
handler.OnReceiveTrailers(stat, str.Trailer()) handler.OnReceiveTrailers(stat, str.Trailer())
@ -502,12 +490,7 @@ func invokeServerStream(ctx context.Context, stub grpcdynamic.Stub, md *desc.Met
} }
break break
} }
jsm := jsonpb.Marshaler{EmitDefaults: true, Indent: " "} handler.OnReceiveResponse(resp)
respStr, err := jsm.MarshalToString(resp)
if err != nil {
return fmt.Errorf("failed to generate JSON form of response message: %v", err)
}
handler.OnReceiveResponse(json.RawMessage(respStr))
} }
stat, ok := status.FromError(err) stat, ok := status.FromError(err)
@ -588,13 +571,7 @@ func invokeBidi(ctx context.Context, cancel context.CancelFunc, stub grpcdynamic
} }
break break
} }
jsm := jsonpb.Marshaler{EmitDefaults: true, Indent: " "} handler.OnReceiveResponse(resp)
respStr, err := jsm.MarshalToString(resp)
if err != nil {
return fmt.Errorf("failed to generate JSON form of response message: %v", err)
}
handler.OnReceiveResponse(json.RawMessage(respStr))
} }
if se, ok := sendErr.Load().(error); ok && se != io.EOF { if se, ok := sendErr.Load().(error); ok && se != io.EOF {

View File

@ -260,20 +260,6 @@ const (
"payload": { "payload": {
"body": "SXQncyBCdXNpbmVzcyBUaW1l" "body": "SXQncyBCdXNpbmVzcyBUaW1l"
} }
}`
fullResponse1 = `{
"payload": {
"type": "COMPRESSABLE",
"body": "SXQncyBCdXNpbmVzcyBUaW1l"
},
"username": "",
"oauthScope": ""
}`
response1 = `{
"payload": {
"type": "COMPRESSABLE",
"body": "SXQncyBCdXNpbmVzcyBUaW1l"
}
}` }`
payload2 = `{ payload2 = `{
"payload": { "payload": {
@ -306,7 +292,7 @@ func doTestUnary(t *testing.T, cc *grpc.ClientConn, source DescriptorSource) {
} }
if h.check(t, "grpc.testing.TestService.UnaryCall", codes.OK, 1, 1) { if h.check(t, "grpc.testing.TestService.UnaryCall", codes.OK, 1, 1) {
if h.respMessages[0] != fullResponse1 { if h.respMessages[0] != payload1 {
t.Errorf("unexpected response from RPC: expecting %s; got %s", payload1, h.respMessages[0]) t.Errorf("unexpected response from RPC: expecting %s; got %s", payload1, h.respMessages[0])
} }
} }
@ -438,7 +424,6 @@ func TestHalfDuplexStreamReflect(t *testing.T) {
func doTestHalfDuplexStream(t *testing.T, cc *grpc.ClientConn, source DescriptorSource) { func doTestHalfDuplexStream(t *testing.T, cc *grpc.ClientConn, source DescriptorSource) {
reqs := []string{payload1, payload2, payload3} reqs := []string{payload1, payload2, payload3}
resps := []string{response1, payload2, payload3}
// Success // Success
h := &handler{reqMessages: reqs} h := &handler{reqMessages: reqs}
@ -449,8 +434,8 @@ func doTestHalfDuplexStream(t *testing.T, cc *grpc.ClientConn, source Descriptor
if h.check(t, "grpc.testing.TestService.HalfDuplexCall", codes.OK, 3, 3) { if h.check(t, "grpc.testing.TestService.HalfDuplexCall", codes.OK, 3, 3) {
for i, resp := range h.respMessages { for i, resp := range h.respMessages {
if resp != resps[i] { if resp != reqs[i] {
t.Errorf("unexpected response %d from RPC:\nexpecting %q\ngot %q", i, resps[i], resp) t.Errorf("unexpected response %d from RPC:\nexpecting %q\ngot %q", i, reqs[i], resp)
} }
} }
} }
@ -591,8 +576,13 @@ func (h *handler) OnReceiveHeaders(md metadata.MD) {
h.respHeaders = md h.respHeaders = md
} }
func (h *handler) OnReceiveResponse(msg json.RawMessage) { func (h *handler) OnReceiveResponse(msg proto.Message) {
h.respMessages = append(h.respMessages, string(msg)) jsm := jsonpb.Marshaler{Indent: " "}
respStr, err := jsm.MarshalToString(msg)
if err != nil {
panic(fmt.Errorf("failed to generate JSON form of response message: %v", err))
}
h.respMessages = append(h.respMessages, respStr)
} }
func (h *handler) OnReceiveTrailers(stat *status.Status, md metadata.MD) { func (h *handler) OnReceiveTrailers(stat *status.Status, md metadata.MD) {