new feature: use grpcurl as an offline tool to convert JSON into proto
This commit is contained in:
parent
b953ea196a
commit
03c21551f3
|
|
@ -152,6 +152,13 @@ var (
|
|||
permitted if they are both set to the same value, to increase backwards
|
||||
compatibility with earlier releases that allowed both to be set).`))
|
||||
reflection = optionalBoolFlag{val: true}
|
||||
|
||||
convertMessage = flags.String("convert-message", "", prettify(`
|
||||
Turns the tool into an offline converter; the proto representation of
|
||||
the JSON input will be printed to the standard output.
|
||||
This parameter should specify the fully qualified name of the protobuf
|
||||
message definition (e.g. some.service/ReadRequest).
|
||||
`))
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -302,27 +309,34 @@ func main() {
|
|||
|
||||
args := flags.Args()
|
||||
|
||||
if len(args) == 0 {
|
||||
fail(nil, "Too few arguments.")
|
||||
}
|
||||
var target string
|
||||
if args[0] != "list" && args[0] != "describe" {
|
||||
target = args[0]
|
||||
args = args[1:]
|
||||
}
|
||||
convertJson := *convertMessage != ""
|
||||
|
||||
if len(args) == 0 {
|
||||
fail(nil, "Too few arguments.")
|
||||
}
|
||||
var target string
|
||||
var list, describe, invoke bool
|
||||
if args[0] == "list" {
|
||||
list = true
|
||||
args = args[1:]
|
||||
} else if args[0] == "describe" {
|
||||
describe = true
|
||||
args = args[1:]
|
||||
if len(args) != 0 {
|
||||
if convertJson {
|
||||
fail(nil, "Target service should be omitted for offline conversions.")
|
||||
}
|
||||
|
||||
if args[0] != "list" && args[0] != "describe" {
|
||||
target = args[0]
|
||||
args = args[1:]
|
||||
}
|
||||
|
||||
if args[0] == "list" {
|
||||
list = true
|
||||
args = args[1:]
|
||||
} else if args[0] == "describe" {
|
||||
describe = true
|
||||
args = args[1:]
|
||||
} else {
|
||||
invoke = true
|
||||
}
|
||||
|
||||
} else {
|
||||
invoke = true
|
||||
if !convertJson {
|
||||
fail(nil, "Too few arguments.")
|
||||
}
|
||||
}
|
||||
|
||||
verbosityLevel := 0
|
||||
|
|
@ -341,7 +355,7 @@ func main() {
|
|||
symbol = args[0]
|
||||
args = args[1:]
|
||||
} else {
|
||||
if *data != "" {
|
||||
if *data != "" && !convertJson {
|
||||
warn("The -d argument is not used with 'list' or 'describe' verb.")
|
||||
}
|
||||
if len(rpcHeaders) > 0 {
|
||||
|
|
@ -675,9 +689,10 @@ func main() {
|
|||
|
||||
} else {
|
||||
// Invoke an RPC
|
||||
if cc == nil {
|
||||
if cc == nil && !convertJson {
|
||||
cc = dial()
|
||||
}
|
||||
|
||||
var in io.Reader
|
||||
if *data == "@" {
|
||||
in = os.Stdin
|
||||
|
|
@ -698,6 +713,16 @@ func main() {
|
|||
if err != nil {
|
||||
fail(err, "Failed to construct request parser and formatter for %q", *format)
|
||||
}
|
||||
|
||||
if convertJson {
|
||||
proto, err:= grpcurl.ConvertMessage(descSource, *convertMessage, rf.Next)
|
||||
if err != nil {
|
||||
fail(err, "Error converting message %q", *convertMessage)
|
||||
}
|
||||
os.Stdout.Write(proto)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
h := &grpcurl.DefaultEventHandler{
|
||||
Out: os.Stdout,
|
||||
Formatter: formatter,
|
||||
|
|
|
|||
58
invoke.go
58
invoke.go
|
|
@ -119,18 +119,7 @@ func InvokeRPC(ctx context.Context, source DescriptorSource, ch grpcdynamic.Chan
|
|||
|
||||
handler.OnResolveMethod(mtd)
|
||||
|
||||
// we also download any applicable extensions so we can provide full support for parsing user-provided data
|
||||
var ext dynamic.ExtensionRegistry
|
||||
alreadyFetched := map[string]bool{}
|
||||
if err = fetchAllExtensions(source, &ext, mtd.GetInputType(), alreadyFetched); err != nil {
|
||||
return fmt.Errorf("error resolving server extensions for message %s: %v", mtd.GetInputType().GetFullyQualifiedName(), err)
|
||||
}
|
||||
if err = fetchAllExtensions(source, &ext, mtd.GetOutputType(), alreadyFetched); err != nil {
|
||||
return fmt.Errorf("error resolving server extensions for message %s: %v", mtd.GetOutputType().GetFullyQualifiedName(), err)
|
||||
}
|
||||
|
||||
msgFactory := dynamic.NewMessageFactoryWithExtensionRegistry(&ext)
|
||||
req := msgFactory.NewMessage(mtd.GetInputType())
|
||||
req, msgFactory, err:= getExtensions(source, mtd.GetInputType())
|
||||
|
||||
handler.OnSendHeaders(md)
|
||||
ctx = metadata.NewOutgoingContext(ctx, md)
|
||||
|
|
@ -403,3 +392,48 @@ func parseSymbol(svcAndMethod string) (string, string) {
|
|||
}
|
||||
return svcAndMethod[:pos], svcAndMethod[pos+1:]
|
||||
}
|
||||
|
||||
func ConvertMessage(source DescriptorSource, messageFullName string, requestData RequestSupplier) ([]byte, error) {
|
||||
dsc, err := source.FindSymbol(messageFullName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
md, ok := dsc.(*desc.MessageDescriptor)
|
||||
if ! ok {
|
||||
return nil, fmt.Errorf("%q should point to a message descriptor instead of %d:", messageFullName, md)
|
||||
}
|
||||
|
||||
req, _, err:= getExtensions(source, md)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = requestData(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
re, err:= proto.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return re, nil
|
||||
}
|
||||
|
||||
func getExtensions(source DescriptorSource, md *desc.MessageDescriptor) (req proto.Message, msgFactory *dynamic.MessageFactory, err error) {
|
||||
// we also download any applicable extensions so we can provide full support for parsing user-provided data
|
||||
var ext dynamic.ExtensionRegistry
|
||||
alreadyFetched := map[string]bool{}
|
||||
if err = fetchAllExtensions(source, &ext, md, alreadyFetched); err != nil {
|
||||
return nil, nil, fmt.Errorf("error resolving server extensions for message %s: %v", md.GetFullyQualifiedName(), err)
|
||||
}
|
||||
if err = fetchAllExtensions(source, &ext, md, alreadyFetched); err != nil {
|
||||
return nil, nil, fmt.Errorf("error resolving server extensions for message %s: %v", md.GetFullyQualifiedName(), err)
|
||||
}
|
||||
|
||||
msgFactory = dynamic.NewMessageFactoryWithExtensionRegistry(&ext)
|
||||
req = msgFactory.NewMessage(md)
|
||||
|
||||
return req, msgFactory, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue