diff --git a/cmd/query/app/grpc_handler_test.go b/cmd/query/app/grpc_handler_test.go index 63a2bd3d11c..f7c29595eb9 100644 --- a/cmd/query/app/grpc_handler_test.go +++ b/cmd/query/app/grpc_handler_test.go @@ -415,20 +415,29 @@ func TestGetServicesFailureGRPC(t *testing.T) { func TestGetOperationsSuccessGRPC(t *testing.T) { withServerAndClient(t, func(server *grpcServer, client *grpcClient) { - expectedOperations := []string{"", "get"} - server.spanReader.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), "abc/trifle").Return(expectedOperations, nil).Once() + expectedOperations := []*spanstore.Operation{{Name: ""}, {Name: "get", SpanKind: "server"}} + server.spanReader.On("GetOperations", + mock.AnythingOfType("*context.valueCtx"), + &spanstore.OperationQueryParameters{ServiceName: "abc/trifle"}, + ).Return(expectedOperations, nil).Once() res, err := client.GetOperations(context.Background(), &api_v2.GetOperationsRequest{ Service: "abc/trifle", }) assert.NoError(t, err) - assert.Equal(t, expectedOperations, res.Operations) + assert.Equal(t, len(expectedOperations), len(res.Operations)) + for idx, actualOp := range res.Operations { + assert.Equal(t, expectedOperations[idx].Name, actualOp) + } }) } func TestGetOperationsFailureGRPC(t *testing.T) { withServerAndClient(t, func(server *grpcServer, client *grpcClient) { - server.spanReader.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), "trifle").Return(nil, errStorageGRPC).Once() + server.spanReader.On("GetOperations", + mock.AnythingOfType("*context.valueCtx"), + &spanstore.OperationQueryParameters{ServiceName: "trifle"}, + ).Return(nil, errStorageGRPC).Once() _, err := client.GetOperations(context.Background(), &api_v2.GetOperationsRequest{ Service: "trifle", diff --git a/cmd/query/app/http_handler_test.go b/cmd/query/app/http_handler_test.go index 444106636ec..986dcb5a746 100644 --- a/cmd/query/app/http_handler_test.go +++ b/cmd/query/app/http_handler_test.go @@ -32,7 +32,7 @@ import ( testHttp "github.com/stretchr/testify/http" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - jaeger "github.com/uber/jaeger-client-go" + "github.com/uber/jaeger-client-go" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -483,17 +483,17 @@ func TestGetServicesStorageFailure(t *testing.T) { func TestGetOperationsSuccess(t *testing.T) { server, readMock, _ := initializeTestServer() defer server.Close() - expectedOperations := []string{"", "get"} - readMock.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), "abc/trifle").Return(expectedOperations, nil).Once() + expectedOperations := []*spanstore.Operation{{Name: ""}, {Name: "get", SpanKind: "server"}} + readMock.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), + &spanstore.OperationQueryParameters{ServiceName: "abc/trifle"}).Return(expectedOperations, nil).Once() var response structuredResponse err := getJSON(server.URL+"/api/operations?service=abc%2Ftrifle", &response) assert.NoError(t, err) - actualOperations := make([]string, len(expectedOperations)) for i, s := range response.Data.([]interface{}) { - actualOperations[i] = s.(string) + assert.Equal(t, expectedOperations[i].Name, s.(string)) } - assert.Equal(t, expectedOperations, actualOperations) + } func TestGetOperationsNoServiceName(t *testing.T) { @@ -506,9 +506,12 @@ func TestGetOperationsNoServiceName(t *testing.T) { } func TestGetOperationsStorageFailure(t *testing.T) { - server, reaMock, _ := initializeTestServer() + server, readMock, _ := initializeTestServer() defer server.Close() - reaMock.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), "trifle").Return(nil, errStorage).Once() + readMock.On( + "GetOperations", + mock.AnythingOfType("*context.valueCtx"), + mock.AnythingOfType("*spanstore.OperationQueryParameters")).Return(nil, errStorage).Once() var response structuredResponse err := getJSON(server.URL+"/api/operations?service=trifle", &response) @@ -518,8 +521,16 @@ func TestGetOperationsStorageFailure(t *testing.T) { func TestGetOperationsLegacySuccess(t *testing.T) { server, readMock, _ := initializeTestServer() defer server.Close() - expectedOperations := []string{"", "get"} - readMock.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), "abc/trifle").Return(expectedOperations, nil).Once() + expectedOperationNames := []string{"", "get"} + expectedOperations := []*spanstore.Operation{{Name: ""}, {Name: "get", SpanKind: "server"}} + readMock.On("GetOperations", + mock.AnythingOfType("*context.valueCtx"), + "abc/trifle", + ).Return(expectedOperationNames, nil).Once() + readMock.On( + "GetOperations", + mock.AnythingOfType("*context.valueCtx"), + mock.AnythingOfType("*spanstore.OperationQueryParameters")).Return(expectedOperations, nil).Once() var response structuredResponse err := getJSON(server.URL+"/api/services/abc%2Ftrifle/operations", &response) @@ -528,14 +539,16 @@ func TestGetOperationsLegacySuccess(t *testing.T) { for i, s := range response.Data.([]interface{}) { actualOperations[i] = s.(string) } - assert.Equal(t, expectedOperations, actualOperations) + assert.Equal(t, expectedOperationNames, actualOperations) } func TestGetOperationsLegacyStorageFailure(t *testing.T) { server, readMock, _ := initializeTestServer() defer server.Close() - readMock.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), "trifle").Return(nil, errStorage).Once() - + readMock.On( + "GetOperations", + mock.AnythingOfType("*context.valueCtx"), + mock.AnythingOfType("*spanstore.OperationQueryParameters")).Return(nil, errStorage).Once() var response structuredResponse err := getJSON(server.URL+"/api/services/trifle/operations", &response) assert.Error(t, err) diff --git a/cmd/query/app/querysvc/query_service.go b/cmd/query/app/querysvc/query_service.go index 05c38647cf7..ddc34c295ed 100644 --- a/cmd/query/app/querysvc/query_service.go +++ b/cmd/query/app/querysvc/query_service.go @@ -80,7 +80,18 @@ func (qs QueryService) GetServices(ctx context.Context) ([]string, error) { // GetOperations is the queryService implementation of spanstore.Reader.GetOperations func (qs QueryService) GetOperations(ctx context.Context, service string) ([]string, error) { - return qs.spanReader.GetOperations(ctx, service) + operations, err := qs.spanReader.GetOperations(ctx, &spanstore.OperationQueryParameters{ + ServiceName: service, + }) + if err != nil { + return nil, err + } + + names := make([]string, len(operations)) + for idx, operation := range operations { + names[idx] = operation.Name + } + return names, err } // FindTraces is the queryService implementation of spanstore.Reader.FindTraces diff --git a/cmd/query/app/querysvc/query_service_test.go b/cmd/query/app/querysvc/query_service_test.go index 05a84810aa4..fdd0c742f6c 100644 --- a/cmd/query/app/querysvc/query_service_test.go +++ b/cmd/query/app/querysvc/query_service_test.go @@ -147,14 +147,17 @@ func TestGetServices(t *testing.T) { // Test QueryService.GetOperations() for success. func TestGetOperations(t *testing.T) { qs, readMock, _ := initializeTestService() - expectedOperations := []string{"", "get"} - readMock.On("GetOperations", mock.AnythingOfType("*context.valueCtx"), "abc/trifle").Return(expectedOperations, nil).Once() + expectedOperationNames := []string{"", "get"} + expectedOperations := []*spanstore.Operation{{Name: ""}, {Name: "get", SpanKind: "server"}} + readMock.On("GetOperations", + mock.AnythingOfType("*context.valueCtx"), + mock.AnythingOfType("*spanstore.OperationQueryParameters")).Return(expectedOperations, nil).Once() type contextKey string ctx := context.Background() actualOperations, err := qs.GetOperations(context.WithValue(ctx, contextKey("foo"), "bar"), "abc/trifle") assert.NoError(t, err) - assert.Equal(t, expectedOperations, actualOperations) + assert.Equal(t, expectedOperationNames, actualOperations) } // Test QueryService.FindTraces() for success. diff --git a/plugin/storage/badger/spanstore/cache.go b/plugin/storage/badger/spanstore/cache.go index 36f1bb6d044..9aac7c6d944 100644 --- a/plugin/storage/badger/spanstore/cache.go +++ b/plugin/storage/badger/spanstore/cache.go @@ -20,6 +20,8 @@ import ( "time" "github.com/dgraph-io/badger" + + "github.com/jaegertracing/jaeger/storage/spanstore" ) // CacheStore saves expensive calculations from the K/V store @@ -125,8 +127,8 @@ func (c *CacheStore) Update(service, operation string, expireTime uint64) { c.cacheLock.Unlock() } -// GetOperations returns all operations for a specific service traced by Jaeger -func (c *CacheStore) GetOperations(service string) ([]string, error) { +// GetOperations returns all operations for a specific service & spanKind traced by Jaeger +func (c *CacheStore) GetOperations(service string) ([]*spanstore.Operation, error) { operations := make([]string, 0, len(c.services)) t := uint64(time.Now().Unix()) c.cacheLock.Lock() @@ -137,7 +139,7 @@ func (c *CacheStore) GetOperations(service string) ([]string, error) { // Expired, remove delete(c.services, service) delete(c.operations, service) - return operations, nil // empty slice rather than nil + return []*spanstore.Operation{}, nil // empty slice rather than nil } for o, e := range c.operations[service] { if e > t { @@ -150,7 +152,14 @@ func (c *CacheStore) GetOperations(service string) ([]string, error) { sort.Strings(operations) - return operations, nil + //TODO: return the operations with actual spanKind + result := make([]*spanstore.Operation, 0, len(operations)) + for _, op := range operations { + result = append(result, &spanstore.Operation{ + Name: op, + }) + } + return result, nil } // GetServices returns all services traced by Jaeger diff --git a/plugin/storage/badger/spanstore/read_write_test.go b/plugin/storage/badger/spanstore/read_write_test.go index d6422edc6ef..59fbe92a455 100644 --- a/plugin/storage/badger/spanstore/read_write_test.go +++ b/plugin/storage/badger/spanstore/read_write_test.go @@ -331,7 +331,8 @@ func TestMenuSeeks(t *testing.T) { } } - operations, err := sr.GetOperations(context.Background(), "service-1") + operations, err := sr.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: "service-1", SpanKind: ""}) assert.NoError(t, err) serviceList, err := sr.GetServices(context.Background()) diff --git a/plugin/storage/badger/spanstore/reader.go b/plugin/storage/badger/spanstore/reader.go index a329e98e6f3..1249eec645a 100644 --- a/plugin/storage/badger/spanstore/reader.go +++ b/plugin/storage/badger/spanstore/reader.go @@ -237,8 +237,9 @@ func (r *TraceReader) GetServices(ctx context.Context) ([]string, error) { } // GetOperations fetches operations in the service and empty slice if service does not exists -func (r *TraceReader) GetOperations(ctx context.Context, service string) ([]string, error) { - return r.cache.GetOperations(service) +func (r *TraceReader) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { + return r.cache.GetOperations(query.ServiceName) } // setQueryDefaults alters the query with defaults if certain parameters are not set diff --git a/plugin/storage/cassandra/spanstore/operation_names.go b/plugin/storage/cassandra/spanstore/operation_names.go index 71a8215c4ed..f3c8d5f9b8f 100644 --- a/plugin/storage/cassandra/spanstore/operation_names.go +++ b/plugin/storage/cassandra/spanstore/operation_names.go @@ -50,7 +50,8 @@ type tableMeta struct { queryByKindStmt string queryStmt string createWriteQuery func(query cassandra.Query, service, kind, opName string) cassandra.Query - getOperations func(s *OperationNamesStorage, query *spanstore.OperationQueryParameters) ([]*spanstore.Operation, error) + getOperations func(s *OperationNamesStorage, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) } func (t *tableMeta) materialize() { @@ -126,10 +127,8 @@ func NewOperationNamesStorage( } // Write saves Operation and Service name tuples -func (s *OperationNamesStorage) Write(serviceName string, operationName string) error { +func (s *OperationNamesStorage) Write(serviceName, operationName, spanKind string) error { var err error - //TODO: take spanKind from args - spanKind := "" if inCache := checkWriteCache(serviceName+"|"+spanKind+"|"+operationName, s.operationNames, s.writeCacheTTL); !inCache { q := s.table.createWriteQuery(s.session.Query(s.table.insertStmt), serviceName, spanKind, operationName) @@ -142,20 +141,11 @@ func (s *OperationNamesStorage) Write(serviceName string, operationName string) } // GetOperations returns all operations for a specific service traced by Jaeger -func (s *OperationNamesStorage) GetOperations(service string) ([]string, error) { - operations, err := s.table.getOperations(s, &spanstore.OperationQueryParameters{ - ServiceName: service, +func (s *OperationNamesStorage) GetOperations(query *spanstore.OperationQueryParameters) ([]*spanstore.Operation, error) { + return s.table.getOperations(s, &spanstore.OperationQueryParameters{ + ServiceName: query.ServiceName, + SpanKind: query.SpanKind, }) - - if err != nil { - return nil, err - } - //TODO: return operations instead of list of string - operationNames := make([]string, len(operations)) - for idx, operation := range operations { - operationNames[idx] = operation.Name - } - return operationNames, err } func tableExist(session cassandra.Session, tableName string) bool { diff --git a/plugin/storage/cassandra/spanstore/operation_names_test.go b/plugin/storage/cassandra/spanstore/operation_names_test.go index 91b0e812e2e..1f7ac373f8c 100644 --- a/plugin/storage/cassandra/spanstore/operation_names_test.go +++ b/plugin/storage/cassandra/spanstore/operation_names_test.go @@ -28,6 +28,7 @@ import ( "github.com/jaegertracing/jaeger/pkg/cassandra/mocks" "github.com/jaegertracing/jaeger/pkg/testutils" + "github.com/jaegertracing/jaeger/storage/spanstore" ) type operationNameStorageTest struct { @@ -49,6 +50,9 @@ func withOperationNamesStorage(writeCacheTTL time.Duration, query := &mocks.Query{} session.On("Query", fmt.Sprintf(tableCheckStmt, schemas[latestVersion].tableName), mock.Anything).Return(query) + session.On("Query", + fmt.Sprintf(tableCheckStmt, schemas[latestVersion].tableName), + mock.Anything).Return(query) if schemaVersion != latestVersion { query.On("Exec").Return(errors.New("new table does not exist")) } else { @@ -98,12 +102,14 @@ func TestOperationNamesStorageWrite(t *testing.T) { s.session.On("Query", mock.AnythingOfType("string"), mock.Anything).Return(query) - err := s.storage.Write("service-a", "Operation-b") + err := s.storage.Write("service-a", "Operation-b", "") assert.NoError(t, err) - err = s.storage.Write("service-c", "operation-d") + err = s.storage.Write("service-c", "operation-d", "") assert.EqualError(t, err, - "failed to Exec query 'select from "+schemas[test.schemaVersion].tableName+"': exec error") + "failed to Exec query 'select from "+ + schemas[test.schemaVersion].tableName+ + "': exec error") assert.Equal(t, map[string]string{ "level": "error", "msg": "Failed to exec query", @@ -119,7 +125,7 @@ func TestOperationNamesStorageWrite(t *testing.T) { }, counts, "after first two writes") // write again - err = s.storage.Write("service-a", "Operation-b") + err = s.storage.Write("service-a", "Operation-b", "") assert.NoError(t, err) counts2, _ := s.metricsFactory.Snapshot() @@ -168,16 +174,22 @@ func TestOperationNamesStorageGetServices(t *testing.T) { query.On("Iter").Return(iter) s.session.On("Query", mock.AnythingOfType("string"), mock.Anything).Return(query) - services, err := s.storage.GetOperations("service-a") + services, err := s.storage.GetOperations(&spanstore.OperationQueryParameters{ + ServiceName: "service-a", + }) if test.expErr == nil { assert.NoError(t, err) - // expect empty string because mock iter.Scan(&placeholder) does not write to `placeholder` - assert.Equal(t, []string{""}, services) + // expect one empty operation result + // because mock iter.Scan(&placeholder) does not write to `placeholder` + assert.Equal(t, []*spanstore.Operation{{}}, services) } else { - assert.EqualError(t, err, + assert.EqualError( + t, + err, fmt.Sprintf("Error reading %s from storage: %s", schemas[test.schemaVersion].tableName, - test.expErr.Error())) + test.expErr.Error()), + ) } }) }) diff --git a/plugin/storage/cassandra/spanstore/reader.go b/plugin/storage/cassandra/spanstore/reader.go index f89026d480e..3cdbff48220 100644 --- a/plugin/storage/cassandra/spanstore/reader.go +++ b/plugin/storage/cassandra/spanstore/reader.go @@ -91,7 +91,7 @@ var ( type serviceNamesReader func() ([]string, error) -type operationNamesReader func(service string) ([]string, error) +type operationNamesReader func(query *spanstore.OperationQueryParameters) ([]*spanstore.Operation, error) type spanReaderMetrics struct { readTraces *casMetrics.Table @@ -143,8 +143,9 @@ func (s *SpanReader) GetServices(ctx context.Context) ([]string, error) { } // GetOperations returns all operations for a specific service traced by Jaeger -func (s *SpanReader) GetOperations(ctx context.Context, service string) ([]string, error) { - return s.operationNamesReader(service) +func (s *SpanReader) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { + return s.operationNamesReader(query) } func (s *SpanReader) readTrace(ctx context.Context, traceID dbmodel.TraceID) (*model.Trace, error) { diff --git a/plugin/storage/cassandra/spanstore/reader_test.go b/plugin/storage/cassandra/spanstore/reader_test.go index 24e2af007cf..a8090a82a19 100644 --- a/plugin/storage/cassandra/spanstore/reader_test.go +++ b/plugin/storage/cassandra/spanstore/reader_test.go @@ -47,7 +47,9 @@ type spanReaderTest struct { func withSpanReader(fn func(r *spanReaderTest)) { session := &mocks.Session{} query := &mocks.Query{} - session.On("Query", fmt.Sprintf(tableCheckStmt, schemas[latestVersion].tableName), mock.Anything).Return(query) + session.On("Query", + fmt.Sprintf(tableCheckStmt, schemas[latestVersion].tableName), + mock.Anything).Return(query) query.On("Exec").Return(nil) logger, logBuffer := testutils.NewLogger() metricsFactory := metricstest.NewFactory(0) @@ -73,10 +75,19 @@ func TestSpanReaderGetServices(t *testing.T) { func TestSpanReaderGetOperations(t *testing.T) { withSpanReader(func(r *spanReaderTest) { - r.reader.operationNamesReader = func(string) ([]string, error) { return []string{"operation-a"}, nil } - s, err := r.reader.GetOperations(context.Background(), "service-x") + r.reader.operationNamesReader = + func(parameters *spanstore.OperationQueryParameters) ([]*spanstore.Operation, error) { + return []*spanstore.Operation{ + { + Name: "operation-a", + SpanKind: "server", + }, + }, nil + } + s, err := r.reader.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: "service-x", SpanKind: "server"}) assert.NoError(t, err) - assert.Equal(t, []string{"operation-a"}, s) + assert.Equal(t, []*spanstore.Operation{{Name: "operation-a", SpanKind: "server"}}, s) }) } @@ -333,12 +344,24 @@ func TestSpanReaderFindTraces(t *testing.T) { return loadQuery } - r.session.On("Query", stringMatcher(queryByServiceName), matchEverything()).Return(mainQuery) - r.session.On("Query", stringMatcher(queryByTag), matchEverything()).Return(tagsQuery) - r.session.On("Query", stringMatcher(queryByServiceAndOperationName), matchEverything()).Return(operationQuery) - r.session.On("Query", stringMatcher(queryByDuration), matchEverything()).Return(durationQuery) - r.session.On("Query", stringMatcher("SELECT trace_id"), matchOnce()).Return(makeLoadQuery()) - r.session.On("Query", stringMatcher("SELECT trace_id"), matchEverything()).Return(makeLoadQuery()) + r.session.On("Query", + stringMatcher(queryByServiceName), + matchEverything()).Return(mainQuery) + r.session.On("Query", + stringMatcher(queryByTag), + matchEverything()).Return(tagsQuery) + r.session.On("Query", + stringMatcher(queryByServiceAndOperationName), + matchEverything()).Return(operationQuery) + r.session.On("Query", + stringMatcher(queryByDuration), + matchEverything()).Return(durationQuery) + r.session.On("Query", + stringMatcher("SELECT trace_id"), + matchOnce()).Return(makeLoadQuery()) + r.session.On("Query", + stringMatcher("SELECT trace_id"), + matchEverything()).Return(makeLoadQuery()) queryParams := &spanstore.TraceQueryParameters{ ServiceName: "service-a", @@ -368,7 +391,11 @@ func TestSpanReaderFindTraces(t *testing.T) { assert.EqualError(t, err, testCase.expectedError) } for _, expectedLog := range testCase.expectedLogs { - assert.True(t, strings.Contains(r.logBuffer.String(), expectedLog), "Log must contain %s, but was %s", expectedLog, r.logBuffer.String()) + assert.True(t, + strings.Contains(r.logBuffer.String(), expectedLog), + "Log must contain %s, "+"but was %s", + expectedLog, + r.logBuffer.String()) } if len(testCase.expectedLogs) == 0 { assert.Equal(t, "", r.logBuffer.String()) diff --git a/plugin/storage/cassandra/spanstore/writer.go b/plugin/storage/cassandra/spanstore/writer.go index 712ad53ba3d..3ea10e75482 100644 --- a/plugin/storage/cassandra/spanstore/writer.go +++ b/plugin/storage/cassandra/spanstore/writer.go @@ -73,7 +73,7 @@ const ( type storageMode uint8 type serviceNamesWriter func(serviceName string) error -type operationNamesWriter func(serviceName, operationName string) error +type operationNamesWriter func(serviceName, operationName, spanKind string) error type spanWriterMetrics struct { traces *casMetrics.Table @@ -172,7 +172,8 @@ func (s *SpanWriter) writeSpan(span *model.Span, ds *dbmodel.Span) error { } func (s *SpanWriter) writeIndexes(span *model.Span, ds *dbmodel.Span) error { - if err := s.saveServiceNameAndOperationName(ds.ServiceName, ds.OperationName); err != nil { + spanKind, _ := span.GetSpanKind() + if err := s.saveServiceNameAndOperationName(ds.ServiceName, ds.OperationName, spanKind); err != nil { // should this be a soft failure? return s.logError(ds, err, "Failed to insert service name and operation name", s.logger) } @@ -274,9 +275,9 @@ func (s *SpanWriter) logError(span *dbmodel.Span, err error, msg string, logger return errors.Wrap(err, msg) } -func (s *SpanWriter) saveServiceNameAndOperationName(serviceName, operationName string) error { +func (s *SpanWriter) saveServiceNameAndOperationName(serviceName, operationName, spanKind string) error { if err := s.serviceNamesWriter(serviceName); err != nil { return err } - return s.operationNamesWriter(serviceName, operationName) + return s.operationNamesWriter(serviceName, operationName, spanKind) } diff --git a/plugin/storage/cassandra/spanstore/writer_test.go b/plugin/storage/cassandra/spanstore/writer_test.go index 460125e42ac..6e1bb136b55 100644 --- a/plugin/storage/cassandra/spanstore/writer_test.go +++ b/plugin/storage/cassandra/spanstore/writer_test.go @@ -45,7 +45,9 @@ func withSpanWriter(writeCacheTTL time.Duration, fn func(w *spanWriterTest), opt ) { session := &mocks.Session{} query := &mocks.Query{} - session.On("Query", fmt.Sprintf(tableCheckStmt, schemas[latestVersion].tableName), mock.Anything).Return(query) + session.On("Query", + fmt.Sprintf(tableCheckStmt, schemas[latestVersion].tableName), + mock.Anything).Return(query) query.On("Exec").Return(nil) logger, logBuffer := testutils.NewLogger() metricsFactory := metricstest.NewFactory(0) @@ -192,13 +194,20 @@ func TestSpanWriter(t *testing.T) { // note: using matchOnce below because we only want one tag to be inserted w.session.On("Query", stringMatcher(insertTag), matchOnce()).Return(tagsQuery) - w.session.On("Query", stringMatcher(serviceNameIndex), matchEverything()).Return(serviceNameQuery) - w.session.On("Query", stringMatcher(serviceOperationIndex), matchEverything()).Return(serviceOperationNameQuery) + w.session.On("Query", + stringMatcher(serviceNameIndex), + matchEverything()).Return(serviceNameQuery) + w.session.On("Query", + stringMatcher(serviceOperationIndex), + matchEverything()).Return(serviceOperationNameQuery) - w.session.On("Query", stringMatcher(durationIndex), matchOnce()).Return(durationNoOperationQuery) + w.session.On("Query", + stringMatcher(durationIndex), + matchOnce()).Return(durationNoOperationQuery) w.writer.serviceNamesWriter = func(serviceName string) error { return testCase.serviceNameError } - w.writer.operationNamesWriter = func(serviceName, operationName string) error { return testCase.serviceNameError } + w.writer.operationNamesWriter = + func(serviceName, operationName, spanKind string) error { return testCase.serviceNameError } err := w.writer.WriteSpan(span) if testCase.expectedError == "" { @@ -207,7 +216,11 @@ func TestSpanWriter(t *testing.T) { assert.EqualError(t, err, testCase.expectedError) } for _, expectedLog := range testCase.expectedLogs { - assert.True(t, strings.Contains(w.logBuffer.String(), expectedLog), "Log must contain %s, but was %s", expectedLog, w.logBuffer.String()) + assert.True(t, + strings.Contains(w.logBuffer.String(), expectedLog), + "Log must contain %s, but was %s", + expectedLog, + w.logBuffer.String()) } if len(testCase.expectedLogs) == 0 { assert.Equal(t, "", w.logBuffer.String()) @@ -226,16 +239,16 @@ func TestSpanWriterSaveServiceNameAndOperationName(t *testing.T) { }{ { serviceNamesWriter: func(serviceName string) error { return nil }, - operationNamesWriter: func(serviceName, operationName string) error { return nil }, + operationNamesWriter: func(serviceName, operationName, spanKind string) error { return nil }, }, { serviceNamesWriter: func(serviceName string) error { return expectedErr }, - operationNamesWriter: func(serviceName, operationName string) error { return nil }, + operationNamesWriter: func(serviceName, operationName, spanKind string) error { return nil }, expectedError: "some error", }, { serviceNamesWriter: func(serviceName string) error { return nil }, - operationNamesWriter: func(serviceName, operationName string) error { return expectedErr }, + operationNamesWriter: func(serviceName, operationName, spanKind string) error { return expectedErr }, expectedError: "some error", }, } @@ -244,7 +257,7 @@ func TestSpanWriterSaveServiceNameAndOperationName(t *testing.T) { withSpanWriter(0, func(w *spanWriterTest) { w.writer.serviceNamesWriter = testCase.serviceNamesWriter w.writer.operationNamesWriter = testCase.operationNamesWriter - err := w.writer.saveServiceNameAndOperationName("service", "operation") + err := w.writer.saveServiceNameAndOperationName("service", "operation", "") if testCase.expectedError == "" { assert.NoError(t, err) } else { @@ -285,7 +298,7 @@ func TestStorageMode_IndexOnly(t *testing.T) { withSpanWriter(0, func(w *spanWriterTest) { w.writer.serviceNamesWriter = func(serviceName string) error { return nil } - w.writer.operationNamesWriter = func(serviceName, operationName string) error { return nil } + w.writer.operationNamesWriter = func(serviceName, operationName, spanKind string) error { return nil } span := &model.Span{ TraceID: model.NewTraceID(0, 1), Process: &model.Process{ @@ -306,7 +319,9 @@ func TestStorageMode_IndexOnly(t *testing.T) { durationNoOperationQuery.On("Exec").Return(nil) w.session.On("Query", stringMatcher(serviceNameIndex), matchEverything()).Return(serviceNameQuery) - w.session.On("Query", stringMatcher(serviceOperationIndex), matchEverything()).Return(serviceOperationNameQuery) + w.session.On("Query", + stringMatcher(serviceOperationIndex), + matchEverything()).Return(serviceOperationNameQuery) w.session.On("Query", stringMatcher(durationIndex), matchOnce()).Return(durationNoOperationQuery) err := w.writer.WriteSpan(span) @@ -328,7 +343,7 @@ func TestStorageMode_IndexOnly_WithFilter(t *testing.T) { withSpanWriter(0, func(w *spanWriterTest) { w.writer.indexFilter = filterEverything w.writer.serviceNamesWriter = func(serviceName string) error { return nil } - w.writer.operationNamesWriter = func(serviceName, operationName string) error { return nil } + w.writer.operationNamesWriter = func(serviceName, operationName, spanKind string) error { return nil } span := &model.Span{ TraceID: model.NewTraceID(0, 1), Process: &model.Process{ @@ -348,7 +363,7 @@ func TestStorageMode_IndexOnly_FirehoseSpan(t *testing.T) { withSpanWriter(0, func(w *spanWriterTest) { w.writer.serviceNamesWriter = func(serviceName string) error { return nil } - w.writer.operationNamesWriter = func(serviceName, operationName string) error { return nil } + w.writer.operationNamesWriter = func(serviceName, operationName, spanKind string) error { return nil } span := &model.Span{ TraceID: model.NewTraceID(0, 1), Process: &model.Process{ diff --git a/plugin/storage/es/spanstore/reader.go b/plugin/storage/es/spanstore/reader.go index 1303155c551..f8b80a097bf 100644 --- a/plugin/storage/es/spanstore/reader.go +++ b/plugin/storage/es/spanstore/reader.go @@ -245,12 +245,26 @@ func (s *SpanReader) GetServices(ctx context.Context) ([]string, error) { } // GetOperations returns all operations for a specific service traced by Jaeger -func (s *SpanReader) GetOperations(ctx context.Context, service string) ([]string, error) { +func (s *SpanReader) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { span, ctx := opentracing.StartSpanFromContext(ctx, "GetOperations") defer span.Finish() currentTime := time.Now() jaegerIndices := s.timeRangeIndices(s.serviceIndexPrefix, currentTime.Add(-s.maxSpanAge), currentTime) - return s.serviceOperationStorage.getOperations(ctx, jaegerIndices, service) + operations, err := s.serviceOperationStorage.getOperations(ctx, jaegerIndices, query.ServiceName) + if err != nil { + return nil, err + } + + //TODO: return the operations with actual span kind that meet requirement + var result []*spanstore.Operation + for _, operation := range operations { + result = append(result, &spanstore.Operation{ + Name: operation, + SpanKind: "", + }) + } + return result, err } func bucketToStringArray(buckets []*elastic.AggregationBucketKeyItem) ([]string, error) { diff --git a/plugin/storage/es/spanstore/reader_test.go b/plugin/storage/es/spanstore/reader_test.go index 7f12d94cd87..5e3ac56e687 100644 --- a/plugin/storage/es/spanstore/reader_test.go +++ b/plugin/storage/es/spanstore/reader_test.go @@ -488,12 +488,11 @@ func testGet(typ string, t *testing.T) { searchResult *elastic.SearchResult searchError error expectedError string - expectedOutput []string + expectedOutput interface{} }{ { - caption: typ + " full behavior", - searchResult: &elastic.SearchResult{Aggregations: elastic.Aggregations(goodAggregations)}, - expectedOutput: []string{"123"}, + caption: typ + " full behavior", + searchResult: &elastic.SearchResult{Aggregations: elastic.Aggregations(goodAggregations)}, }, { caption: typ + " search error", @@ -506,6 +505,16 @@ func testGet(typ string, t *testing.T) { expectedError: "Could not find aggregation of " + typ, }, } + if typ == operationsAggregation { + testCases[0].expectedOutput = []*spanstore.Operation{ + { + Name: "123", + SpanKind: "", + }, + } + } else { + testCases[0].expectedOutput = []string{"123"} + } for _, tc := range testCases { testCase := tc t.Run(testCase.caption, func(t *testing.T) { @@ -525,11 +534,12 @@ func testGet(typ string, t *testing.T) { } } -func returnSearchFunc(typ string, r *spanReaderTest) ([]string, error) { +func returnSearchFunc(typ string, r *spanReaderTest) (interface{}, error) { if typ == servicesAggregation { return r.reader.GetServices(context.Background()) } else if typ == operationsAggregation { - return r.reader.GetOperations(context.Background(), "someService") + return r.reader.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: "someService", SpanKind: ""}) } else if typ == traceIDAggregation { return r.reader.findTraceIDs(context.Background(), &spanstore.TraceQueryParameters{}) } diff --git a/plugin/storage/es/spanstore/service_operation_test.go b/plugin/storage/es/spanstore/service_operation_test.go index 6ebbf194502..2b16c8597bf 100644 --- a/plugin/storage/es/spanstore/service_operation_test.go +++ b/plugin/storage/es/spanstore/service_operation_test.go @@ -26,6 +26,7 @@ import ( "github.com/jaegertracing/jaeger/pkg/es/mocks" "github.com/jaegertracing/jaeger/plugin/storage/es/spanstore/dbmodel" + "github.com/jaegertracing/jaeger/storage/spanstore" ) func TestWriteService(t *testing.T) { @@ -121,7 +122,8 @@ func TestSpanReader_GetOperationsEmptyIndex(t *testing.T) { Return(&elastic.MultiSearchResult{ Responses: []*elastic.SearchResult{}, }, nil) - services, err := r.reader.GetOperations(context.Background(), "foo") + services, err := r.reader.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: "foo", SpanKind: ""}) require.NoError(t, err) assert.Empty(t, services) }) diff --git a/plugin/storage/grpc/proto/storage.proto b/plugin/storage/grpc/proto/storage.proto index 0c347883dcf..a77ae63b65d 100644 --- a/plugin/storage/grpc/proto/storage.proto +++ b/plugin/storage/grpc/proto/storage.proto @@ -76,10 +76,17 @@ message GetServicesResponse { message GetOperationsRequest { string service = 1; + string span_kind = 2; +} + +message Operation { + string name = 1; + string span_kind = 2; } message GetOperationsResponse { - repeated string operations = 1; + repeated string operations = 1; // deprecated + repeated Operation operations_v2 = 2; } message TraceQueryParameters { diff --git a/plugin/storage/grpc/shared/grpc_client.go b/plugin/storage/grpc/shared/grpc_client.go index 89fe9e9dc86..cb6147906c3 100644 --- a/plugin/storage/grpc/shared/grpc_client.go +++ b/plugin/storage/grpc/shared/grpc_client.go @@ -104,15 +104,24 @@ func (c *grpcClient) GetServices(ctx context.Context) ([]string, error) { } // GetOperations returns the operations of a given service -func (c *grpcClient) GetOperations(ctx context.Context, service string) ([]string, error) { +func (c *grpcClient) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { resp, err := c.readerClient.GetOperations(upgradeContextWithBearerToken(ctx), &storage_v1.GetOperationsRequest{ - Service: service, + Service: query.ServiceName, + SpanKind: query.SpanKind, }) if err != nil { return nil, errors.Wrap(err, "plugin error") } - return resp.Operations, nil + operations := make([]*spanstore.Operation, len(resp.OperationsV2)) + for idx, operation := range resp.OperationsV2 { + operations[idx] = &spanstore.Operation{ + Name: operation.Name, + SpanKind: operation.SpanKind, + } + } + return operations, nil } // FindTraces retrieves traces that match the traceQuery diff --git a/plugin/storage/grpc/shared/grpc_client_test.go b/plugin/storage/grpc/shared/grpc_client_test.go index 6adacf3e27c..17cc2ea4e9b 100644 --- a/plugin/storage/grpc/shared/grpc_client_test.go +++ b/plugin/storage/grpc/shared/grpc_client_test.go @@ -124,12 +124,13 @@ func TestGRPCClientGetOperations(t *testing.T) { r.spanReader.On("GetOperations", mock.Anything, &storage_v1.GetOperationsRequest{ Service: "service-a", }).Return(&storage_v1.GetOperationsResponse{ - Operations: []string{"operation-a"}, + OperationsV2: []*storage_v1.Operation{{Name: "operation-a", SpanKind: ""}}, }, nil) - s, err := r.client.GetOperations(context.Background(), "service-a") + s, err := r.client.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: "service-a"}) assert.NoError(t, err) - assert.Equal(t, []string{"operation-a"}, s) + assert.Equal(t, []*spanstore.Operation{{Name: "operation-a", SpanKind: ""}}, s) }) } diff --git a/plugin/storage/grpc/shared/grpc_server.go b/plugin/storage/grpc/shared/grpc_server.go index 1db0ee1aa28..2681d578a94 100644 --- a/plugin/storage/grpc/shared/grpc_server.go +++ b/plugin/storage/grpc/shared/grpc_server.go @@ -78,13 +78,24 @@ func (s *grpcServer) GetServices(ctx context.Context, r *storage_v1.GetServicesR } // GetOperations returns the operations of a given service -func (s *grpcServer) GetOperations(ctx context.Context, r *storage_v1.GetOperationsRequest) (*storage_v1.GetOperationsResponse, error) { - operations, err := s.Impl.SpanReader().GetOperations(ctx, r.Service) +func (s *grpcServer) GetOperations(ctx context.Context, r *storage_v1.GetOperationsRequest) ( + *storage_v1.GetOperationsResponse, error) { + operations, err := s.Impl.SpanReader().GetOperations(ctx, &spanstore.OperationQueryParameters{ + ServiceName: r.Service, + SpanKind: r.SpanKind, + }) if err != nil { return nil, err } + grpcOperation := make([]*storage_v1.Operation, len(operations)) + for idx, operation := range operations { + grpcOperation[idx] = &storage_v1.Operation{ + Name: operation.Name, + SpanKind: operation.SpanKind, + } + } return &storage_v1.GetOperationsResponse{ - Operations: operations, + OperationsV2: grpcOperation, }, nil } diff --git a/plugin/storage/grpc/shared/grpc_server_test.go b/plugin/storage/grpc/shared/grpc_server_test.go index 01f4f2d23e2..27c93fb1e6b 100644 --- a/plugin/storage/grpc/shared/grpc_server_test.go +++ b/plugin/storage/grpc/shared/grpc_server_test.go @@ -87,14 +87,17 @@ func TestGRPCServerGetServices(t *testing.T) { func TestGRPCServerGetOperations(t *testing.T) { withGRPCServer(func(r *grpcServerTest) { - r.impl.spanReader.On("GetOperations", mock.Anything, "service-a"). - Return([]string{"operation-a"}, nil) + r.impl.spanReader.On("GetOperations", + mock.Anything, + &spanstore.OperationQueryParameters{ServiceName: "service-a"}). + Return([]*spanstore.Operation{{Name: "operation-a", SpanKind: ""}}, nil) s, err := r.server.GetOperations(context.Background(), &storage_v1.GetOperationsRequest{ Service: "service-a", }) assert.NoError(t, err) - assert.Equal(t, &storage_v1.GetOperationsResponse{Operations: []string{"operation-a"}}, s) + assert.Equal(t, &storage_v1.GetOperationsResponse{OperationsV2: []*storage_v1.Operation{{Name: "operation-a", + SpanKind: ""}}}, s) }) } diff --git a/plugin/storage/integration/integration_test.go b/plugin/storage/integration/integration_test.go index 147f01ef0f0..5054f3a45bc 100644 --- a/plugin/storage/integration/integration_test.go +++ b/plugin/storage/integration/integration_test.go @@ -149,14 +149,18 @@ func (s *StorageIntegration) testGetLargeSpan(t *testing.T) { func (s *StorageIntegration) testGetOperations(t *testing.T) { defer s.cleanUp(t) - expected := []string{"example-operation-1", "example-operation-3", "example-operation-4"} + expected := []*spanstore.Operation{ + {Name: "example-operation-1", SpanKind: ""}, + {Name: "example-operation-3", SpanKind: ""}, + {Name: "example-operation-4", SpanKind: ""}} s.loadParseAndWriteExampleTrace(t) s.refresh(t) - var actual []string + var actual []*spanstore.Operation found := s.waitForCondition(t, func(t *testing.T) bool { var err error - actual, err = s.SpanReader.GetOperations(context.Background(), "example-service-1") + actual, err = s.SpanReader.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: "example-service-1", SpanKind: ""}) require.NoError(t, err) return assert.ObjectsAreEqualValues(expected, actual) }) diff --git a/plugin/storage/integration/kafka_test.go b/plugin/storage/integration/kafka_test.go index c0ec5f3b757..dffb41642fa 100644 --- a/plugin/storage/integration/kafka_test.go +++ b/plugin/storage/integration/kafka_test.go @@ -119,7 +119,8 @@ func (r *ingester) GetServices(ctx context.Context) ([]string, error) { return nil, nil } -func (r *ingester) GetOperations(ctx context.Context, service string) ([]string, error) { +func (r *ingester) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { return nil, nil } diff --git a/plugin/storage/memory/memory.go b/plugin/storage/memory/memory.go index d4aaa4c98da..c4eb84f99d7 100644 --- a/plugin/storage/memory/memory.go +++ b/plugin/storage/memory/memory.go @@ -34,7 +34,7 @@ type Store struct { ids []*model.TraceID traces map[model.TraceID]*model.Trace services map[string]struct{} - operations map[string]map[string]struct{} + operations map[string]map[string]map[string]struct{} deduper adjuster.Adjuster config config.Configuration index int @@ -51,7 +51,7 @@ func WithConfiguration(configuration config.Configuration) *Store { ids: make([]*model.TraceID, configuration.MaxTraces), traces: map[model.TraceID]*model.Trace{}, services: map[string]struct{}{}, - operations: map[string]map[string]struct{}{}, + operations: map[string]map[string]map[string]struct{}{}, deduper: adjuster.SpanIDDeduper(), config: configuration, } @@ -118,9 +118,14 @@ func (m *Store) WriteSpan(span *model.Span) error { m.Lock() defer m.Unlock() if _, ok := m.operations[span.Process.ServiceName]; !ok { - m.operations[span.Process.ServiceName] = map[string]struct{}{} + m.operations[span.Process.ServiceName] = map[string]map[string]struct{}{} } - m.operations[span.Process.ServiceName][span.OperationName] = struct{}{} + if _, ok := m.operations[span.Process.ServiceName][span.OperationName]; !ok { + m.operations[span.Process.ServiceName][span.OperationName] = map[string]struct{}{} + } + + spanKind, _ := span.GetSpanKind() + m.operations[span.Process.ServiceName][span.OperationName][spanKind] = struct{}{} m.services[span.Process.ServiceName] = struct{}{} if _, ok := m.traces[span.TraceID]; !ok { m.traces[span.TraceID] = &model.Trace{} @@ -177,13 +182,21 @@ func (m *Store) GetServices(ctx context.Context) ([]string, error) { } // GetOperations returns the operations of a given service -func (m *Store) GetOperations(ctx context.Context, service string) ([]string, error) { +func (m *Store) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { m.RLock() defer m.RUnlock() - var retMe []string - if operations, ok := m.operations[service]; ok { - for ops := range operations { - retMe = append(retMe, ops) + var retMe []*spanstore.Operation + if operations, ok := m.operations[query.ServiceName]; ok { + for operationName, kinds := range operations { + for kind := range kinds { + if query.SpanKind == "" || query.SpanKind == kind { + retMe = append(retMe, &spanstore.Operation{ + Name: operationName, + SpanKind: kind, + }) + } + } } } return retMe, nil diff --git a/plugin/storage/memory/memory_test.go b/plugin/storage/memory/memory_test.go index 497606bacd2..40ebf952b23 100644 --- a/plugin/storage/memory/memory_test.go +++ b/plugin/storage/memory/memory_test.go @@ -39,6 +39,7 @@ var testingSpan = &model.Span{ OperationName: "operationName", Tags: model.KeyValues{ model.String("tagKey", "tagValue"), + model.String("span.kind", "client"), }, Logs: []model.Log{ { @@ -63,6 +64,7 @@ var childSpan1 = &model.Span{ OperationName: "childOperationName", Tags: model.KeyValues{ model.String("tagKey", "tagValue"), + model.String("span.kind", "server"), }, Logs: []model.Log{ { @@ -87,6 +89,7 @@ var childSpan2 = &model.Span{ OperationName: "childOperationName", Tags: model.KeyValues{ model.String("tagKey", "tagValue"), + model.String("span.kind", "local"), }, Logs: []model.Log{ { @@ -224,18 +227,39 @@ func TestStoreGetServices(t *testing.T) { }) } -func TestStoreGetOperationsFound(t *testing.T) { +func TestStoreGetAllOperationsFound(t *testing.T) { withPopulatedMemoryStore(func(store *Store) { - operations, err := store.GetOperations(context.Background(), testingSpan.Process.ServiceName) + assert.NoError(t, store.WriteSpan(testingSpan)) + assert.NoError(t, store.WriteSpan(childSpan1)) + assert.NoError(t, store.WriteSpan(childSpan2)) + assert.NoError(t, store.WriteSpan(childSpan2_1)) + operations, err := store.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: childSpan1.Process.ServiceName, SpanKind: ""}) + assert.NoError(t, err) + assert.Len(t, operations, 3) + assert.EqualValues(t, childSpan1.OperationName, (*operations[0]).Name) + }) +} + +func TestStoreGetServerOperationsFound(t *testing.T) { + withPopulatedMemoryStore(func(store *Store) { + assert.NoError(t, store.WriteSpan(testingSpan)) + assert.NoError(t, store.WriteSpan(childSpan1)) + assert.NoError(t, store.WriteSpan(childSpan2)) + assert.NoError(t, store.WriteSpan(childSpan2_1)) + operations, err := store.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: childSpan1.Process.ServiceName, SpanKind: "server"}) assert.NoError(t, err) assert.Len(t, operations, 1) - assert.EqualValues(t, testingSpan.OperationName, operations[0]) + assert.EqualValues(t, childSpan1.OperationName, operations[0].Name) + assert.EqualValues(t, "server", operations[0].SpanKind) }) } func TestStoreGetOperationsNotFound(t *testing.T) { withPopulatedMemoryStore(func(store *Store) { - operations, err := store.GetOperations(context.Background(), "notAService") + operations, err := store.GetOperations(context.Background(), + &spanstore.OperationQueryParameters{ServiceName: "notAService", SpanKind: ""}) assert.NoError(t, err) assert.Len(t, operations, 0) }) diff --git a/proto-gen/storage_v1/storage.pb.go b/proto-gen/storage_v1/storage.pb.go index 4452ef3c715..db6137ee4f5 100644 --- a/proto-gen/storage_v1/storage.pb.go +++ b/proto-gen/storage_v1/storage.pb.go @@ -349,6 +349,7 @@ func (m *GetServicesResponse) GetServices() []string { type GetOperationsRequest struct { Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` + SpanKind string `protobuf:"bytes,2,opt,name=span_kind,json=spanKind,proto3" json:"span_kind,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -394,18 +395,81 @@ func (m *GetOperationsRequest) GetService() string { return "" } -type GetOperationsResponse struct { - Operations []string `protobuf:"bytes,1,rep,name=operations,proto3" json:"operations,omitempty"` +func (m *GetOperationsRequest) GetSpanKind() string { + if m != nil { + return m.SpanKind + } + return "" +} + +type Operation struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + SpanKind string `protobuf:"bytes,2,opt,name=span_kind,json=spanKind,proto3" json:"span_kind,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } +func (m *Operation) Reset() { *m = Operation{} } +func (m *Operation) String() string { return proto.CompactTextString(m) } +func (*Operation) ProtoMessage() {} +func (*Operation) Descriptor() ([]byte, []int) { + return fileDescriptor_0d2c4ccf1453ffdb, []int{8} +} +func (m *Operation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Operation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Operation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Operation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Operation.Merge(m, src) +} +func (m *Operation) XXX_Size() int { + return m.Size() +} +func (m *Operation) XXX_DiscardUnknown() { + xxx_messageInfo_Operation.DiscardUnknown(m) +} + +var xxx_messageInfo_Operation proto.InternalMessageInfo + +func (m *Operation) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Operation) GetSpanKind() string { + if m != nil { + return m.SpanKind + } + return "" +} + +type GetOperationsResponse struct { + Operations []string `protobuf:"bytes,1,rep,name=operations,proto3" json:"operations,omitempty"` + OperationsV2 []*Operation `protobuf:"bytes,2,rep,name=operations_v2,json=operationsV2,proto3" json:"operations_v2,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + func (m *GetOperationsResponse) Reset() { *m = GetOperationsResponse{} } func (m *GetOperationsResponse) String() string { return proto.CompactTextString(m) } func (*GetOperationsResponse) ProtoMessage() {} func (*GetOperationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0d2c4ccf1453ffdb, []int{8} + return fileDescriptor_0d2c4ccf1453ffdb, []int{9} } func (m *GetOperationsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -441,6 +505,13 @@ func (m *GetOperationsResponse) GetOperations() []string { return nil } +func (m *GetOperationsResponse) GetOperationsV2() []*Operation { + if m != nil { + return m.OperationsV2 + } + return nil +} + type TraceQueryParameters struct { ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` OperationName string `protobuf:"bytes,2,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` @@ -459,7 +530,7 @@ func (m *TraceQueryParameters) Reset() { *m = TraceQueryParameters{} } func (m *TraceQueryParameters) String() string { return proto.CompactTextString(m) } func (*TraceQueryParameters) ProtoMessage() {} func (*TraceQueryParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_0d2c4ccf1453ffdb, []int{9} + return fileDescriptor_0d2c4ccf1453ffdb, []int{10} } func (m *TraceQueryParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -555,7 +626,7 @@ func (m *FindTracesRequest) Reset() { *m = FindTracesRequest{} } func (m *FindTracesRequest) String() string { return proto.CompactTextString(m) } func (*FindTracesRequest) ProtoMessage() {} func (*FindTracesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0d2c4ccf1453ffdb, []int{10} + return fileDescriptor_0d2c4ccf1453ffdb, []int{11} } func (m *FindTracesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -602,7 +673,7 @@ func (m *SpansResponseChunk) Reset() { *m = SpansResponseChunk{} } func (m *SpansResponseChunk) String() string { return proto.CompactTextString(m) } func (*SpansResponseChunk) ProtoMessage() {} func (*SpansResponseChunk) Descriptor() ([]byte, []int) { - return fileDescriptor_0d2c4ccf1453ffdb, []int{11} + return fileDescriptor_0d2c4ccf1453ffdb, []int{12} } func (m *SpansResponseChunk) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -649,7 +720,7 @@ func (m *FindTraceIDsRequest) Reset() { *m = FindTraceIDsRequest{} } func (m *FindTraceIDsRequest) String() string { return proto.CompactTextString(m) } func (*FindTraceIDsRequest) ProtoMessage() {} func (*FindTraceIDsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0d2c4ccf1453ffdb, []int{12} + return fileDescriptor_0d2c4ccf1453ffdb, []int{13} } func (m *FindTraceIDsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -696,7 +767,7 @@ func (m *FindTraceIDsResponse) Reset() { *m = FindTraceIDsResponse{} } func (m *FindTraceIDsResponse) String() string { return proto.CompactTextString(m) } func (*FindTraceIDsResponse) ProtoMessage() {} func (*FindTraceIDsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_0d2c4ccf1453ffdb, []int{13} + return fileDescriptor_0d2c4ccf1453ffdb, []int{14} } func (m *FindTraceIDsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -742,6 +813,8 @@ func init() { golang_proto.RegisterType((*GetServicesResponse)(nil), "jaeger.storage.v1.GetServicesResponse") proto.RegisterType((*GetOperationsRequest)(nil), "jaeger.storage.v1.GetOperationsRequest") golang_proto.RegisterType((*GetOperationsRequest)(nil), "jaeger.storage.v1.GetOperationsRequest") + proto.RegisterType((*Operation)(nil), "jaeger.storage.v1.Operation") + golang_proto.RegisterType((*Operation)(nil), "jaeger.storage.v1.Operation") proto.RegisterType((*GetOperationsResponse)(nil), "jaeger.storage.v1.GetOperationsResponse") golang_proto.RegisterType((*GetOperationsResponse)(nil), "jaeger.storage.v1.GetOperationsResponse") proto.RegisterType((*TraceQueryParameters)(nil), "jaeger.storage.v1.TraceQueryParameters") @@ -762,64 +835,67 @@ func init() { proto.RegisterFile("storage.proto", fileDescriptor_0d2c4ccf1453ffd func init() { golang_proto.RegisterFile("storage.proto", fileDescriptor_0d2c4ccf1453ffdb) } var fileDescriptor_0d2c4ccf1453ffdb = []byte{ - // 905 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xc7, 0x6d, 0xb2, 0x71, 0x5e, 0xd2, 0xa5, 0x9d, 0x06, 0x30, 0x16, 0x9b, 0x14, 0x43, 0xb7, - 0x05, 0x09, 0x67, 0x1b, 0x0e, 0x8b, 0x40, 0x08, 0xc8, 0xa6, 0x1b, 0x15, 0xf1, 0x67, 0xf1, 0x46, - 0xac, 0xc4, 0x22, 0xac, 0x49, 0x3c, 0xb8, 0xde, 0xc6, 0x63, 0xaf, 0x3d, 0x8e, 0x92, 0x3b, 0x1f, - 0x80, 0x23, 0x27, 0xae, 0x7c, 0x0d, 0x8e, 0x7b, 0xe4, 0xcc, 0xa1, 0xa0, 0x70, 0xe4, 0x4b, 0x20, - 0xcf, 0x8c, 0xdd, 0xfc, 0xb1, 0xb6, 0xdd, 0x8a, 0x9b, 0xe7, 0xcd, 0xef, 0xfd, 0xde, 0x9b, 0xf7, - 0xe7, 0x97, 0xc0, 0x56, 0xcc, 0x82, 0x08, 0xbb, 0xc4, 0x0c, 0xa3, 0x80, 0x05, 0x68, 0xe7, 0x09, - 0x26, 0x2e, 0x89, 0xcc, 0xcc, 0x3a, 0x39, 0xd2, 0x1b, 0x6e, 0xe0, 0x06, 0xfc, 0xb6, 0x9d, 0x7e, - 0x09, 0xa0, 0xde, 0x72, 0x83, 0xc0, 0x1d, 0x93, 0x36, 0x3f, 0x0d, 0x93, 0x1f, 0xdb, 0xcc, 0xf3, - 0x49, 0xcc, 0xb0, 0x1f, 0x4a, 0x40, 0x73, 0x15, 0xe0, 0x24, 0x11, 0x66, 0x5e, 0x40, 0xe5, 0x7d, - 0xcd, 0x0f, 0x1c, 0x32, 0x16, 0x07, 0xe3, 0x57, 0x05, 0x5e, 0xed, 0x13, 0xd6, 0x23, 0x21, 0xa1, - 0x0e, 0xa1, 0x23, 0x8f, 0xc4, 0x16, 0x79, 0x9a, 0x90, 0x98, 0xa1, 0x7b, 0x00, 0x31, 0xc3, 0x11, - 0xb3, 0xd3, 0x00, 0x9a, 0xb2, 0xa7, 0x1c, 0xd6, 0x3a, 0xba, 0x29, 0xc8, 0xcd, 0x8c, 0xdc, 0x1c, - 0x64, 0xd1, 0xbb, 0xea, 0xb3, 0xf3, 0xd6, 0x4b, 0x3f, 0xff, 0xd5, 0x52, 0xac, 0x2a, 0xf7, 0x4b, - 0x6f, 0xd0, 0x27, 0xa0, 0x12, 0xea, 0x08, 0x8a, 0x8d, 0x17, 0xa0, 0xa8, 0x10, 0xea, 0xa4, 0x76, - 0x63, 0x08, 0xaf, 0xad, 0xe5, 0x17, 0x87, 0x01, 0x8d, 0x09, 0xea, 0x43, 0xdd, 0x59, 0xb0, 0x6b, - 0xca, 0xde, 0xe6, 0x61, 0xad, 0x73, 0xcb, 0x94, 0x95, 0xc4, 0xa1, 0x67, 0x4f, 0x3a, 0x66, 0xee, - 0x3a, 0xfb, 0xc2, 0xa3, 0x67, 0xdd, 0x52, 0x1a, 0xc2, 0x5a, 0x72, 0x34, 0x3e, 0x82, 0xed, 0x47, - 0x91, 0xc7, 0xc8, 0xc3, 0x10, 0xd3, 0xec, 0xf5, 0x07, 0x50, 0x8a, 0x43, 0x4c, 0xe5, 0xbb, 0x77, - 0x57, 0x48, 0x39, 0x92, 0x03, 0x8c, 0x5d, 0xd8, 0x59, 0x70, 0x16, 0xa9, 0x19, 0x14, 0x5e, 0xee, - 0x13, 0x36, 0x88, 0xf0, 0x88, 0x64, 0x84, 0x8f, 0x41, 0x65, 0xe9, 0xd9, 0xf6, 0x1c, 0x4e, 0x5a, - 0xef, 0x7e, 0x9a, 0xa6, 0xf2, 0xe7, 0x79, 0xeb, 0x3d, 0xd7, 0x63, 0xa7, 0xc9, 0xd0, 0x1c, 0x05, - 0x7e, 0x5b, 0x84, 0x49, 0x81, 0x1e, 0x75, 0xe5, 0xa9, 0x2d, 0x1a, 0xc6, 0xd9, 0x4e, 0x7a, 0xf3, - 0xf3, 0x56, 0x45, 0x7e, 0x5a, 0x15, 0xce, 0x78, 0xe2, 0x18, 0x0d, 0x40, 0x7d, 0xc2, 0x1e, 0x92, - 0x68, 0xe2, 0x8d, 0xf2, 0x0e, 0x1a, 0x47, 0xb0, 0xbb, 0x64, 0x95, 0x75, 0xd3, 0x41, 0x8d, 0xa5, - 0x8d, 0xd7, 0xac, 0x6a, 0xe5, 0x67, 0xe3, 0x0e, 0x34, 0xfa, 0x84, 0x7d, 0x1d, 0x12, 0x31, 0x32, - 0xf9, 0x30, 0x68, 0x50, 0x91, 0x18, 0x9e, 0x7c, 0xd5, 0xca, 0x8e, 0xc6, 0x5d, 0x78, 0x65, 0xc5, - 0x43, 0x86, 0x69, 0x02, 0x04, 0xb9, 0x55, 0x06, 0x5a, 0xb0, 0x18, 0xbf, 0x95, 0xa0, 0xc1, 0x1f, - 0xf2, 0x4d, 0x42, 0xa2, 0xd9, 0x03, 0x1c, 0x61, 0x9f, 0x30, 0x12, 0xc5, 0xe8, 0x4d, 0xa8, 0x4b, - 0x72, 0x9b, 0x62, 0x3f, 0x0b, 0x58, 0x93, 0xb6, 0xaf, 0xb0, 0x4f, 0xd0, 0x3e, 0xdc, 0xcc, 0x99, - 0x04, 0x68, 0x83, 0x83, 0xb6, 0x72, 0x2b, 0x87, 0x1d, 0x43, 0x89, 0x61, 0x37, 0xd6, 0x36, 0xf9, - 0x64, 0x1c, 0x99, 0x6b, 0x3b, 0x66, 0x16, 0x25, 0x60, 0x0e, 0xb0, 0x1b, 0x1f, 0x53, 0x16, 0xcd, - 0x2c, 0xee, 0x8e, 0x3e, 0x87, 0x9b, 0x17, 0x9b, 0x60, 0xfb, 0x1e, 0xd5, 0x4a, 0x2f, 0x30, 0xca, - 0xf5, 0x7c, 0x1b, 0xbe, 0xf4, 0xe8, 0x2a, 0x17, 0x9e, 0x6a, 0xe5, 0xeb, 0x71, 0xe1, 0x29, 0xba, - 0x0f, 0xf5, 0x6c, 0xb7, 0x79, 0x56, 0x37, 0x38, 0xd3, 0xeb, 0x6b, 0x4c, 0x3d, 0x09, 0x12, 0x44, - 0xbf, 0xa4, 0x44, 0xb5, 0xcc, 0x31, 0xcd, 0x69, 0x89, 0x07, 0x4f, 0xb5, 0xca, 0x75, 0x78, 0xf0, - 0x14, 0xdd, 0x02, 0xa0, 0x89, 0x6f, 0xf3, 0xa1, 0x8c, 0x35, 0x75, 0x4f, 0x39, 0x2c, 0x5b, 0x55, - 0x9a, 0xf8, 0xbc, 0xc8, 0xb1, 0x7e, 0x17, 0xaa, 0x79, 0x65, 0xd1, 0x36, 0x6c, 0x9e, 0x91, 0x99, - 0xec, 0x6d, 0xfa, 0x89, 0x1a, 0x50, 0x9e, 0xe0, 0x71, 0x92, 0xb5, 0x52, 0x1c, 0x3e, 0xdc, 0xf8, - 0x40, 0x31, 0x2c, 0xd8, 0xb9, 0xef, 0x51, 0x47, 0xd0, 0x64, 0x13, 0xf9, 0x31, 0x94, 0x9f, 0xa6, - 0x7d, 0x93, 0x1b, 0x7a, 0x70, 0xc5, 0xe6, 0x5a, 0xc2, 0xcb, 0x38, 0x06, 0x94, 0x6e, 0x6c, 0x3e, - 0xae, 0xf7, 0x4e, 0x13, 0x7a, 0x86, 0xda, 0x50, 0x4e, 0x97, 0x3a, 0xd3, 0x92, 0xa2, 0xb5, 0x97, - 0x0a, 0x22, 0x70, 0xc6, 0x00, 0x76, 0xf3, 0xd4, 0x4e, 0x7a, 0xff, 0x57, 0x72, 0x13, 0x68, 0x2c, - 0xb3, 0xca, 0x95, 0xfa, 0x01, 0xaa, 0x99, 0x86, 0x88, 0x14, 0xeb, 0xdd, 0xcf, 0xae, 0x2b, 0x22, - 0x6a, 0xce, 0xae, 0x4a, 0x15, 0x89, 0x3b, 0x4f, 0x60, 0x3b, 0x7d, 0x22, 0xd7, 0xb3, 0xe8, 0xc1, - 0x38, 0x71, 0x3d, 0x8a, 0xbe, 0x85, 0x6a, 0xae, 0x6f, 0xe8, 0xad, 0x82, 0x87, 0xac, 0x4a, 0xa7, - 0xfe, 0xf6, 0xf3, 0x41, 0xe2, 0x2d, 0x9d, 0x7f, 0x37, 0x45, 0x30, 0x8b, 0x60, 0x27, 0x0f, 0xf6, - 0x08, 0xd4, 0x4c, 0x37, 0x91, 0x51, 0x40, 0xb3, 0x22, 0xaa, 0xfa, 0x7e, 0x01, 0x66, 0xbd, 0xad, - 0x77, 0x14, 0xf4, 0x3d, 0xd4, 0x16, 0xa4, 0x10, 0xed, 0x17, 0x73, 0xaf, 0x08, 0xa8, 0x7e, 0xfb, - 0x32, 0x98, 0xec, 0xcb, 0x10, 0xb6, 0x96, 0x34, 0x10, 0x1d, 0x14, 0x3b, 0xae, 0xe9, 0xaa, 0x7e, - 0x78, 0x39, 0x50, 0xc6, 0x78, 0x0c, 0x70, 0xb1, 0x04, 0xa8, 0xa8, 0xc6, 0x6b, 0x3b, 0x72, 0xf5, - 0xf2, 0xd8, 0x50, 0x5f, 0x1c, 0x38, 0x74, 0xfb, 0x79, 0xf4, 0x17, 0x73, 0xae, 0x1f, 0x5c, 0x8a, - 0x93, 0xdd, 0xfe, 0x49, 0x01, 0x6d, 0xf9, 0x47, 0x7c, 0xa1, 0xeb, 0xa7, 0xfc, 0xd7, 0x72, 0xf1, - 0x1a, 0xbd, 0x53, 0x5c, 0x97, 0x82, 0xff, 0x29, 0xfa, 0xbb, 0x57, 0x81, 0x8a, 0x34, 0xba, 0x6f, - 0x3c, 0x9b, 0x37, 0x95, 0x3f, 0xe6, 0x4d, 0xe5, 0xef, 0x79, 0x53, 0xf9, 0xfd, 0x9f, 0xa6, 0xf2, - 0x1d, 0x48, 0x2f, 0x7b, 0x72, 0x34, 0xbc, 0xc1, 0x95, 0xee, 0xfd, 0xff, 0x02, 0x00, 0x00, 0xff, - 0xff, 0x7d, 0x2c, 0x50, 0x42, 0x9b, 0x09, 0x00, 0x00, + // 957 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4b, 0x73, 0xdb, 0x54, + 0x14, 0x46, 0x89, 0x5d, 0x5b, 0xc7, 0x4e, 0x49, 0x6e, 0x0c, 0x08, 0xd1, 0xda, 0x41, 0x90, 0x26, + 0x30, 0x83, 0x4c, 0xcc, 0x02, 0x86, 0xc7, 0x40, 0xdd, 0xa4, 0x9e, 0x00, 0x85, 0xa2, 0x66, 0xda, + 0x19, 0xca, 0xa0, 0xb9, 0x8e, 0x2e, 0x8a, 0x9a, 0xe8, 0x4a, 0x95, 0xae, 0x3c, 0x09, 0x6b, 0x7e, + 0x00, 0x4b, 0x56, 0x6c, 0xf9, 0x1b, 0x2c, 0xbb, 0x64, 0xcd, 0x22, 0x30, 0x61, 0xc9, 0x9f, 0x60, + 0xee, 0x43, 0xf2, 0x4b, 0x93, 0xa4, 0x19, 0x76, 0x3a, 0xe7, 0x7e, 0xe7, 0xbb, 0xe7, 0x71, 0xcf, + 0x67, 0xc3, 0x52, 0xca, 0xa2, 0x04, 0xfb, 0xc4, 0x8e, 0x93, 0x88, 0x45, 0x68, 0xe5, 0x09, 0x26, + 0x3e, 0x49, 0xec, 0xdc, 0x3b, 0xda, 0x32, 0x5b, 0x7e, 0xe4, 0x47, 0xe2, 0xb4, 0xcb, 0xbf, 0x24, + 0xd0, 0xec, 0xf8, 0x51, 0xe4, 0x1f, 0x91, 0xae, 0xb0, 0x86, 0xd9, 0x0f, 0x5d, 0x16, 0x84, 0x24, + 0x65, 0x38, 0x8c, 0x15, 0xa0, 0x3d, 0x0b, 0xf0, 0xb2, 0x04, 0xb3, 0x20, 0xa2, 0xea, 0xbc, 0x11, + 0x46, 0x1e, 0x39, 0x92, 0x86, 0xf5, 0xab, 0x06, 0x2f, 0x0f, 0x08, 0xdb, 0x26, 0x31, 0xa1, 0x1e, + 0xa1, 0xfb, 0x01, 0x49, 0x1d, 0xf2, 0x34, 0x23, 0x29, 0x43, 0x77, 0x00, 0x52, 0x86, 0x13, 0xe6, + 0xf2, 0x0b, 0x0c, 0x6d, 0x4d, 0xdb, 0x6c, 0xf4, 0x4c, 0x5b, 0x92, 0xdb, 0x39, 0xb9, 0xbd, 0x97, + 0xdf, 0xde, 0xaf, 0x3f, 0x3b, 0xed, 0xbc, 0xf0, 0xf3, 0x5f, 0x1d, 0xcd, 0xd1, 0x45, 0x1c, 0x3f, + 0x41, 0x9f, 0x42, 0x9d, 0x50, 0x4f, 0x52, 0x2c, 0x3c, 0x07, 0x45, 0x8d, 0x50, 0x8f, 0xfb, 0xad, + 0x21, 0xbc, 0x32, 0x97, 0x5f, 0x1a, 0x47, 0x34, 0x25, 0x68, 0x00, 0x4d, 0x6f, 0xc2, 0x6f, 0x68, + 0x6b, 0x8b, 0x9b, 0x8d, 0xde, 0x4d, 0x5b, 0x75, 0x12, 0xc7, 0x81, 0x3b, 0xea, 0xd9, 0x45, 0xe8, + 0xc9, 0x97, 0x01, 0x3d, 0xec, 0x57, 0xf8, 0x15, 0xce, 0x54, 0xa0, 0xf5, 0x11, 0x2c, 0x3f, 0x4a, + 0x02, 0x46, 0x1e, 0xc4, 0x98, 0xe6, 0xd5, 0x6f, 0x40, 0x25, 0x8d, 0x31, 0x55, 0x75, 0xaf, 0xce, + 0x90, 0x0a, 0xa4, 0x00, 0x58, 0xab, 0xb0, 0x32, 0x11, 0x2c, 0x53, 0xb3, 0x28, 0xbc, 0x38, 0x20, + 0x6c, 0x2f, 0xc1, 0xfb, 0x24, 0x27, 0x7c, 0x0c, 0x75, 0xc6, 0x6d, 0x37, 0xf0, 0x04, 0x69, 0xb3, + 0xff, 0x19, 0x4f, 0xe5, 0xcf, 0xd3, 0xce, 0x3b, 0x7e, 0xc0, 0x0e, 0xb2, 0xa1, 0xbd, 0x1f, 0x85, + 0x5d, 0x79, 0x0d, 0x07, 0x06, 0xd4, 0x57, 0x56, 0x57, 0x0e, 0x4c, 0xb0, 0xed, 0x6e, 0x9f, 0x9d, + 0x76, 0x6a, 0xea, 0xd3, 0xa9, 0x09, 0xc6, 0x5d, 0xcf, 0x6a, 0x01, 0x1a, 0x10, 0xf6, 0x80, 0x24, + 0xa3, 0x60, 0xbf, 0x98, 0xa0, 0xb5, 0x05, 0xab, 0x53, 0x5e, 0xd5, 0x37, 0x13, 0xea, 0xa9, 0xf2, + 0x89, 0x9e, 0xe9, 0x4e, 0x61, 0x5b, 0xf7, 0xa0, 0x35, 0x20, 0xec, 0xeb, 0x98, 0xc8, 0x27, 0x53, + 0x3c, 0x06, 0x03, 0x6a, 0x0a, 0x23, 0x92, 0xd7, 0x9d, 0xdc, 0x44, 0xaf, 0x81, 0xce, 0xfb, 0xe0, + 0x1e, 0x06, 0xd4, 0x13, 0x23, 0xe6, 0x74, 0x31, 0xa6, 0x5f, 0x04, 0xd4, 0xb3, 0x3e, 0x06, 0xbd, + 0xe0, 0x42, 0x08, 0x2a, 0x14, 0x87, 0x39, 0x81, 0xf8, 0x3e, 0x3f, 0xfa, 0x47, 0x78, 0x69, 0x26, + 0x19, 0x55, 0x41, 0x1b, 0x20, 0x2a, 0xbc, 0xaa, 0x86, 0x09, 0x0f, 0xba, 0x0d, 0x4b, 0x63, 0xcb, + 0x1d, 0xf5, 0x8c, 0x05, 0xf1, 0x34, 0x6e, 0xd8, 0x73, 0x4b, 0x66, 0x17, 0xec, 0x4e, 0x73, 0x1c, + 0xf2, 0xb0, 0x67, 0xfd, 0x56, 0x81, 0x96, 0x68, 0xf3, 0x37, 0x19, 0x49, 0x4e, 0xee, 0xe3, 0x04, + 0x87, 0x84, 0x91, 0x24, 0x45, 0xaf, 0x43, 0x53, 0x95, 0xee, 0x4e, 0x54, 0xd3, 0x50, 0xbe, 0xaf, + 0x78, 0x51, 0xeb, 0x70, 0xbd, 0xe0, 0x92, 0x20, 0x59, 0xd9, 0x38, 0x29, 0x01, 0xdb, 0x81, 0x0a, + 0xc3, 0x7e, 0x6a, 0x2c, 0x8a, 0xe4, 0xb6, 0x4a, 0x92, 0x2b, 0x4b, 0xc0, 0xde, 0xc3, 0x7e, 0xba, + 0x43, 0x59, 0x72, 0xe2, 0x88, 0x70, 0xf4, 0x39, 0x5c, 0x1f, 0xef, 0xa9, 0x1b, 0x06, 0xd4, 0xa8, + 0x3c, 0xc7, 0xa2, 0x35, 0x8b, 0x5d, 0xbd, 0x17, 0xd0, 0x59, 0x2e, 0x7c, 0x6c, 0x54, 0xaf, 0xc6, + 0x85, 0x8f, 0xd1, 0x5d, 0x68, 0xe6, 0xca, 0x23, 0xb2, 0xba, 0x26, 0x98, 0x5e, 0x9d, 0x63, 0xda, + 0x56, 0x20, 0x49, 0xf4, 0x0b, 0x27, 0x6a, 0xe4, 0x81, 0x3c, 0xa7, 0x29, 0x1e, 0x7c, 0x6c, 0xd4, + 0xae, 0xc2, 0x83, 0x8f, 0xd1, 0x4d, 0x00, 0x9a, 0x85, 0xae, 0x58, 0x99, 0xd4, 0xa8, 0xaf, 0x69, + 0x9b, 0x55, 0x47, 0xa7, 0x59, 0x28, 0x9a, 0x9c, 0x9a, 0xef, 0x83, 0x5e, 0x74, 0x16, 0x2d, 0xc3, + 0xe2, 0x21, 0x39, 0x51, 0xb3, 0xe5, 0x9f, 0xa8, 0x05, 0xd5, 0x11, 0x3e, 0xca, 0xf2, 0x51, 0x4a, + 0xe3, 0xc3, 0x85, 0x0f, 0x34, 0xcb, 0x81, 0x95, 0xbb, 0x01, 0xf5, 0x24, 0x4d, 0xbe, 0x2f, 0x9f, + 0x40, 0xf5, 0x29, 0x9f, 0x9b, 0xd2, 0x8f, 0x8d, 0x4b, 0x0e, 0xd7, 0x91, 0x51, 0xd6, 0x0e, 0x20, + 0xae, 0x27, 0xc5, 0x8b, 0xbf, 0x73, 0x90, 0xd1, 0x43, 0xd4, 0x85, 0x2a, 0xdf, 0x8d, 0x5c, 0xe9, + 0xca, 0x44, 0x49, 0xe9, 0x9b, 0xc4, 0x59, 0x7b, 0xb0, 0x5a, 0xa4, 0xb6, 0xbb, 0xfd, 0x7f, 0x25, + 0x37, 0x82, 0xd6, 0x34, 0xab, 0xda, 0xca, 0xef, 0x41, 0xcf, 0x15, 0x4e, 0xa6, 0xd8, 0xec, 0xdf, + 0xbe, 0xaa, 0xc4, 0xd5, 0x0b, 0xf6, 0xba, 0xd2, 0xb8, 0xb4, 0xf7, 0x04, 0x96, 0x79, 0x89, 0x42, + 0x6d, 0x93, 0xfb, 0x47, 0x99, 0x1f, 0x50, 0xf4, 0x10, 0xf4, 0x42, 0x7d, 0xd1, 0x1b, 0x25, 0x85, + 0xcc, 0x0a, 0xbb, 0xf9, 0xe6, 0xf9, 0x20, 0x59, 0x4b, 0xef, 0xdf, 0x45, 0x79, 0x99, 0x43, 0xb0, + 0x57, 0x5c, 0xf6, 0x08, 0xea, 0xb9, 0xaa, 0x23, 0xab, 0x84, 0x66, 0x46, 0xf2, 0xcd, 0xf5, 0x12, + 0xcc, 0xfc, 0x58, 0xdf, 0xd5, 0xd0, 0x77, 0xd0, 0x98, 0x10, 0x6a, 0xb4, 0x5e, 0xce, 0x3d, 0x23, + 0xef, 0xe6, 0xad, 0x8b, 0x60, 0x6a, 0x2e, 0x43, 0x58, 0x9a, 0x92, 0x51, 0xb4, 0x51, 0x1e, 0x38, + 0xa7, 0xfa, 0xe6, 0xe6, 0xc5, 0x40, 0x75, 0xc7, 0x63, 0x80, 0xf1, 0x12, 0xa0, 0xb2, 0x1e, 0xcf, + 0xed, 0xc8, 0xe5, 0xdb, 0xe3, 0x42, 0x73, 0xf2, 0xc1, 0xa1, 0x5b, 0xe7, 0xd1, 0x8f, 0xdf, 0xb9, + 0xb9, 0x71, 0x21, 0x4e, 0x4d, 0xfb, 0x27, 0x0d, 0x8c, 0xe9, 0xbf, 0x18, 0x13, 0x53, 0x3f, 0x10, + 0xbf, 0xe5, 0x93, 0xc7, 0xe8, 0xad, 0xf2, 0xbe, 0x94, 0xfc, 0x8b, 0x32, 0xdf, 0xbe, 0x0c, 0x54, + 0xa6, 0xd1, 0xbf, 0xf1, 0xec, 0xac, 0xad, 0xfd, 0x71, 0xd6, 0xd6, 0xfe, 0x3e, 0x6b, 0x6b, 0xbf, + 0xff, 0xd3, 0xd6, 0xbe, 0x05, 0x15, 0xe5, 0x8e, 0xb6, 0x86, 0xd7, 0x84, 0xd2, 0xbd, 0xf7, 0x5f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0xf7, 0xe6, 0x31, 0x39, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1444,6 +1520,45 @@ func (m *GetOperationsRequest) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintStorage(dAtA, i, uint64(len(m.Service))) i += copy(dAtA[i:], m.Service) } + if len(m.SpanKind) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintStorage(dAtA, i, uint64(len(m.SpanKind))) + i += copy(dAtA[i:], m.SpanKind) + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *Operation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Operation) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintStorage(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.SpanKind) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintStorage(dAtA, i, uint64(len(m.SpanKind))) + i += copy(dAtA[i:], m.SpanKind) + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1480,6 +1595,18 @@ func (m *GetOperationsResponse) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], s) } } + if len(m.OperationsV2) > 0 { + for _, msg := range m.OperationsV2 { + dAtA[i] = 0x12 + i++ + i = encodeVarintStorage(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -1826,6 +1953,30 @@ func (m *GetOperationsRequest) Size() (n int) { if l > 0 { n += 1 + l + sovStorage(uint64(l)) } + l = len(m.SpanKind) + if l > 0 { + n += 1 + l + sovStorage(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Operation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovStorage(uint64(l)) + } + l = len(m.SpanKind) + if l > 0 { + n += 1 + l + sovStorage(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -1844,6 +1995,12 @@ func (m *GetOperationsResponse) Size() (n int) { n += 1 + l + sovStorage(uint64(l)) } } + if len(m.OperationsV2) > 0 { + for _, e := range m.OperationsV2 { + l = e.Size() + n += 1 + l + sovStorage(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2610,6 +2767,156 @@ func (m *GetOperationsRequest) Unmarshal(dAtA []byte) error { } m.Service = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpanKind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStorage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStorage + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStorage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpanKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStorage(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStorage + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthStorage + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Operation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStorage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Operation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Operation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStorage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStorage + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStorage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpanKind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStorage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStorage + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStorage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpanKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipStorage(dAtA[iNdEx:]) @@ -2696,6 +3003,40 @@ func (m *GetOperationsResponse) Unmarshal(dAtA []byte) error { } m.Operations = append(m.Operations, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OperationsV2", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStorage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStorage + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStorage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OperationsV2 = append(m.OperationsV2, &Operation{}) + if err := m.OperationsV2[len(m.OperationsV2)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipStorage(dAtA[iNdEx:]) diff --git a/storage/spanstore/interface.go b/storage/spanstore/interface.go index 6b08b58d4e3..4b1a2ba3ff2 100644 --- a/storage/spanstore/interface.go +++ b/storage/spanstore/interface.go @@ -37,7 +37,7 @@ var ( type Reader interface { GetTrace(ctx context.Context, traceID model.TraceID) (*model.Trace, error) GetServices(ctx context.Context) ([]string, error) - GetOperations(ctx context.Context, service string) ([]string, error) + GetOperations(ctx context.Context, query *OperationQueryParameters) ([]*Operation, error) FindTraces(ctx context.Context, query *TraceQueryParameters) ([]*model.Trace, error) FindTraceIDs(ctx context.Context, query *TraceQueryParameters) ([]model.TraceID, error) } diff --git a/storage/spanstore/metrics/decorator.go b/storage/spanstore/metrics/decorator.go index fcf614d93f6..907fa39ea3c 100644 --- a/storage/spanstore/metrics/decorator.go +++ b/storage/spanstore/metrics/decorator.go @@ -106,9 +106,10 @@ func (m *ReadMetricsDecorator) GetServices(ctx context.Context) ([]string, error } // GetOperations implements spanstore.Reader#GetOperations -func (m *ReadMetricsDecorator) GetOperations(ctx context.Context, service string) ([]string, error) { +func (m *ReadMetricsDecorator) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { start := time.Now() - retMe, err := m.spanReader.GetOperations(ctx, service) + retMe, err := m.spanReader.GetOperations(ctx, query) m.getOperationsMetrics.emit(err, time.Since(start), len(retMe)) return retMe, err } diff --git a/storage/spanstore/metrics/decorator_test.go b/storage/spanstore/metrics/decorator_test.go index 4f0ea790a0c..f69c5b624b2 100644 --- a/storage/spanstore/metrics/decorator_test.go +++ b/storage/spanstore/metrics/decorator_test.go @@ -36,13 +36,17 @@ func TestSuccessfulUnderlyingCalls(t *testing.T) { mrs := NewReadMetricsDecorator(&mockReader, mf) mockReader.On("GetServices", context.Background()).Return([]string{}, nil) mrs.GetServices(context.Background()) - mockReader.On("GetOperations", context.Background(), "something").Return([]string{}, nil) - mrs.GetOperations(context.Background(), "something") + operationQuery := &spanstore.OperationQueryParameters{ServiceName: "something", SpanKind: ""} + mockReader.On("GetOperations", context.Background(), operationQuery). + Return([]*spanstore.Operation{}, nil) + mrs.GetOperations(context.Background(), operationQuery) mockReader.On("GetTrace", context.Background(), model.TraceID{}).Return(&model.Trace{}, nil) mrs.GetTrace(context.Background(), model.TraceID{}) - mockReader.On("FindTraces", context.Background(), &spanstore.TraceQueryParameters{}).Return([]*model.Trace{}, nil) + mockReader.On("FindTraces", context.Background(), &spanstore.TraceQueryParameters{}). + Return([]*model.Trace{}, nil) mrs.FindTraces(context.Background(), &spanstore.TraceQueryParameters{}) - mockReader.On("FindTraceIDs", context.Background(), &spanstore.TraceQueryParameters{}).Return([]model.TraceID{}, nil) + mockReader.On("FindTraceIDs", context.Background(), &spanstore.TraceQueryParameters{}). + Return([]model.TraceID{}, nil) mrs.FindTraceIDs(context.Background(), &spanstore.TraceQueryParameters{}) counters, gauges := mf.Snapshot() expecteds := map[string]int64{ @@ -70,7 +74,12 @@ func TestSuccessfulUnderlyingCalls(t *testing.T) { checkExpectedExistingAndNonExistentCounters(t, counters, expecteds, gauges, existingKeys, nonExistentKeys) } -func checkExpectedExistingAndNonExistentCounters(t *testing.T, actualCounters, expectedCounters, actualGauges map[string]int64, existingKeys, nonExistentKeys []string) { +func checkExpectedExistingAndNonExistentCounters(t *testing.T, + actualCounters, + expectedCounters, + actualGauges map[string]int64, + existingKeys, + nonExistentKeys []string) { for k, v := range expectedCounters { assert.EqualValues(t, v, actualCounters[k], k) } @@ -91,15 +100,21 @@ func TestFailingUnderlyingCalls(t *testing.T) { mockReader := mocks.Reader{} mrs := NewReadMetricsDecorator(&mockReader, mf) - mockReader.On("GetServices", context.Background()).Return(nil, errors.New("Failure")) + mockReader.On("GetServices", context.Background()). + Return(nil, errors.New("Failure")) mrs.GetServices(context.Background()) - mockReader.On("GetOperations", context.Background(), "something").Return(nil, errors.New("Failure")) - mrs.GetOperations(context.Background(), "something") - mockReader.On("GetTrace", context.Background(), model.TraceID{}).Return(nil, errors.New("Failure")) + operationQuery := &spanstore.OperationQueryParameters{ServiceName: "something", SpanKind: ""} + mockReader.On("GetOperations", context.Background(), operationQuery). + Return(nil, errors.New("Failure")) + mrs.GetOperations(context.Background(), operationQuery) + mockReader.On("GetTrace", context.Background(), model.TraceID{}). + Return(nil, errors.New("Failure")) mrs.GetTrace(context.Background(), model.TraceID{}) - mockReader.On("FindTraces", context.Background(), &spanstore.TraceQueryParameters{}).Return(nil, errors.New("Failure")) + mockReader.On("FindTraces", context.Background(), &spanstore.TraceQueryParameters{}). + Return(nil, errors.New("Failure")) mrs.FindTraces(context.Background(), &spanstore.TraceQueryParameters{}) - mockReader.On("FindTraceIDs", context.Background(), &spanstore.TraceQueryParameters{}).Return(nil, errors.New("Failure")) + mockReader.On("FindTraceIDs", context.Background(), &spanstore.TraceQueryParameters{}). + Return(nil, errors.New("Failure")) mrs.FindTraceIDs(context.Background(), &spanstore.TraceQueryParameters{}) counters, gauges := mf.Snapshot() expecteds := map[string]int64{ diff --git a/storage/spanstore/mocks/Reader.go b/storage/spanstore/mocks/Reader.go index 0ce7ecc64c9..135f576c802 100644 --- a/storage/spanstore/mocks/Reader.go +++ b/storage/spanstore/mocks/Reader.go @@ -15,10 +15,12 @@ package mocks -import context "context" -import mock "github.com/stretchr/testify/mock" -import model "github.com/jaegertracing/jaeger/model" -import spanstore "github.com/jaegertracing/jaeger/storage/spanstore" +import ( + "context" +) +import "github.com/stretchr/testify/mock" +import "github.com/jaegertracing/jaeger/model" +import "github.com/jaegertracing/jaeger/storage/spanstore" // Reader is an autogenerated mock type for the Reader type type Reader struct { @@ -71,22 +73,24 @@ func (_m *Reader) FindTraces(ctx context.Context, query *spanstore.TraceQueryPar return r0, r1 } -// GetOperations provides a mock function with given fields: ctx, service -func (_m *Reader) GetOperations(ctx context.Context, service string) ([]string, error) { - ret := _m.Called(ctx, service) +// GetOperations provides a mock function with given fields: ctx, query +func (_m *Reader) GetOperations(ctx context.Context, query *spanstore.OperationQueryParameters) ( + []*spanstore.Operation, error) { + ret := _m.Called(ctx, query) - var r0 []string - if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok { - r0 = rf(ctx, service) + var r0 []*spanstore.Operation + if rf, ok := ret.Get(0).(func(context.Context, + *spanstore.OperationQueryParameters) []*spanstore.Operation); ok { + r0 = rf(ctx, query) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) + r0 = ret.Get(0).([]*spanstore.Operation) } } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, service) + if rf, ok := ret.Get(1).(func(context.Context, *spanstore.OperationQueryParameters) error); ok { + r1 = rf(ctx, query) } else { r1 = ret.Error(1) }