From 9d43ed0621e4c9549a3d92a53dedc5dd57e9bec2 Mon Sep 17 00:00:00 2001 From: Viacheslav Rostovtsev <58152857+viacheslav-rostovtsev@users.noreply.github.com> Date: Tue, 26 Jul 2022 18:09:33 -0700 Subject: [PATCH] feat: add binding testing and multiple bindings test data to compliance service (#1150) --- client/compliance_client.go | 15 + cmd/gapic-showcase/compliance_suite_test.go | 40 ++ cmd/gapic-showcase/endpoint_test.go | 11 +- cmd/gapic-showcase/repeat-data-body-info.go | 8 + cmd/gapic-showcase/repeat-data-body-patch.go | 8 + cmd/gapic-showcase/repeat-data-body-put.go | 8 + cmd/gapic-showcase/repeat-data-body.go | 8 + .../repeat-data-path-resource.go | 8 + .../repeat-data-path-trailing-resource.go | 8 + cmd/gapic-showcase/repeat-data-query.go | 8 + cmd/gapic-showcase/repeat-data-simple-path.go | 8 + .../google/showcase/v1beta1/compliance.proto | 9 + server/genproto/compliance.pb.go | 489 ++++++++++-------- server/genrest/compliance.go | 87 +++- server/genrest/echo.go | 19 +- server/genrest/genrest.go | 1 + server/genrest/identity.go | 16 +- server/genrest/messaging.go | 52 +- server/genrest/operations.go | 13 +- server/genrest/sequenceservice.go | 10 +- .../genrest/showcase-rest-sample-response.txt | 6 +- server/genrest/testing.go | 25 +- server/services/compliance_service.go | 29 +- server/services/compliance_service_test.go | 83 ++- server/services/compliance_suite.json | 44 ++ util/genrest/goviewcreator.go | 4 +- util/genrest/resttools/constants.go | 5 + 27 files changed, 728 insertions(+), 294 deletions(-) diff --git a/client/compliance_client.go b/client/compliance_client.go index 726fc8ce7..f898b1d3f 100644 --- a/client/compliance_client.go +++ b/client/compliance_client.go @@ -840,6 +840,9 @@ func (c *complianceRESTClient) RepeatDataBodyInfo(ctx context.Context, req *genp if req.GetFInt64() != 0 { params.Add("fInt64", fmt.Sprintf("%v", req.GetFInt64())) } + if req != nil && req.IntendedBindingUri != nil { + params.Add("intendedBindingUri", fmt.Sprintf("%v", req.GetIntendedBindingUri())) + } if req.GetName() != "" { params.Add("name", fmt.Sprintf("%v", req.GetName())) } @@ -1079,6 +1082,9 @@ func (c *complianceRESTClient) RepeatDataQuery(ctx context.Context, req *genprot if req.GetInfo() != nil && req.GetInfo().PString != nil { params.Add("info.pString", fmt.Sprintf("%v", req.GetInfo().GetPString())) } + if req != nil && req.IntendedBindingUri != nil { + params.Add("intendedBindingUri", fmt.Sprintf("%v", req.GetIntendedBindingUri())) + } if req.GetName() != "" { params.Add("name", fmt.Sprintf("%v", req.GetName())) } @@ -1304,6 +1310,9 @@ func (c *complianceRESTClient) RepeatDataSimplePath(ctx context.Context, req *ge if req.GetInfo() != nil && req.GetInfo().PString != nil { params.Add("info.pString", fmt.Sprintf("%v", req.GetInfo().GetPString())) } + if req != nil && req.IntendedBindingUri != nil { + params.Add("intendedBindingUri", fmt.Sprintf("%v", req.GetIntendedBindingUri())) + } if req.GetName() != "" { params.Add("name", fmt.Sprintf("%v", req.GetName())) } @@ -1535,6 +1544,9 @@ func (c *complianceRESTClient) RepeatDataPathResource(ctx context.Context, req * if req.GetInfo() != nil && req.GetInfo().PString != nil { params.Add("info.pString", fmt.Sprintf("%v", req.GetInfo().GetPString())) } + if req != nil && req.IntendedBindingUri != nil { + params.Add("intendedBindingUri", fmt.Sprintf("%v", req.GetIntendedBindingUri())) + } if req.GetName() != "" { params.Add("name", fmt.Sprintf("%v", req.GetName())) } @@ -1769,6 +1781,9 @@ func (c *complianceRESTClient) RepeatDataPathTrailingResource(ctx context.Contex if req.GetInfo() != nil && req.GetInfo().PString != nil { params.Add("info.pString", fmt.Sprintf("%v", req.GetInfo().GetPString())) } + if req != nil && req.IntendedBindingUri != nil { + params.Add("intendedBindingUri", fmt.Sprintf("%v", req.GetIntendedBindingUri())) + } if req.GetName() != "" { params.Add("name", fmt.Sprintf("%v", req.GetName())) } diff --git a/cmd/gapic-showcase/compliance_suite_test.go b/cmd/gapic-showcase/compliance_suite_test.go index 89f4d60ac..66bf2b1ac 100644 --- a/cmd/gapic-showcase/compliance_suite_test.go +++ b/cmd/gapic-showcase/compliance_suite_test.go @@ -217,6 +217,16 @@ func prepRepeatDataPathResourceTest(request *genproto.RepeatRequest) (verb strin name = "Compliance.RepeatDataPathResource" info := request.GetInfo() + if strings.HasPrefix(info.GetFString(), "first/") { + return prepRepeatDataPathResourceTestFirstBinding(request) + } else { + return prepRepeatDataPathResourceTestSecondBinding(request) + } +} + +func prepRepeatDataPathResourceTestFirstBinding(request *genproto.RepeatRequest) (verb string, name string, path string, body string, err error) { + name = "Compliance.RepeatDataPathResource" + info := request.GetInfo() pathParts := []string{} nonQueryParamNames := map[string]bool{} @@ -243,6 +253,35 @@ func prepRepeatDataPathResourceTest(request *genproto.RepeatRequest) (verb strin return "GET", name, path + queryString, body, err } +func prepRepeatDataPathResourceTestSecondBinding(request *genproto.RepeatRequest) (verb string, name string, path string, body string, err error) { + name = "Compliance.RepeatDataPathResource" + info := request.GetInfo() + pathParts := []string{} + nonQueryParamNames := map[string]bool{} + + for _, part := range []struct { + name string + format string + value interface{} + requiredPrefix string + }{ + {"f_child.f_string", "%s", info.GetFChild().GetFString(), "first/"}, + {"f_string", "%s", info.GetFString(), "second/"}, + {"f_bool", "bool/%t", info.GetFBool(), ""}, + } { + if len(part.requiredPrefix) > 0 && !strings.HasPrefix(part.value.(string), part.requiredPrefix) { + err = fmt.Errorf("expected value of %q to begin with %q; got %q", part.name, part.requiredPrefix, part.value) + return + } + pathParts = append(pathParts, url.PathEscape(fmt.Sprintf(part.format, part.value))) + nonQueryParamNames["info."+part.name] = true + } + path = fmt.Sprintf("/v1beta1/repeat/%s:childfirstpathresource", strings.Join(pathParts, "/")) + + queryString := prepRepeatDataTestsQueryString(request, nonQueryParamNames) + return "GET", name, path + queryString, body, err +} + func prepRepeatDataPathTrailingResourceTest(request *genproto.RepeatRequest) (verb string, name string, path string, body string, err error) { name = "Compliance.RepeatDataPathTrailingResource" info := request.GetInfo() @@ -294,6 +333,7 @@ func prepRepeatDataTestsQueryParams(request *genproto.RepeatRequest, exclude map // Top-level fields addParam("server_verify", request.GetServerVerify(), "true") addParam("name", len(request.GetName()) > 0, url.QueryEscape(request.GetName())) + addParam("intended_binding_uri", request.IntendedBindingUri != nil, url.QueryEscape(request.GetIntendedBindingUri())) addParam("f_int32", request.GetFInt32() != 0, fmt.Sprintf("%d", request.GetFInt32())) addParam("f_int64", request.GetFInt64() != 0, fmt.Sprintf("%d", request.GetFInt64())) diff --git a/cmd/gapic-showcase/endpoint_test.go b/cmd/gapic-showcase/endpoint_test.go index 3c9e53efe..cbf01956d 100644 --- a/cmd/gapic-showcase/endpoint_test.go +++ b/cmd/gapic-showcase/endpoint_test.go @@ -54,12 +54,12 @@ func TestRESTCalls(t *testing.T) { verb: "POST", path: "/v1beta1/repeat:body", body: `{"info":{"fString":"jonas^ mila"}}`, - want: `{"request":{"info":{"fString":"jonas^ mila"}}}`, + want: `{"request":{"info":{"fString":"jonas^ mila"}}, "bindingUri":"/v1beta1/repeat:body"}`, }, { verb: "GET", path: "/v1beta1/repeat:query?info.fString=jonas+mila", - want: `{"request":{"info":{"fString":"jonas mila"}}}`, + want: `{"request":{"info":{"fString":"jonas mila"}}, "bindingUri":"/v1beta1/repeat:query"}`, }, { verb: "GET", @@ -67,7 +67,7 @@ func TestRESTCalls(t *testing.T) { // TODO: Fix so that this returns an error, because `^` is not URL-escaped statusCode: 200, - want: `{"request":{"info":{"fString":"jonas^mila"}}}`, + want: `{"request":{"info":{"fString":"jonas^mila"}}, "bindingUri":"/v1beta1/repeat:query"}`, }, { verb: "GET", @@ -127,7 +127,8 @@ func TestRESTCalls(t *testing.T) { "fInt32": 0, "fInt64": "0", "fDouble": 0 - } + }, + "bindingUri":"/v1beta1/repeat:body" } `, }, @@ -174,7 +175,7 @@ func TestRESTCalls(t *testing.T) { log.Fatal(err) } if got, want := string(body), testCase.want; noSpace(got) != noSpace(want) { - t.Errorf("testcase %2d: body: got `%s`, want %s", idx, got, want) + t.Errorf("testcase %2d: body: got %q, want %q", idx, noSpace(got), noSpace(want)) t.Errorf(" request: %v", request) } jsonOptions.Restore() diff --git a/cmd/gapic-showcase/repeat-data-body-info.go b/cmd/gapic-showcase/repeat-data-body-info.go index 65bb5db60..498332854 100644 --- a/cmd/gapic-showcase/repeat-data-body-info.go +++ b/cmd/gapic-showcase/repeat-data-body-info.go @@ -56,6 +56,8 @@ var repeatDataBodyInfoInputInfoPChildPBool bool var RepeatDataBodyInfoInputInfoPChildPContinent string +var repeatDataBodyInfoInputIntendedBindingUri string + var repeatDataBodyInfoInputPInt32 int32 var repeatDataBodyInfoInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataBodyInfoCmd.Flags().BoolVar(&RepeatDataBodyInfoInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataBodyInfoCmd.Flags().StringVar(&repeatDataBodyInfoInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataBodyInfoCmd.Flags().Int32Var(&RepeatDataBodyInfoInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataBodyInfoCmd.Flags().Int64Var(&RepeatDataBodyInfoInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataBodyInfoCmd = &cobra.Command{ RepeatDataBodyInfoInput.Info.PChild.PBool = &repeatDataBodyInfoInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataBodyInfoInput.IntendedBindingUri = &repeatDataBodyInfoInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataBodyInfoInput.PInt32 = &repeatDataBodyInfoInputPInt32 } diff --git a/cmd/gapic-showcase/repeat-data-body-patch.go b/cmd/gapic-showcase/repeat-data-body-patch.go index 298548104..bb89010d3 100644 --- a/cmd/gapic-showcase/repeat-data-body-patch.go +++ b/cmd/gapic-showcase/repeat-data-body-patch.go @@ -56,6 +56,8 @@ var repeatDataBodyPatchInputInfoPChildPBool bool var RepeatDataBodyPatchInputInfoPChildPContinent string +var repeatDataBodyPatchInputIntendedBindingUri string + var repeatDataBodyPatchInputPInt32 int32 var repeatDataBodyPatchInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataBodyPatchCmd.Flags().BoolVar(&RepeatDataBodyPatchInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataBodyPatchCmd.Flags().StringVar(&repeatDataBodyPatchInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataBodyPatchCmd.Flags().Int32Var(&RepeatDataBodyPatchInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataBodyPatchCmd.Flags().Int64Var(&RepeatDataBodyPatchInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataBodyPatchCmd = &cobra.Command{ RepeatDataBodyPatchInput.Info.PChild.PBool = &repeatDataBodyPatchInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataBodyPatchInput.IntendedBindingUri = &repeatDataBodyPatchInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataBodyPatchInput.PInt32 = &repeatDataBodyPatchInputPInt32 } diff --git a/cmd/gapic-showcase/repeat-data-body-put.go b/cmd/gapic-showcase/repeat-data-body-put.go index e4827b40b..425a7eee8 100644 --- a/cmd/gapic-showcase/repeat-data-body-put.go +++ b/cmd/gapic-showcase/repeat-data-body-put.go @@ -56,6 +56,8 @@ var repeatDataBodyPutInputInfoPChildPBool bool var RepeatDataBodyPutInputInfoPChildPContinent string +var repeatDataBodyPutInputIntendedBindingUri string + var repeatDataBodyPutInputPInt32 int32 var repeatDataBodyPutInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataBodyPutCmd.Flags().BoolVar(&RepeatDataBodyPutInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataBodyPutCmd.Flags().StringVar(&repeatDataBodyPutInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataBodyPutCmd.Flags().Int32Var(&RepeatDataBodyPutInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataBodyPutCmd.Flags().Int64Var(&RepeatDataBodyPutInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataBodyPutCmd = &cobra.Command{ RepeatDataBodyPutInput.Info.PChild.PBool = &repeatDataBodyPutInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataBodyPutInput.IntendedBindingUri = &repeatDataBodyPutInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataBodyPutInput.PInt32 = &repeatDataBodyPutInputPInt32 } diff --git a/cmd/gapic-showcase/repeat-data-body.go b/cmd/gapic-showcase/repeat-data-body.go index a553c7de8..06d6900c9 100644 --- a/cmd/gapic-showcase/repeat-data-body.go +++ b/cmd/gapic-showcase/repeat-data-body.go @@ -56,6 +56,8 @@ var repeatDataBodyInputInfoPChildPBool bool var RepeatDataBodyInputInfoPChildPContinent string +var repeatDataBodyInputIntendedBindingUri string + var repeatDataBodyInputPInt32 int32 var repeatDataBodyInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataBodyCmd.Flags().BoolVar(&RepeatDataBodyInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataBodyCmd.Flags().StringVar(&repeatDataBodyInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataBodyCmd.Flags().Int32Var(&RepeatDataBodyInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataBodyCmd.Flags().Int64Var(&RepeatDataBodyInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataBodyCmd = &cobra.Command{ RepeatDataBodyInput.Info.PChild.PBool = &repeatDataBodyInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataBodyInput.IntendedBindingUri = &repeatDataBodyInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataBodyInput.PInt32 = &repeatDataBodyInputPInt32 } diff --git a/cmd/gapic-showcase/repeat-data-path-resource.go b/cmd/gapic-showcase/repeat-data-path-resource.go index e75c833ed..9ce2719dc 100644 --- a/cmd/gapic-showcase/repeat-data-path-resource.go +++ b/cmd/gapic-showcase/repeat-data-path-resource.go @@ -56,6 +56,8 @@ var repeatDataPathResourceInputInfoPChildPBool bool var RepeatDataPathResourceInputInfoPChildPContinent string +var repeatDataPathResourceInputIntendedBindingUri string + var repeatDataPathResourceInputPInt32 int32 var repeatDataPathResourceInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataPathResourceCmd.Flags().BoolVar(&RepeatDataPathResourceInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataPathResourceCmd.Flags().StringVar(&repeatDataPathResourceInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataPathResourceCmd.Flags().Int32Var(&RepeatDataPathResourceInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataPathResourceCmd.Flags().Int64Var(&RepeatDataPathResourceInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataPathResourceCmd = &cobra.Command{ RepeatDataPathResourceInput.Info.PChild.PBool = &repeatDataPathResourceInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataPathResourceInput.IntendedBindingUri = &repeatDataPathResourceInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataPathResourceInput.PInt32 = &repeatDataPathResourceInputPInt32 } diff --git a/cmd/gapic-showcase/repeat-data-path-trailing-resource.go b/cmd/gapic-showcase/repeat-data-path-trailing-resource.go index 1d193bc85..71e1e4aa5 100644 --- a/cmd/gapic-showcase/repeat-data-path-trailing-resource.go +++ b/cmd/gapic-showcase/repeat-data-path-trailing-resource.go @@ -56,6 +56,8 @@ var repeatDataPathTrailingResourceInputInfoPChildPBool bool var RepeatDataPathTrailingResourceInputInfoPChildPContinent string +var repeatDataPathTrailingResourceInputIntendedBindingUri string + var repeatDataPathTrailingResourceInputPInt32 int32 var repeatDataPathTrailingResourceInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataPathTrailingResourceCmd.Flags().BoolVar(&RepeatDataPathTrailingResourceInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataPathTrailingResourceCmd.Flags().StringVar(&repeatDataPathTrailingResourceInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataPathTrailingResourceCmd.Flags().Int32Var(&RepeatDataPathTrailingResourceInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataPathTrailingResourceCmd.Flags().Int64Var(&RepeatDataPathTrailingResourceInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataPathTrailingResourceCmd = &cobra.Command{ RepeatDataPathTrailingResourceInput.Info.PChild.PBool = &repeatDataPathTrailingResourceInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataPathTrailingResourceInput.IntendedBindingUri = &repeatDataPathTrailingResourceInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataPathTrailingResourceInput.PInt32 = &repeatDataPathTrailingResourceInputPInt32 } diff --git a/cmd/gapic-showcase/repeat-data-query.go b/cmd/gapic-showcase/repeat-data-query.go index 601aa2884..c31c0481d 100644 --- a/cmd/gapic-showcase/repeat-data-query.go +++ b/cmd/gapic-showcase/repeat-data-query.go @@ -56,6 +56,8 @@ var repeatDataQueryInputInfoPChildPBool bool var RepeatDataQueryInputInfoPChildPContinent string +var repeatDataQueryInputIntendedBindingUri string + var repeatDataQueryInputPInt32 int32 var repeatDataQueryInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataQueryCmd.Flags().BoolVar(&RepeatDataQueryInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataQueryCmd.Flags().StringVar(&repeatDataQueryInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataQueryCmd.Flags().Int32Var(&RepeatDataQueryInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataQueryCmd.Flags().Int64Var(&RepeatDataQueryInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataQueryCmd = &cobra.Command{ RepeatDataQueryInput.Info.PChild.PBool = &repeatDataQueryInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataQueryInput.IntendedBindingUri = &repeatDataQueryInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataQueryInput.PInt32 = &repeatDataQueryInputPInt32 } diff --git a/cmd/gapic-showcase/repeat-data-simple-path.go b/cmd/gapic-showcase/repeat-data-simple-path.go index a74ba56a2..b40b75340 100644 --- a/cmd/gapic-showcase/repeat-data-simple-path.go +++ b/cmd/gapic-showcase/repeat-data-simple-path.go @@ -56,6 +56,8 @@ var repeatDataSimplePathInputInfoPChildPBool bool var RepeatDataSimplePathInputInfoPChildPContinent string +var repeatDataSimplePathInputIntendedBindingUri string + var repeatDataSimplePathInputPInt32 int32 var repeatDataSimplePathInputPInt64 int64 @@ -189,6 +191,8 @@ func init() { RepeatDataSimplePathCmd.Flags().BoolVar(&RepeatDataSimplePathInput.ServerVerify, "server_verify", false, "If true, the server will verify that the received...") + RepeatDataSimplePathCmd.Flags().StringVar(&repeatDataSimplePathInputIntendedBindingUri, "intended_binding_uri", "", "The URI template this request is expected to be...") + RepeatDataSimplePathCmd.Flags().Int32Var(&RepeatDataSimplePathInput.FInt32, "f_int32", 0, "Some top level fields, to test that these are...") RepeatDataSimplePathCmd.Flags().Int64Var(&RepeatDataSimplePathInput.FInt64, "f_int64", 0, "") @@ -296,6 +300,10 @@ var RepeatDataSimplePathCmd = &cobra.Command{ RepeatDataSimplePathInput.Info.PChild.PBool = &repeatDataSimplePathInputInfoPChildPBool } + if cmd.Flags().Changed("intended_binding_uri") { + RepeatDataSimplePathInput.IntendedBindingUri = &repeatDataSimplePathInputIntendedBindingUri + } + if cmd.Flags().Changed("p_int32") { RepeatDataSimplePathInput.PInt32 = &repeatDataSimplePathInputPInt32 } diff --git a/schema/google/showcase/v1beta1/compliance.proto b/schema/google/showcase/v1beta1/compliance.proto index 52d2f2adb..7136c474e 100644 --- a/schema/google/showcase/v1beta1/compliance.proto +++ b/schema/google/showcase/v1beta1/compliance.proto @@ -71,6 +71,9 @@ service Compliance { rpc RepeatDataPathResource(RepeatRequest) returns (RepeatResponse) { option (google.api.http) = { get: "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/*}/bool/{info.f_bool}:pathresource" + additional_bindings { + get: "/v1beta1/repeat/{info.f_child.f_string=first/*}/{info.f_string=second/*}/bool/{info.f_bool}:childfirstpathresource" + } }; } @@ -107,6 +110,9 @@ message RepeatRequest { // the request with the same name in the compliance test suite. bool server_verify = 3; + // The URI template this request is expected to be bound to server-side. + optional string intended_binding_uri = 10; + // Some top level fields, to test that these are encoded correctly // in query params. int32 f_int32 = 4; @@ -120,6 +126,9 @@ message RepeatRequest { message RepeatResponse { RepeatRequest request = 1; + + // The URI template the request was bound to server-side. + string binding_uri = 2; } // ComplianceSuite contains a set of requests that microgenerators should issue diff --git a/server/genproto/compliance.pb.go b/server/genproto/compliance.pb.go index ac00526f7..94e986ae6 100644 --- a/server/genproto/compliance.pb.go +++ b/server/genproto/compliance.pb.go @@ -168,6 +168,8 @@ type RepeatRequest struct { // If true, the server will verify that the received request matches // the request with the same name in the compliance test suite. ServerVerify bool `protobuf:"varint,3,opt,name=server_verify,json=serverVerify,proto3" json:"server_verify,omitempty"` + // The URI template this request is expected to be bound to server-side. + IntendedBindingUri *string `protobuf:"bytes,10,opt,name=intended_binding_uri,json=intendedBindingUri,proto3,oneof" json:"intended_binding_uri,omitempty"` // Some top level fields, to test that these are encoded correctly // in query params. FInt32 int32 `protobuf:"varint,4,opt,name=f_int32,json=fInt32,proto3" json:"f_int32,omitempty"` @@ -231,6 +233,13 @@ func (x *RepeatRequest) GetServerVerify() bool { return false } +func (x *RepeatRequest) GetIntendedBindingUri() string { + if x != nil && x.IntendedBindingUri != nil { + return *x.IntendedBindingUri + } + return "" +} + func (x *RepeatRequest) GetFInt32() int32 { if x != nil { return x.FInt32 @@ -279,6 +288,8 @@ type RepeatResponse struct { unknownFields protoimpl.UnknownFields Request *RepeatRequest `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"` + // The URI template the request was bound to server-side. + BindingUri string `protobuf:"bytes,2,opt,name=binding_uri,json=bindingUri,proto3" json:"binding_uri,omitempty"` } func (x *RepeatResponse) Reset() { @@ -320,6 +331,13 @@ func (x *RepeatResponse) GetRequest() *RepeatRequest { return nil } +func (x *RepeatResponse) GetBindingUri() string { + if x != nil { + return x.BindingUri + } + return "" +} + // ComplianceSuite contains a set of requests that microgenerators should issue // over REST to the Compliance service to test their gRPC-to-REST transcoding // implementation. @@ -869,7 +887,7 @@ var file_google_showcase_v1beta1_compliance_proto_rawDesc = []byte{ 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd3, 0x02, 0x0a, 0x0d, 0x52, + 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa3, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, @@ -878,250 +896,265 @@ var file_google_showcase_v1beta1_compliance_proto_rawDesc = []byte{ 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x17, 0x0a, 0x07, 0x66, - 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x66, 0x49, - 0x6e, 0x74, 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, - 0x1c, 0x0a, 0x07, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, - 0x48, 0x00, 0x52, 0x06, 0x70, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, - 0x07, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, - 0x52, 0x06, 0x70, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x70, - 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, - 0x07, 0x70, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, + 0x66, 0x79, 0x12, 0x35, 0x0a, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x62, + 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x12, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x69, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x55, 0x72, 0x69, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x69, + 0x6e, 0x74, 0x33, 0x32, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x06, 0x66, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, + 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, + 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x33, + 0x32, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x06, 0x70, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x03, 0x48, 0x02, 0x52, 0x06, 0x70, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x88, + 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x01, 0x48, 0x03, 0x52, 0x07, 0x70, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x88, + 0x01, 0x01, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, + 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x72, 0x69, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, - 0x22, 0x52, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x22, 0x73, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x51, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, - 0x63, 0x65, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x7d, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x69, 0x61, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x72, 0x70, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x72, 0x70, - 0x63, 0x73, 0x12, 0x42, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, - 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xac, 0x08, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x19, 0x0a, - 0x08, 0x66, 0x5f, 0x73, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, - 0x07, 0x66, 0x53, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x5f, 0x73, 0x66, - 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x09, 0x66, 0x53, - 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x75, 0x69, 0x6e, - 0x74, 0x33, 0x32, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x66, 0x55, 0x69, 0x6e, 0x74, - 0x33, 0x32, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x07, 0x52, 0x08, 0x66, 0x46, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, - 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x06, 0x66, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x73, 0x69, - 0x6e, 0x74, 0x36, 0x34, 0x18, 0x08, 0x20, 0x01, 0x28, 0x12, 0x52, 0x07, 0x66, 0x53, 0x69, 0x6e, - 0x74, 0x36, 0x34, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x5f, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, - 0x34, 0x18, 0x09, 0x20, 0x01, 0x28, 0x10, 0x52, 0x09, 0x66, 0x53, 0x66, 0x69, 0x78, 0x65, 0x64, - 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x1b, 0x0a, - 0x09, 0x66, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x06, - 0x52, 0x08, 0x66, 0x46, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, - 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, 0x44, - 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x66, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x15, - 0x0a, 0x06, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, - 0x66, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x50, - 0x0a, 0x09, 0x66, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x18, 0x16, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, - 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x4b, - 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x52, 0x08, 0x66, 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, - 0x12, 0x45, 0x0a, 0x07, 0x66, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, - 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, - 0x06, 0x66, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x70, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x5f, 0x69, 0x6e, 0x74, - 0x33, 0x32, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x06, 0x70, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, - 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, 0x07, 0x70, 0x44, 0x6f, 0x75, 0x62, - 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, - 0x14, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x05, 0x70, 0x42, 0x6f, 0x6f, 0x6c, 0x88, 0x01, - 0x01, 0x12, 0x55, 0x0a, 0x09, 0x70, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x18, 0x17, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, - 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, - 0x66, 0x65, 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x48, 0x04, 0x52, 0x08, 0x70, 0x4b, 0x69, - 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x4a, 0x0a, 0x07, 0x70, 0x5f, 0x63, 0x68, - 0x69, 0x6c, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, + 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x55, 0x72, 0x69, 0x22, 0x51, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, + 0x6e, 0x63, 0x65, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x7d, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x72, 0x70, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x72, + 0x70, 0x63, 0x73, 0x12, 0x42, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, + 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xac, 0x08, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x19, + 0x0a, 0x08, 0x66, 0x5f, 0x73, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, + 0x52, 0x07, 0x66, 0x53, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x5f, 0x73, + 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x09, 0x66, + 0x53, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x75, 0x69, + 0x6e, 0x74, 0x33, 0x32, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x66, 0x55, 0x69, 0x6e, + 0x74, 0x33, 0x32, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x07, 0x52, 0x08, 0x66, 0x46, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, + 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x06, 0x66, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x73, + 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x08, 0x20, 0x01, 0x28, 0x12, 0x52, 0x07, 0x66, 0x53, 0x69, + 0x6e, 0x74, 0x36, 0x34, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x5f, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, + 0x36, 0x34, 0x18, 0x09, 0x20, 0x01, 0x28, 0x10, 0x52, 0x09, 0x66, 0x53, 0x66, 0x69, 0x78, 0x65, + 0x64, 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x55, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x1b, + 0x0a, 0x09, 0x66, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x06, 0x52, 0x08, 0x66, 0x46, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, 0x19, 0x0a, 0x08, 0x66, + 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, + 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x66, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, + 0x15, 0x0a, 0x06, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x05, 0x66, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, + 0x50, 0x0a, 0x09, 0x66, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x18, 0x16, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, + 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x66, 0x65, + 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x52, 0x08, 0x66, 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, + 0x6d, 0x12, 0x45, 0x0a, 0x07, 0x66, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, + 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x64, + 0x52, 0x06, 0x66, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x70, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x5f, 0x69, 0x6e, + 0x74, 0x33, 0x32, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x06, 0x70, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, 0x07, 0x70, 0x44, 0x6f, 0x75, + 0x62, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x05, 0x70, 0x42, 0x6f, 0x6f, 0x6c, 0x88, + 0x01, 0x01, 0x12, 0x55, 0x0a, 0x09, 0x70, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, + 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x4c, + 0x69, 0x66, 0x65, 0x4b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x48, 0x04, 0x52, 0x08, 0x70, 0x4b, + 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x4a, 0x0a, 0x07, 0x70, 0x5f, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x48, 0x05, 0x52, 0x06, 0x70, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x88, 0x01, 0x01, 0x22, 0x83, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x66, 0x65, 0x4b, 0x69, + 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x12, 0x1c, 0x0a, 0x18, 0x4c, 0x49, 0x46, 0x45, 0x5f, 0x4b, 0x49, + 0x4e, 0x47, 0x44, 0x4f, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x52, 0x43, 0x48, 0x41, 0x45, 0x42, 0x41, 0x43, + 0x54, 0x45, 0x52, 0x49, 0x41, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x55, 0x42, 0x41, 0x43, + 0x54, 0x45, 0x52, 0x49, 0x41, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x4f, 0x54, 0x49, + 0x53, 0x54, 0x41, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x55, 0x4e, 0x47, 0x49, 0x10, 0x04, + 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x4c, 0x41, 0x4e, 0x54, 0x41, 0x45, 0x10, 0x05, 0x12, 0x0c, 0x0a, + 0x08, 0x41, 0x4e, 0x49, 0x4d, 0x41, 0x4c, 0x49, 0x41, 0x10, 0x06, 0x42, 0x0b, 0x0a, 0x09, 0x5f, + 0x70, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x69, + 0x6e, 0x74, 0x33, 0x32, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, + 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x70, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x42, 0x0c, 0x0a, 0x0a, + 0x5f, 0x70, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, + 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0xd9, 0x04, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x19, + 0x0a, 0x08, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x66, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x66, 0x46, 0x6c, 0x6f, + 0x61, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x15, 0x0a, + 0x06, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, + 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x43, 0x0a, 0x0b, 0x66, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, + 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x48, 0x05, 0x52, 0x06, 0x70, 0x43, 0x68, 0x69, 0x6c, - 0x64, 0x88, 0x01, 0x01, 0x22, 0x83, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x66, 0x65, 0x4b, 0x69, 0x6e, - 0x67, 0x64, 0x6f, 0x6d, 0x12, 0x1c, 0x0a, 0x18, 0x4c, 0x49, 0x46, 0x45, 0x5f, 0x4b, 0x49, 0x4e, - 0x47, 0x44, 0x4f, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x52, 0x43, 0x48, 0x41, 0x45, 0x42, 0x41, 0x43, 0x54, - 0x45, 0x52, 0x49, 0x41, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x55, 0x42, 0x41, 0x43, 0x54, - 0x45, 0x52, 0x49, 0x41, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x4f, 0x54, 0x49, 0x53, - 0x54, 0x41, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x55, 0x4e, 0x47, 0x49, 0x10, 0x04, 0x12, - 0x0b, 0x0a, 0x07, 0x50, 0x4c, 0x41, 0x4e, 0x54, 0x41, 0x45, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, - 0x41, 0x4e, 0x49, 0x4d, 0x41, 0x4c, 0x49, 0x41, 0x10, 0x06, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, - 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x69, 0x6e, - 0x74, 0x33, 0x32, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, - 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x70, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, - 0x70, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, - 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0xd9, 0x04, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, - 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x19, 0x0a, - 0x08, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x66, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x5f, 0x66, 0x6c, - 0x6f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x66, 0x46, 0x6c, 0x6f, 0x61, - 0x74, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x15, 0x0a, 0x06, - 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x42, - 0x6f, 0x6f, 0x6c, 0x12, 0x43, 0x0a, 0x0b, 0x66, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, - 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, + 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x4a, 0x0a, 0x07, 0x66, 0x5f, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x06, 0x66, + 0x43, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x70, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x02, 0x48, 0x01, 0x52, 0x06, 0x70, 0x46, 0x6c, 0x6f, 0x61, 0x74, + 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, 0x07, 0x70, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x03, 0x52, 0x05, 0x70, 0x42, 0x6f, 0x6f, 0x6c, 0x88, 0x01, 0x01, 0x12, + 0x43, 0x0a, 0x0b, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, + 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x4f, 0x0a, 0x07, 0x70, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, + 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x47, 0x72, + 0x61, 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x48, 0x04, 0x52, 0x06, 0x70, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x42, 0x0b, + 0x0a, 0x09, 0x5f, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, + 0x70, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x22, 0x67, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x19, + 0x0a, 0x08, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x66, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x64, + 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, 0x44, 0x6f, + 0x75, 0x62, 0x6c, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x42, 0x6f, 0x6f, 0x6c, 0x2a, 0x69, 0x0a, 0x09, 0x43, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x54, + 0x49, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x46, 0x52, 0x49, 0x43, 0x41, 0x10, 0x01, 0x12, + 0x0b, 0x0a, 0x07, 0x41, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x41, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, + 0x41, 0x4e, 0x54, 0x41, 0x52, 0x54, 0x49, 0x43, 0x41, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x41, + 0x55, 0x53, 0x54, 0x52, 0x41, 0x4c, 0x49, 0x41, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x55, + 0x52, 0x4f, 0x50, 0x45, 0x10, 0x05, 0x32, 0xe0, 0x0b, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, 0x43, - 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x4a, 0x0a, 0x07, 0x66, 0x5f, 0x63, 0x68, - 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x19, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x3a, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x8d, 0x01, 0x0a, 0x12, 0x52, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, + 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x43, - 0x68, 0x69, 0x6c, 0x64, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x70, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x07, 0x70, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x02, 0x48, 0x01, 0x52, 0x06, 0x70, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x88, - 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x01, 0x48, 0x02, 0x52, 0x07, 0x70, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x88, - 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x08, 0x48, 0x03, 0x52, 0x05, 0x70, 0x42, 0x6f, 0x6f, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x43, - 0x0a, 0x0b, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, - 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6e, - 0x65, 0x6e, 0x74, 0x12, 0x4f, 0x0a, 0x07, 0x70, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, - 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x47, 0x72, 0x61, - 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x48, 0x04, 0x52, 0x06, 0x70, 0x43, 0x68, 0x69, 0x6c, - 0x64, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x42, 0x0b, 0x0a, - 0x09, 0x5f, 0x70, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x70, - 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x69, 0x6c, - 0x64, 0x22, 0x67, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x44, - 0x61, 0x74, 0x61, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x19, 0x0a, - 0x08, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x66, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x5f, 0x64, 0x6f, - 0x75, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, 0x44, 0x6f, 0x75, - 0x62, 0x6c, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x42, 0x6f, 0x6f, 0x6c, 0x2a, 0x69, 0x0a, 0x09, 0x43, 0x6f, - 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x54, 0x49, - 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x46, 0x52, 0x49, 0x43, 0x41, 0x10, 0x01, 0x12, 0x0b, - 0x0a, 0x07, 0x41, 0x4d, 0x45, 0x52, 0x49, 0x43, 0x41, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x41, - 0x4e, 0x54, 0x41, 0x52, 0x54, 0x49, 0x43, 0x41, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x55, - 0x53, 0x54, 0x52, 0x41, 0x4c, 0x49, 0x41, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x55, 0x52, - 0x4f, 0x50, 0x45, 0x10, 0x05, 0x32, 0xe8, 0x0a, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, - 0x61, 0x6e, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, - 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x3a, 0x62, 0x6f, 0x64, 0x79, + 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x81, 0x01, 0x0a, 0x0f, 0x52, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x26, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x3a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0xd9, + 0x01, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x53, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, - 0x22, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, - 0x74, 0x3a, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x8d, 0x01, 0x0a, 0x12, 0x52, 0x65, - 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, - 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x3a, 0x62, 0x6f, 0x64, 0x79, 0x69, - 0x6e, 0x66, 0x6f, 0x3a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x81, 0x01, 0x0a, 0x0f, 0x52, 0x65, - 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x26, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6a, + 0x12, 0x68, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, + 0x74, 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x7d, 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x7d, + 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x7d, + 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x7d, 0x2f, 0x7b, + 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x7d, 0x3a, + 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0xd3, 0x02, 0x0a, 0x16, 0x52, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, + 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, - 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x3a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0xd9, 0x01, - 0x0a, 0x14, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x53, 0x69, 0x6d, 0x70, - 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6a, 0x12, - 0x68, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7d, - 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x7d, 0x2f, - 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x7d, 0x2f, - 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x7d, 0x2f, 0x7b, 0x69, - 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x6b, 0x69, 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x7d, 0x3a, 0x73, - 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0xdb, 0x01, 0x0a, 0x16, 0x52, 0x65, - 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, - 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6a, 0x12, 0x68, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x2f, 0x7b, - 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x69, - 0x72, 0x73, 0x74, 0x2f, 0x2a, 0x7d, 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x63, - 0x68, 0x69, 0x6c, 0x64, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x73, 0x65, - 0x63, 0x6f, 0x6e, 0x64, 0x2f, 0x2a, 0x7d, 0x2f, 0x62, 0x6f, 0x6f, 0x6c, 0x2f, 0x7b, 0x69, 0x6e, - 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x7d, 0x3a, 0x70, 0x61, 0x74, 0x68, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0xd9, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x70, 0x65, - 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x61, 0x74, 0x68, 0x54, 0x72, 0x61, 0x69, 0x6c, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe7, 0x01, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0xe0, 0x01, + 0x12, 0x68, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, + 0x74, 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x3d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2f, 0x2a, 0x7d, 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, + 0x66, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x3d, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x2f, 0x2a, 0x7d, 0x2f, 0x62, 0x6f, 0x6f, 0x6c, 0x2f, + 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x7d, 0x3a, 0x70, 0x61, + 0x74, 0x68, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5a, 0x74, 0x12, 0x72, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x2f, 0x7b, 0x69, + 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2e, 0x66, 0x5f, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2f, 0x2a, 0x7d, 0x2f, 0x7b, 0x69, + 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x2f, 0x2a, 0x7d, 0x2f, 0x62, 0x6f, 0x6f, 0x6c, 0x2f, 0x7b, 0x69, 0x6e, 0x66, + 0x6f, 0x2e, 0x66, 0x5f, 0x62, 0x6f, 0x6f, 0x6c, 0x7d, 0x3a, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x70, 0x61, 0x74, 0x68, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x12, 0xd9, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, + 0x61, 0x74, 0x68, 0x54, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, + 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x60, 0x12, 0x5e, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x2f, 0x7b, 0x69, + 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x2f, 0x2a, 0x7d, 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x2f, 0x2a, 0x2a, 0x7d, 0x3a, 0x70, 0x61, 0x74, 0x68, 0x74, 0x72, 0x61, 0x69, + 0x6c, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x88, 0x01, 0x0a, + 0x11, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x50, + 0x75, 0x74, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, - 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x60, 0x12, 0x5e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, - 0x70, 0x65, 0x61, 0x74, 0x2f, 0x7b, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2f, 0x2a, 0x7d, 0x2f, 0x7b, 0x69, 0x6e, - 0x66, 0x6f, 0x2e, 0x66, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2e, 0x66, 0x5f, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x3d, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x2f, 0x2a, 0x2a, 0x7d, 0x3a, 0x70, - 0x61, 0x74, 0x68, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, - 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x75, 0x74, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, - 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, - 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1c, 0x1a, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, - 0x65, 0x61, 0x74, 0x3a, 0x62, 0x6f, 0x64, 0x79, 0x70, 0x75, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x8c, - 0x01, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, - 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x1a, 0x17, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x3a, 0x62, 0x6f, 0x64, + 0x79, 0x70, 0x75, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x8c, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, + 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32, 0x19, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x3a, 0x62, 0x6f, 0x64, 0x79, 0x70, 0x61, + 0x74, 0x63, 0x68, 0x3a, 0x01, 0x2a, 0x1a, 0x11, 0xca, 0x41, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x37, 0x34, 0x36, 0x39, 0x42, 0x71, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x32, - 0x19, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x3a, 0x62, 0x6f, 0x64, 0x79, 0x70, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x01, 0x2a, 0x1a, 0x11, 0xca, - 0x41, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x37, 0x34, 0x36, 0x39, - 0x42, 0x71, 0x0a, 0x1b, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x73, - 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x50, - 0x01, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x61, 0x70, 0x69, 0x63, 0x2d, 0x73, - 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, - 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0xea, 0x02, 0x19, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x3a, 0x3a, 0x53, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x50, 0x01, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, + 0x73, 0x2f, 0x67, 0x61, 0x70, 0x69, 0x63, 0x2d, 0x73, 0x68, 0x6f, 0x77, 0x63, 0x61, 0x73, 0x65, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0xea, 0x02, 0x19, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x53, 0x68, 0x6f, 0x77, 0x63, + 0x61, 0x73, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/server/genrest/compliance.go b/server/genrest/compliance.go index 9283c2bbc..ab3124c32 100644 --- a/server/genrest/compliance.go +++ b/server/genrest/compliance.go @@ -19,6 +19,7 @@ package genrest import ( "bytes" + "context" genprotopb "github.com/googleapis/gapic-showcase/server/genproto" "github.com/googleapis/gapic-showcase/util/genrest/resttools" gmux "github.com/gorilla/mux" @@ -80,7 +81,8 @@ func (backend *RESTBackend) HandleRepeatDataBody(w http.ResponseWriter, r *http. requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataBody(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat:body") + response, err := backend.ComplianceServer.RepeatDataBody(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -158,7 +160,8 @@ func (backend *RESTBackend) HandleRepeatDataBodyInfo(w http.ResponseWriter, r *h requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataBodyInfo(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat:bodyinfo") + response, err := backend.ComplianceServer.RepeatDataBodyInfo(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -214,7 +217,8 @@ func (backend *RESTBackend) HandleRepeatDataQuery(w http.ResponseWriter, r *http requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataQuery(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat:query") + response, err := backend.ComplianceServer.RepeatDataQuery(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -275,7 +279,8 @@ func (backend *RESTBackend) HandleRepeatDataSimplePath(w http.ResponseWriter, r requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataSimplePath(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat/{info.f_string}/{info.f_int32}/{info.f_double}/{info.f_bool}/{info.f_kingdom}:simplepath") + response, err := backend.ComplianceServer.RepeatDataSimplePath(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -336,7 +341,70 @@ func (backend *RESTBackend) HandleRepeatDataPathResource(w http.ResponseWriter, requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataPathResource(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/*}/bool/{info.f_bool}:pathresource") + response, err := backend.ComplianceServer.RepeatDataPathResource(ctx, request) + if err != nil { + backend.ReportGRPCError(w, err) + return + } + + json, err := marshaler.Marshal(response) + if err != nil { + backend.Error(w, http.StatusInternalServerError, "error json-encoding response: %s", err.Error()) + return + } + + w.Write(json) +} + +// HandleRepeatDataPathResource_1 translates REST requests/responses on the wire to internal proto messages for RepeatDataPathResource +// Generated for HTTP binding pattern: "/v1beta1/repeat/{info.f_child.f_string=first/*}/{info.f_string=second/*}/bool/{info.f_bool}:childfirstpathresource" +func (backend *RESTBackend) HandleRepeatDataPathResource_1(w http.ResponseWriter, r *http.Request) { + urlPathParams := gmux.Vars(r) + numUrlPathParams := len(urlPathParams) + + backend.StdLog.Printf("Received %s request matching '/v1beta1/repeat/{info.f_child.f_string=first/*}/{info.f_string=second/*}/bool/{info.f_bool}:childfirstpathresource': %q", r.Method, r.URL) + backend.StdLog.Printf(" urlPathParams (expect 3, have %d): %q", numUrlPathParams, urlPathParams) + + if numUrlPathParams != 3 { + backend.Error(w, http.StatusBadRequest, "found unexpected number of URL variables: expected 3, have %d: %#v", numUrlPathParams, urlPathParams) + return + } + + systemParameters, queryParams, err := resttools.GetSystemParameters(r) + if err != nil { + backend.Error(w, http.StatusBadRequest, "error in query string: %s", err) + return + } + + request := &genprotopb.RepeatRequest{} + if err := resttools.CheckRequestFormat(nil, r, request.ProtoReflect()); err != nil { + backend.Error(w, http.StatusBadRequest, "REST request failed format check: %s", err) + return + } + if err := resttools.PopulateSingularFields(request, urlPathParams); err != nil { + backend.Error(w, http.StatusBadRequest, "error reading URL path params: %s", err) + return + } + + // TODO: Decide whether query-param value or URL-path value takes precedence when a field appears in both + excludedQueryParams := []string{"info.f_child.f_string", "info.f_string", "info.f_bool"} + if duplicates := resttools.KeysMatchPath(queryParams, excludedQueryParams); len(duplicates) > 0 { + backend.Error(w, http.StatusBadRequest, "(QueryParamsInvalidFieldError) found keys that should not appear in query params: %v", duplicates) + return + } + if err := resttools.PopulateFields(request, queryParams); err != nil { + backend.Error(w, http.StatusBadRequest, "error reading query params: %s", err) + return + } + + marshaler := resttools.ToJSON() + marshaler.UseEnumNumbers = systemParameters.EnumEncodingAsInt + requestJSON, _ := marshaler.Marshal(request) + backend.StdLog.Printf(" request: %s", requestJSON) + + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat/{info.f_child.f_string=first/*}/{info.f_string=second/*}/bool/{info.f_bool}:childfirstpathresource") + response, err := backend.ComplianceServer.RepeatDataPathResource(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -397,7 +465,8 @@ func (backend *RESTBackend) HandleRepeatDataPathTrailingResource(w http.Response requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataPathTrailingResource(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/**}:pathtrailingresource") + response, err := backend.ComplianceServer.RepeatDataPathTrailingResource(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -466,7 +535,8 @@ func (backend *RESTBackend) HandleRepeatDataBodyPut(w http.ResponseWriter, r *ht requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataBodyPut(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat:bodyput") + response, err := backend.ComplianceServer.RepeatDataBodyPut(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -535,7 +605,8 @@ func (backend *RESTBackend) HandleRepeatDataBodyPatch(w http.ResponseWriter, r * requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.ComplianceServer.RepeatDataBodyPatch(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/repeat:bodypatch") + response, err := backend.ComplianceServer.RepeatDataBodyPatch(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return diff --git a/server/genrest/echo.go b/server/genrest/echo.go index 9a3b0df6f..767d45a58 100644 --- a/server/genrest/echo.go +++ b/server/genrest/echo.go @@ -19,6 +19,7 @@ package genrest import ( "bytes" + "context" genprotopb "github.com/googleapis/gapic-showcase/server/genproto" "github.com/googleapis/gapic-showcase/util/genrest/resttools" gmux "github.com/gorilla/mux" @@ -80,7 +81,8 @@ func (backend *RESTBackend) HandleEcho(w http.ResponseWriter, r *http.Request) { requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.EchoServer.Echo(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/echo:echo") + response, err := backend.EchoServer.Echo(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -221,7 +223,8 @@ func (backend *RESTBackend) HandlePagedExpand(w http.ResponseWriter, r *http.Req requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.EchoServer.PagedExpand(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/echo:pagedExpand") + response, err := backend.EchoServer.PagedExpand(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -290,7 +293,8 @@ func (backend *RESTBackend) HandlePagedExpandLegacy(w http.ResponseWriter, r *ht requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.EchoServer.PagedExpandLegacy(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/echo:pagedExpandLegacy") + response, err := backend.EchoServer.PagedExpandLegacy(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -359,7 +363,8 @@ func (backend *RESTBackend) HandlePagedExpandLegacyMapped(w http.ResponseWriter, requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.EchoServer.PagedExpandLegacyMapped(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/echo:pagedExpandLegacyMapped") + response, err := backend.EchoServer.PagedExpandLegacyMapped(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -428,7 +433,8 @@ func (backend *RESTBackend) HandleWait(w http.ResponseWriter, r *http.Request) { requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.EchoServer.Wait(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/echo:wait") + response, err := backend.EchoServer.Wait(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -497,7 +503,8 @@ func (backend *RESTBackend) HandleBlock(w http.ResponseWriter, r *http.Request) requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.EchoServer.Block(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/echo:block") + response, err := backend.EchoServer.Block(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return diff --git a/server/genrest/genrest.go b/server/genrest/genrest.go index aafaab290..33462e277 100644 --- a/server/genrest/genrest.go +++ b/server/genrest/genrest.go @@ -37,6 +37,7 @@ func RegisterHandlers(router *gmux.Router, backend *services.Backend) { router.HandleFunc("/v1beta1/repeat:query", rest.HandleRepeatDataQuery).Methods("GET") router.HandleFunc("/v1beta1/repeat/{info.fString:.+}/{info.fInt32:.+}/{info.fDouble:.+}/{info.fBool:.+}/{info.fKingdom:.+}:simplepath", rest.HandleRepeatDataSimplePath).Methods("GET") router.HandleFunc("/v1beta1/repeat/{info.fString:first/.+}/{info.fChild.fString:second/.+}/bool/{info.fBool:.+}:pathresource", rest.HandleRepeatDataPathResource).Methods("GET") + router.HandleFunc("/v1beta1/repeat/{info.fChild.fString:first/.+}/{info.fString:second/.+}/bool/{info.fBool:.+}:childfirstpathresource", rest.HandleRepeatDataPathResource_1).Methods("GET") router.HandleFunc("/v1beta1/repeat/{info.fString:first/.+}/{info.fChild.fString:second/.+}:pathtrailingresource", rest.HandleRepeatDataPathTrailingResource).Methods("GET") router.HandleFunc("/v1beta1/repeat:bodyput", rest.HandleRepeatDataBodyPut).Methods("PUT") router.HandleFunc("/v1beta1/repeat:bodypatch", rest.HandleRepeatDataBodyPatch).Methods("PATCH") diff --git a/server/genrest/identity.go b/server/genrest/identity.go index 00d96d761..231d9987f 100644 --- a/server/genrest/identity.go +++ b/server/genrest/identity.go @@ -19,6 +19,7 @@ package genrest import ( "bytes" + "context" genprotopb "github.com/googleapis/gapic-showcase/server/genproto" "github.com/googleapis/gapic-showcase/util/genrest/resttools" gmux "github.com/gorilla/mux" @@ -80,7 +81,8 @@ func (backend *RESTBackend) HandleCreateUser(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.IdentityServer.CreateUser(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/users") + response, err := backend.IdentityServer.CreateUser(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -141,7 +143,8 @@ func (backend *RESTBackend) HandleGetUser(w http.ResponseWriter, r *http.Request requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.IdentityServer.GetUser(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=users/*}") + response, err := backend.IdentityServer.GetUser(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -210,7 +213,8 @@ func (backend *RESTBackend) HandleUpdateUser(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.IdentityServer.UpdateUser(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{user.name=users/*}") + response, err := backend.IdentityServer.UpdateUser(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -271,7 +275,8 @@ func (backend *RESTBackend) HandleDeleteUser(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.IdentityServer.DeleteUser(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=users/*}") + response, err := backend.IdentityServer.DeleteUser(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -327,7 +332,8 @@ func (backend *RESTBackend) HandleListUsers(w http.ResponseWriter, r *http.Reque requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.IdentityServer.ListUsers(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/users") + response, err := backend.IdentityServer.ListUsers(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return diff --git a/server/genrest/messaging.go b/server/genrest/messaging.go index 4f8263763..8255229d4 100644 --- a/server/genrest/messaging.go +++ b/server/genrest/messaging.go @@ -19,6 +19,7 @@ package genrest import ( "bytes" + "context" genprotopb "github.com/googleapis/gapic-showcase/server/genproto" "github.com/googleapis/gapic-showcase/util/genrest/resttools" gmux "github.com/gorilla/mux" @@ -80,7 +81,8 @@ func (backend *RESTBackend) HandleCreateRoom(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.CreateRoom(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/rooms") + response, err := backend.MessagingServer.CreateRoom(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -141,7 +143,8 @@ func (backend *RESTBackend) HandleGetRoom(w http.ResponseWriter, r *http.Request requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.GetRoom(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=rooms/*}") + response, err := backend.MessagingServer.GetRoom(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -210,7 +213,8 @@ func (backend *RESTBackend) HandleUpdateRoom(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.UpdateRoom(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{room.name=rooms/*}") + response, err := backend.MessagingServer.UpdateRoom(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -271,7 +275,8 @@ func (backend *RESTBackend) HandleDeleteRoom(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.DeleteRoom(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=rooms/*}") + response, err := backend.MessagingServer.DeleteRoom(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -327,7 +332,8 @@ func (backend *RESTBackend) HandleListRooms(w http.ResponseWriter, r *http.Reque requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.ListRooms(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/rooms") + response, err := backend.MessagingServer.ListRooms(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -396,7 +402,8 @@ func (backend *RESTBackend) HandleCreateBlurb(w http.ResponseWriter, r *http.Req requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.CreateBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{parent=rooms/*}/blurbs") + response, err := backend.MessagingServer.CreateBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -465,7 +472,8 @@ func (backend *RESTBackend) HandleCreateBlurb_1(w http.ResponseWriter, r *http.R requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.CreateBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{parent=users/*/profile}/blurbs") + response, err := backend.MessagingServer.CreateBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -526,7 +534,8 @@ func (backend *RESTBackend) HandleGetBlurb(w http.ResponseWriter, r *http.Reques requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.GetBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=rooms/*/blurbs/*}") + response, err := backend.MessagingServer.GetBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -587,7 +596,8 @@ func (backend *RESTBackend) HandleGetBlurb_1(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.GetBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=users/*/profile/blurbs/*}") + response, err := backend.MessagingServer.GetBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -656,7 +666,8 @@ func (backend *RESTBackend) HandleUpdateBlurb(w http.ResponseWriter, r *http.Req requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.UpdateBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{blurb.name=rooms/*/blurbs/*}") + response, err := backend.MessagingServer.UpdateBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -725,7 +736,8 @@ func (backend *RESTBackend) HandleUpdateBlurb_1(w http.ResponseWriter, r *http.R requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.UpdateBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{blurb.name=users/*/profile/blurbs/*}") + response, err := backend.MessagingServer.UpdateBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -786,7 +798,8 @@ func (backend *RESTBackend) HandleDeleteBlurb(w http.ResponseWriter, r *http.Req requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.DeleteBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=rooms/*/blurbs/*}") + response, err := backend.MessagingServer.DeleteBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -847,7 +860,8 @@ func (backend *RESTBackend) HandleDeleteBlurb_1(w http.ResponseWriter, r *http.R requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.DeleteBlurb(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=users/*/profile/blurbs/*}") + response, err := backend.MessagingServer.DeleteBlurb(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -908,7 +922,8 @@ func (backend *RESTBackend) HandleListBlurbs(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.ListBlurbs(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{parent=rooms/*}/blurbs") + response, err := backend.MessagingServer.ListBlurbs(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -969,7 +984,8 @@ func (backend *RESTBackend) HandleListBlurbs_1(w http.ResponseWriter, r *http.Re requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.ListBlurbs(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{parent=users/*/profile}/blurbs") + response, err := backend.MessagingServer.ListBlurbs(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -1038,7 +1054,8 @@ func (backend *RESTBackend) HandleSearchBlurbs(w http.ResponseWriter, r *http.Re requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.SearchBlurbs(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{parent=rooms/*}/blurbs:search") + response, err := backend.MessagingServer.SearchBlurbs(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -1099,7 +1116,8 @@ func (backend *RESTBackend) HandleSearchBlurbs_1(w http.ResponseWriter, r *http. requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.MessagingServer.SearchBlurbs(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{parent=users/*/profile}/blurbs:search") + response, err := backend.MessagingServer.SearchBlurbs(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return diff --git a/server/genrest/operations.go b/server/genrest/operations.go index 8c163ad95..fd3225966 100644 --- a/server/genrest/operations.go +++ b/server/genrest/operations.go @@ -18,6 +18,7 @@ package genrest import ( + "context" "github.com/googleapis/gapic-showcase/util/genrest/resttools" gmux "github.com/gorilla/mux" longrunningpb "google.golang.org/genproto/googleapis/longrunning" @@ -65,7 +66,8 @@ func (backend *RESTBackend) HandleListOperations(w http.ResponseWriter, r *http. requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.OperationsServer.ListOperations(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/operations") + response, err := backend.OperationsServer.ListOperations(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -126,7 +128,8 @@ func (backend *RESTBackend) HandleGetOperation(w http.ResponseWriter, r *http.Re requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.OperationsServer.GetOperation(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=operations/**}") + response, err := backend.OperationsServer.GetOperation(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -187,7 +190,8 @@ func (backend *RESTBackend) HandleDeleteOperation(w http.ResponseWriter, r *http requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.OperationsServer.DeleteOperation(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=operations/**}") + response, err := backend.OperationsServer.DeleteOperation(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -248,7 +252,8 @@ func (backend *RESTBackend) HandleCancelOperation(w http.ResponseWriter, r *http requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.OperationsServer.CancelOperation(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=operations/**}:cancel") + response, err := backend.OperationsServer.CancelOperation(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return diff --git a/server/genrest/sequenceservice.go b/server/genrest/sequenceservice.go index 1a0c64744..2fa04331d 100644 --- a/server/genrest/sequenceservice.go +++ b/server/genrest/sequenceservice.go @@ -19,6 +19,7 @@ package genrest import ( "bytes" + "context" genprotopb "github.com/googleapis/gapic-showcase/server/genproto" "github.com/googleapis/gapic-showcase/util/genrest/resttools" gmux "github.com/gorilla/mux" @@ -89,7 +90,8 @@ func (backend *RESTBackend) HandleCreateSequence(w http.ResponseWriter, r *http. requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.SequenceServiceServer.CreateSequence(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/sequences") + response, err := backend.SequenceServiceServer.CreateSequence(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -150,7 +152,8 @@ func (backend *RESTBackend) HandleGetSequenceReport(w http.ResponseWriter, r *ht requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.SequenceServiceServer.GetSequenceReport(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=sequences/*/sequenceReport}") + response, err := backend.SequenceServiceServer.GetSequenceReport(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -219,7 +222,8 @@ func (backend *RESTBackend) HandleAttemptSequence(w http.ResponseWriter, r *http requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.SequenceServiceServer.AttemptSequence(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=sequences/*}") + response, err := backend.SequenceServiceServer.AttemptSequence(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return diff --git a/server/genrest/showcase-rest-sample-response.txt b/server/genrest/showcase-rest-sample-response.txt index e79a7ca47..f18fc4f7e 100644 --- a/server/genrest/showcase-rest-sample-response.txt +++ b/server/genrest/showcase-rest-sample-response.txt @@ -14,6 +14,7 @@ Compliance (.google.showcase.v1beta1.Compliance): .google.showcase.v1beta1.Compliance.RepeatDataQuery[0] : GET: "/v1beta1/repeat:query" .google.showcase.v1beta1.Compliance.RepeatDataSimplePath[0] : GET: "/v1beta1/repeat/{info.f_string}/{info.f_int32}/{info.f_double}/{info.f_bool}/{info.f_kingdom}:simplepath" .google.showcase.v1beta1.Compliance.RepeatDataPathResource[0] : GET: "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/*}/bool/{info.f_bool}:pathresource" + .google.showcase.v1beta1.Compliance.RepeatDataPathResource[1] : GET: "/v1beta1/repeat/{info.f_child.f_string=first/*}/{info.f_string=second/*}/bool/{info.f_bool}:childfirstpathresource" .google.showcase.v1beta1.Compliance.RepeatDataPathTrailingResource[0] : GET: "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/**}:pathtrailingresource" .google.showcase.v1beta1.Compliance.RepeatDataBodyPut[0] : PUT: "/v1beta1/repeat:bodyput" .google.showcase.v1beta1.Compliance.RepeatDataBodyPatch[0] : PATCH: "/v1beta1/repeat:bodypatch" @@ -86,10 +87,13 @@ GoModel Shim "Compliance" (.google.showcase.v1beta1.Compliance) Imports: genprotopb: "github.com/googleapis/gapic-showcase/server/genproto" "github.com/googleapis/gapic-showcase/server/genproto" - Handlers (8): + Handlers (9): GET /v1beta1/repeat:query func RepeatDataQuery(request genprotopb.RepeatRequest) (response genprotopb.RepeatResponse) {} ["/" "v1beta1" "/" "repeat" ":" "query"] + GET /v1beta1/repeat/{info.f_child.f_string=first/*}/{info.f_string=second/*}/bool/{info.f_bool}:childfirstpathresource func RepeatDataPathResource(request genprotopb.RepeatRequest) (response genprotopb.RepeatResponse) {} +["/" "v1beta1" "/" "repeat" "/" {info.f_child.f_string = ["first" "/" *]} "/" {info.f_string = ["second" "/" *]} "/" "bool" "/" {info.f_bool = []} ":" "childfirstpathresource"] + GET /v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/**}:pathtrailingresource func RepeatDataPathTrailingResource(request genprotopb.RepeatRequest) (response genprotopb.RepeatResponse) {} ["/" "v1beta1" "/" "repeat" "/" {info.f_string = ["first" "/" *]} "/" {info.f_child.f_string = ["second" "/" **]} ":" "pathtrailingresource"] diff --git a/server/genrest/testing.go b/server/genrest/testing.go index 22973df64..fe96c738d 100644 --- a/server/genrest/testing.go +++ b/server/genrest/testing.go @@ -19,6 +19,7 @@ package genrest import ( "bytes" + "context" genprotopb "github.com/googleapis/gapic-showcase/server/genproto" "github.com/googleapis/gapic-showcase/util/genrest/resttools" gmux "github.com/gorilla/mux" @@ -89,7 +90,8 @@ func (backend *RESTBackend) HandleCreateSession(w http.ResponseWriter, r *http.R requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.CreateSession(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/sessions") + response, err := backend.TestingServer.CreateSession(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -150,7 +152,8 @@ func (backend *RESTBackend) HandleGetSession(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.GetSession(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=sessions/*}") + response, err := backend.TestingServer.GetSession(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -206,7 +209,8 @@ func (backend *RESTBackend) HandleListSessions(w http.ResponseWriter, r *http.Re requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.ListSessions(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/sessions") + response, err := backend.TestingServer.ListSessions(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -267,7 +271,8 @@ func (backend *RESTBackend) HandleDeleteSession(w http.ResponseWriter, r *http.R requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.DeleteSession(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=sessions/*}") + response, err := backend.TestingServer.DeleteSession(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -328,7 +333,8 @@ func (backend *RESTBackend) HandleReportSession(w http.ResponseWriter, r *http.R requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.ReportSession(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=sessions/*}:report") + response, err := backend.TestingServer.ReportSession(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -389,7 +395,8 @@ func (backend *RESTBackend) HandleListTests(w http.ResponseWriter, r *http.Reque requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.ListTests(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{parent=sessions/*}/tests") + response, err := backend.TestingServer.ListTests(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -450,7 +457,8 @@ func (backend *RESTBackend) HandleDeleteTest(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.DeleteTest(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=sessions/*/tests/*}") + response, err := backend.TestingServer.DeleteTest(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return @@ -511,7 +519,8 @@ func (backend *RESTBackend) HandleVerifyTest(w http.ResponseWriter, r *http.Requ requestJSON, _ := marshaler.Marshal(request) backend.StdLog.Printf(" request: %s", requestJSON) - response, err := backend.TestingServer.VerifyTest(r.Context(), request) + ctx := context.WithValue(r.Context(), resttools.BindingURIKey, "/v1beta1/{name=sessions/*/tests/*}:check") + response, err := backend.TestingServer.VerifyTest(ctx, request) if err != nil { backend.ReportGRPCError(w, err) return diff --git a/server/services/compliance_service.go b/server/services/compliance_service.go index e3b40f0e1..067560f34 100644 --- a/server/services/compliance_service.go +++ b/server/services/compliance_service.go @@ -22,6 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/googleapis/gapic-showcase/server" pb "github.com/googleapis/gapic-showcase/server/genproto" + "github.com/googleapis/gapic-showcase/util/genrest/resttools" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" ) @@ -37,10 +38,11 @@ type complianceServerImpl struct { // requestMatchesExpectations returns an error iff the received request asks for server verification and its // contents do not match a known suite testing request with the same name. -func (csi *complianceServerImpl) requestMatchesExpectation(received *pb.RepeatRequest) error { +func (csi *complianceServerImpl) requestMatchesExpectation(received *pb.RepeatRequest, binding string) error { if !received.GetServerVerify() { return nil } + if ComplianceSuiteStatus == ComplianceSuiteError { return fmt.Errorf(ComplianceSuiteStatusMessage) } @@ -51,6 +53,20 @@ func (csi *complianceServerImpl) requestMatchesExpectation(received *pb.RepeatRe return fmt.Errorf("(ComplianceSuiteRequestNotFoundError) compliance suite does not contain a request %q", name) } + // Checking that the binding in the test suite matches actual binding used. + if expectedRequest.IntendedBindingUri != nil { + intendedBinding := expectedRequest.GetIntendedBindingUri() + if intendedBinding != binding { + return fmt.Errorf("(ComplianceSuiteWrongBindingError) request %q was transcoded to the wrong binding (expected: %s; actual %s)", name, intendedBinding, binding) + } + } + + // Separately checking that the binding in the client request matches binding in the test suite. + // This guards against the test suite file being wrong on the client. + if expectedRequest.GetIntendedBindingUri() != received.GetIntendedBindingUri() { + return fmt.Errorf("(ComplianceSuiteRequestBindingMismatchError) intended binding of request %q does not match test suite (expected: %s, received: %s)", name, expectedRequest.GetIntendedBindingUri(), received.GetIntendedBindingUri()) + } + if diff := cmp.Diff(received.GetInfo(), expectedRequest.GetInfo(), cmp.Comparer(proto.Equal)); diff != "" { return fmt.Errorf("(ComplianceSuiteRequestMismatchError) contents of request %q do not match test suite", name) } @@ -60,10 +76,17 @@ func (csi *complianceServerImpl) requestMatchesExpectation(received *pb.RepeatRe func (csi *complianceServerImpl) Repeat(ctx context.Context, in *pb.RepeatRequest) (*pb.RepeatResponse, error) { echoTrailers(ctx) - if err := csi.requestMatchesExpectation(in); err != nil { + + bindingURI, ok := ctx.Value(resttools.BindingURIKey).(string) + if !ok { + bindingURI = "" + } + + if err := csi.requestMatchesExpectation(in, bindingURI); err != nil { return nil, err } - return &pb.RepeatResponse{Request: in}, nil + + return &pb.RepeatResponse{Request: in, BindingUri: bindingURI}, nil } func (csi *complianceServerImpl) RepeatDataBody(ctx context.Context, in *pb.RepeatRequest) (*pb.RepeatResponse, error) { diff --git a/server/services/compliance_service_test.go b/server/services/compliance_service_test.go index a2e6ce122..95367f2c1 100644 --- a/server/services/compliance_service_test.go +++ b/server/services/compliance_service_test.go @@ -82,12 +82,12 @@ func TestMatchingComplianceSuiteRequests(t *testing.T) { Info: info, } - if got := server.requestMatchesExpectation(request); got != nil { + if got := server.requestMatchesExpectation(request, ""); got != nil { t.Errorf("expected request to trivially match when serverVerify unset. Got error: %s", got) } request.ServerVerify = true - if err := server.requestMatchesExpectation(request); err == nil { + if err := server.requestMatchesExpectation(request, ""); err == nil { t.Errorf("expected verified request with differing data to not match") } else { if got, want := err.Error(), "(ComplianceSuiteRequestMismatchError)"; !strings.Contains(got, want) { @@ -99,7 +99,7 @@ func TestMatchingComplianceSuiteRequests(t *testing.T) { } request.Name = "non-existent case" - if err := server.requestMatchesExpectation(request); err == nil { + if err := server.requestMatchesExpectation(request, ""); err == nil { t.Errorf("expected verified request with unmatched name to cause an error") } else { if got, want := err.Error(), "(ComplianceSuiteRequestNotFoundError)"; !strings.Contains(got, want) { @@ -111,7 +111,7 @@ func TestMatchingComplianceSuiteRequests(t *testing.T) { } request = ComplianceSuiteRequests["Basic data types"] // matches a name in compliance_suite.json - if got := server.requestMatchesExpectation(request); got != nil { + if got := server.requestMatchesExpectation(request, ""); got != nil { t.Errorf("expected test suite case to match. Got error: %s", got) } if _, got := server.Repeat(context.Background(), request); got != nil { @@ -119,6 +119,79 @@ func TestMatchingComplianceSuiteRequests(t *testing.T) { } } +// Tests for the binding verification parts of the request verification +// in the compliance service. +func TestBindingComplianceSuiteRequests(t *testing.T) { + server := &complianceServerImpl{} + + info := &pb.ComplianceData{ + FString: "first/hello", + PBool: &[]bool{true}[0], + FChild: &pb.ComplianceDataChild{ + FString: "second/greetings", + }, + } + + noURIVerifyRequest := &pb.RepeatRequest{ + Name: "Binding testing baseline no Uri verification", // matches a name in compliance_suite.json + Info: info, + ServerVerify: true, + } + wrongBindingURI := "/foo/{id=bar/*}" + + if got := server.requestMatchesExpectation(noURIVerifyRequest, wrongBindingURI); got != nil { + t.Errorf("expected request to match when intended Uri is not set on server. Got error: %s", got) + } + + // realBindingUri matches the value in compliance_suite.json + realBindingURI := "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/*}/bool/{info.f_bool}:pathresource" + uriVerifyRequest := &pb.RepeatRequest{ + Name: "Binding testing first binding", // matches a name in compliance_suite.json + Info: info, + ServerVerify: true, + IntendedBindingUri: &realBindingURI, + } + + // There are three sources of binding Uri: + // - actualUri: what actual Uri the request was bound to in runtime + // (the second parameter of the `requestMatchesExpectation` method) + // - serverUri: what server thinks the binding Uri should be + // (in the server-side json testing suite data's `IntendedBindingUri` field) + // - clientUri: what client thinks the binding Uri should be + // (in the client-side json testing suite data `IntendedBindingUri` field) + // The `requestMatchesExpectation` method verifies + // - actualUri <- vs -> serverUri (looking for incorrect runtime binding) + // - clientUri <- vs -> serverUri (looking for wrong client test suite) + + // In this case the request is simulated to get bound to a wrong Uri + // (the second parameter of the `requestMatchesExpectation` method), + // therefore actualUri will differ from serverUri. + if err := server.requestMatchesExpectation(uriVerifyRequest, wrongBindingURI); err == nil { + t.Errorf("expected request that got bound to a wrong uri to not match") + } else { + if got, want := err.Error(), "(ComplianceSuiteWrongBindingError)"; !strings.Contains(got, want) { + t.Errorf("error message does not contain expected substring: want: %q got %q", want, got) + } + } + + // In this case the actualUri is set to the correct value + // (matching the serverUri), but the clientUri is set to the wrong value, + // simulating a corrupt or outdated client testing suite. + uriVerifyRequest.IntendedBindingUri = &wrongBindingURI + if err := server.requestMatchesExpectation(uriVerifyRequest, realBindingURI); err == nil { + t.Errorf("expected request with an incorrect bindingUri to not match") + } else { + if got, want := err.Error(), "(ComplianceSuiteRequestBindingMismatchError)"; !strings.Contains(got, want) { + t.Errorf("error message does not contain expected substring: want: %q got %q", want, got) + } + } + + uriVerifyRequest.IntendedBindingUri = &realBindingURI + if got := server.requestMatchesExpectation(uriVerifyRequest, realBindingURI); got != nil { + t.Errorf("expected request to match when binding Uri is same everywhere. Got error: %s", got) + } +} + func TestIndexingComplianceSuite(t *testing.T) { // set up ComplianceSuiteStatus = ComplianceSuiteUninitialized @@ -162,7 +235,7 @@ func TestIndexingComplianceSuite(t *testing.T) { Name: "Basic data types", // matches a name in compliance_suite.json ServerVerify: true, } - if err := server.requestMatchesExpectation(request); err == nil { + if err := server.requestMatchesExpectation(request, ""); err == nil { t.Errorf("expected verified request with differing data to not match") } else { if got, want := err.Error(), "(ComplianceServiceSetupError)"; !strings.Contains(got, want) { diff --git a/server/services/compliance_suite.json b/server/services/compliance_suite.json index 11494801f..42734296f 100644 --- a/server/services/compliance_suite.json +++ b/server/services/compliance_suite.json @@ -161,6 +161,50 @@ } ] }, + { + "name": "Binding selection testing", + "rpcs": ["Compliance.RepeatDataPathResource"], + "requests": [ + { + "name": "Binding testing baseline no Uri verification", + "serverVerify": true, + "info": { + "fString": "first/hello", + "pBool": true, + + "fChild": { + "fString": "second/greetings" + } + } + }, + { + "name": "Binding testing first binding", + "serverVerify": true, + "info": { + "fString": "first/hello", + "pBool": true, + + "fChild": { + "fString": "second/greetings" + } + }, + "intendedBindingUri": "/v1beta1/repeat/{info.f_string=first/*}/{info.f_child.f_string=second/*}/bool/{info.f_bool}:pathresource" + }, + { + "name": "Binding testing additional binding", + "serverVerify": true, + "info": { + "fString": "second/greetings", + "pBool": true, + + "fChild": { + "fString": "first/hello" + } + }, + "intendedBindingUri": "/v1beta1/repeat/{info.f_child.f_string=first/*}/{info.f_string=second/*}/bool/{info.f_bool}:childfirstpathresource" + } + ] + }, { "name": "Cases that apply to non-path requests", "rpcs": ["Compliance.RepeatDataBody", "Compliance.RepeatDataBodyPut", "Compliance.RepeatDataBodyPatch", "Compliance.RepeatDataQuery"], diff --git a/util/genrest/goviewcreator.go b/util/genrest/goviewcreator.go index 01216deaf..c29968a4f 100644 --- a/util/genrest/goviewcreator.go +++ b/util/genrest/goviewcreator.go @@ -47,6 +47,7 @@ func NewView(model *gomodel.Model) (*goview.View, error) { file.P("") fileImports := map[string]string{ + "context": "", "net/http": "", "github.com/googleapis/gapic-showcase/util/genrest/resttools": "", "github.com/gorilla/mux": "gmux", @@ -223,7 +224,8 @@ func NewView(model *gomodel.Model) (*goview.View, error) { } else { // regular unary call // TODO: In the future, we may want to redirect all REST-endpoint requests to the gRPC endpoint so that the gRPC-registered observers get invoked. - source.P(" %s, err := backend.%sServer.%s(r.Context(), %s)", handler.ResponseVariable, service.ShortName, handler.GoMethod, handler.RequestVariable) + source.P(" ctx := context.WithValue(r.Context(), resttools.BindingURIKey, \"%s\")", handler.URIPattern) + source.P(" %s, err := backend.%sServer.%s(ctx, %s)", handler.ResponseVariable, service.ShortName, handler.GoMethod, handler.RequestVariable) source.P(" if err != nil {") source.P(" backend.ReportGRPCError(w, err)") source.P(" return") diff --git a/util/genrest/resttools/constants.go b/util/genrest/resttools/constants.go index c30e9d768..b1e8d5211 100644 --- a/util/genrest/resttools/constants.go +++ b/util/genrest/resttools/constants.go @@ -56,3 +56,8 @@ func init() { RegexLiteral = fmt.Sprintf(`^[%s]+`, CharsLiteral) } + +// A key-type for storing binding URI value in the Context +type BindingURIKeyType string + +const BindingURIKey BindingURIKeyType = BindingURIKeyType("BindingURIKey")