diff --git a/protoc-gen-swagger/genswagger/template.go b/protoc-gen-swagger/genswagger/template.go index 4dd5f04656d..dc3cf6a3130 100644 --- a/protoc-gen-swagger/genswagger/template.go +++ b/protoc-gen-swagger/genswagger/template.go @@ -934,6 +934,9 @@ func renderServices(services []*descriptor.Service, paths swaggerPathsObject, re operationObject.Tags = make([]string, len(opts.Tags)) copy(operationObject.Tags, opts.Tags) } + if opts.OperationId != "" { + operationObject.OperationID = opts.OperationId + } if opts.Security != nil { newSecurity := []swaggerSecurityRequirementObject{} if operationObject.Security != nil { diff --git a/protoc-gen-swagger/genswagger/template_test.go b/protoc-gen-swagger/genswagger/template_test.go index dbcb238e290..c61a3346acc 100644 --- a/protoc-gen-swagger/genswagger/template_test.go +++ b/protoc-gen-swagger/genswagger/template_test.go @@ -372,6 +372,84 @@ func TestApplyTemplateSimple(t *testing.T) { } } +func TestApplyTemplateOverrideOperationID(t *testing.T) { + msgdesc := &protodescriptor.DescriptorProto{ + Name: proto.String("ExampleMessage"), + } + meth := &protodescriptor.MethodDescriptorProto{ + Name: proto.String("Example"), + InputType: proto.String("ExampleMessage"), + OutputType: proto.String("ExampleMessage"), + Options: &protodescriptor.MethodOptions{}, + } + swaggerOperation := swagger_options.Operation{ + OperationId: "MyExample", + } + if err := proto.SetExtension(proto.Message(meth.Options), swagger_options.E_Openapiv2Operation, &swaggerOperation); err != nil { + t.Fatalf("proto.SetExtension(MethodDescriptorProto.Options) failed: %v", err) + } + + svc := &protodescriptor.ServiceDescriptorProto{ + Name: proto.String("ExampleService"), + Method: []*protodescriptor.MethodDescriptorProto{meth}, + } + msg := &descriptor.Message{ + DescriptorProto: msgdesc, + } + file := descriptor.File{ + FileDescriptorProto: &protodescriptor.FileDescriptorProto{ + SourceCodeInfo: &protodescriptor.SourceCodeInfo{}, + Name: proto.String("example.proto"), + Package: proto.String("example"), + Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"}, + MessageType: []*protodescriptor.DescriptorProto{msgdesc}, + Service: []*protodescriptor.ServiceDescriptorProto{svc}, + }, + GoPkg: descriptor.GoPackage{ + Path: "example.com/path/to/example/example.pb", + Name: "example_pb", + }, + Messages: []*descriptor.Message{msg}, + Services: []*descriptor.Service{ + { + ServiceDescriptorProto: svc, + Methods: []*descriptor.Method{ + { + MethodDescriptorProto: meth, + RequestType: msg, + ResponseType: msg, + Bindings: []*descriptor.Binding{ + { + HTTPMethod: "GET", + Body: &descriptor.Body{FieldPath: nil}, + PathTmpl: httprule.Template{ + Version: 1, + OpCodes: []int{0, 0}, + Template: "/v1/echo", // TODO(achew22): Figure out what this should really be + }, + }, + }, + }, + }, + }, + }, + } + result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: descriptor.NewRegistry()}) + if err != nil { + t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err) + return + } + if want, is := "MyExample", result.Paths["/v1/echo"].Get.OperationID; !reflect.DeepEqual(is, want) { + t.Errorf("applyTemplate(%#v).Paths[0].Get.OperationID = %s want to be %s", file, is, want) + } + + // If there was a failure, print out the input and the json result for debugging. + if t.Failed() { + t.Errorf("had: %s", file) + t.Errorf("got: %s", fmt.Sprint(result)) + } +} + func TestApplyTemplateExtensions(t *testing.T) { msgdesc := &protodescriptor.DescriptorProto{ Name: proto.String("ExampleMessage"),