Skip to content

Commit 2046eb9

Browse files
mahadzaryab1amol-verma-allen
authored andcommitted
[grpc][v2] Implement v2 gRPC dependency reader (jaegertracing#6933)
## Which problem is this PR solving? - Towards jaegertracing#6789 ## Description of the changes - This PR implements the v2 gRPC dependency reader ## How was this change tested? - Added unit tests ## Checklist - [x] I have read https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md - [x] I have signed all commits - [x] I have added unit tests for the new functionality - [x] I have run lint and test steps successfully - for `jaeger`: `make lint test` - for `jaeger-ui`: `npm run lint` and `npm run test` Signed-off-by: Mahad Zaryab <[email protected]> Signed-off-by: amol-verma-allen <[email protected]>
1 parent fcb7787 commit 2046eb9

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

internal/storage/v2/grpc/depreader.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (c) 2025 The Jaeger Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package grpc
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"google.golang.org/grpc"
11+
12+
"github.com/jaegertracing/jaeger-idl/model/v1"
13+
"github.com/jaegertracing/jaeger/internal/storage/v2/api/depstore"
14+
"github.com/jaegertracing/jaeger/proto-gen/storage/v2"
15+
)
16+
17+
var _ depstore.Reader = (*DependencyReader)(nil)
18+
19+
type DependencyReader struct {
20+
client storage.DependencyReaderClient
21+
}
22+
23+
// NewDependencyReader creates a DependencyReader that communicates with a remote gRPC storage server.
24+
// The provided gRPC connection is used exclusively for reading dependencies, meaning it is safe
25+
// to enable instrumentation on the connection.
26+
func NewDependencyReader(conn *grpc.ClientConn) *DependencyReader {
27+
return &DependencyReader{
28+
client: storage.NewDependencyReaderClient(conn),
29+
}
30+
}
31+
32+
func (dr *DependencyReader) GetDependencies(
33+
ctx context.Context,
34+
query depstore.QueryParameters,
35+
) ([]model.DependencyLink, error) {
36+
resp, err := dr.client.GetDependencies(ctx, &storage.GetDependenciesRequest{
37+
StartTime: query.StartTime,
38+
EndTime: query.EndTime,
39+
})
40+
if err != nil {
41+
return nil, fmt.Errorf("failed to get dependencies: %w", err)
42+
}
43+
dependencies := make([]model.DependencyLink, len(resp.Dependencies))
44+
for i, dep := range resp.Dependencies {
45+
dependencies[i] = model.DependencyLink{
46+
Parent: dep.Parent,
47+
Child: dep.Child,
48+
CallCount: dep.CallCount,
49+
Source: dep.Source,
50+
}
51+
}
52+
return dependencies, nil
53+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright (c) 2025 The Jaeger Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package grpc
5+
6+
import (
7+
"context"
8+
"net"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
"google.golang.org/grpc"
14+
15+
"github.com/jaegertracing/jaeger-idl/model/v1"
16+
"github.com/jaegertracing/jaeger/internal/storage/v2/api/depstore"
17+
"github.com/jaegertracing/jaeger/proto-gen/storage/v2"
18+
)
19+
20+
// testDependenciesServer implements the storage.DependencyReaderServer interface
21+
// to simulate responses for testing.
22+
type testDependenciesServer struct {
23+
storage.UnimplementedDependencyReaderServer
24+
25+
dependencies []*storage.Dependency
26+
err error
27+
}
28+
29+
func (t *testDependenciesServer) GetDependencies(
30+
context.Context,
31+
*storage.GetDependenciesRequest,
32+
) (*storage.GetDependenciesResponse, error) {
33+
return &storage.GetDependenciesResponse{
34+
Dependencies: t.dependencies,
35+
}, t.err
36+
}
37+
38+
func startTestDependenciesServer(t *testing.T, testServer *testDependenciesServer) *grpc.ClientConn {
39+
listener, err := net.Listen("tcp", ":0")
40+
require.NoError(t, err)
41+
42+
server := grpc.NewServer()
43+
storage.RegisterDependencyReaderServer(server, testServer)
44+
45+
return startServer(t, server, listener)
46+
}
47+
48+
func TestDependencyReader_GetDependencies(t *testing.T) {
49+
tests := []struct {
50+
name string
51+
testServer *testDependenciesServer
52+
expectedDependencies []model.DependencyLink
53+
expectedError string
54+
}{
55+
{
56+
name: "success",
57+
testServer: &testDependenciesServer{
58+
dependencies: []*storage.Dependency{
59+
{
60+
Parent: "service-a",
61+
Child: "service-b",
62+
CallCount: 42,
63+
Source: "source",
64+
},
65+
{
66+
Parent: "service-c",
67+
Child: "service-d",
68+
CallCount: 24,
69+
Source: "source",
70+
},
71+
},
72+
},
73+
expectedDependencies: []model.DependencyLink{
74+
{
75+
Parent: "service-a",
76+
Child: "service-b",
77+
CallCount: 42,
78+
Source: "source",
79+
},
80+
{
81+
Parent: "service-c",
82+
Child: "service-d",
83+
CallCount: 24,
84+
Source: "source",
85+
},
86+
},
87+
},
88+
{
89+
name: "empty",
90+
testServer: &testDependenciesServer{
91+
dependencies: []*storage.Dependency{},
92+
},
93+
expectedDependencies: []model.DependencyLink{},
94+
},
95+
{
96+
name: "error",
97+
testServer: &testDependenciesServer{
98+
err: assert.AnError,
99+
},
100+
expectedError: "failed to get dependencies",
101+
},
102+
}
103+
104+
for _, test := range tests {
105+
t.Run(test.name, func(t *testing.T) {
106+
conn := startTestDependenciesServer(t, test.testServer)
107+
108+
reader := NewDependencyReader(conn)
109+
dependencies, err := reader.GetDependencies(context.Background(), depstore.QueryParameters{})
110+
111+
if test.expectedError != "" {
112+
require.ErrorContains(t, err, test.expectedError)
113+
} else {
114+
require.Equal(t, test.expectedDependencies, dependencies)
115+
}
116+
})
117+
}
118+
}

internal/storage/v2/grpc/tracereader_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ func startTestServer(t *testing.T, testServer *testServer) *grpc.ClientConn {
6565
server := grpc.NewServer()
6666
storage.RegisterTraceReaderServer(server, testServer)
6767

68+
return startServer(t, server, listener)
69+
}
70+
71+
func startServer(t *testing.T, server *grpc.Server, listener net.Listener) *grpc.ClientConn {
6872
go func() {
6973
server.Serve(listener)
7074
}()

0 commit comments

Comments
 (0)