Skip to content

Commit 2cf6213

Browse files
committed
Make ArchiveTrace button auto-configurable
## Which problem is this PR solving? - Resolves #4874 ## Description of the changes The button to archive a trace is now configured based on the state of the QueryService in addition to the UI configuration. It is now possible to request features from the QueryService to inject them into the UI. ## How was this change tested? All corresponding tests have been updated. ## 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 --------- Signed-off-by: Antonin Barthelemy <antobarth@gmail.com>
1 parent f99eae5 commit 2cf6213

File tree

5 files changed

+71
-18
lines changed

5 files changed

+71
-18
lines changed

cmd/query/app/querysvc/query_service.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ type QueryServiceOptions struct {
4141
Adjuster adjuster.Adjuster
4242
}
4343

44+
// QueryServiceFeature is a feature flag for query service
45+
type QueryServiceFeature struct {
46+
SupportArchive bool
47+
// SupportRegex bool
48+
// SupportTagFilter bool
49+
}
50+
4451
// QueryService contains span utils required by the query-service.
4552
type QueryService struct {
4653
spanReader spanstore.Reader
@@ -122,6 +129,13 @@ func (qs QueryService) GetDependencies(ctx context.Context, endTs time.Time, loo
122129
return qs.dependencyReader.GetDependencies(ctx, endTs, lookback)
123130
}
124131

132+
// GetFeatures returns the features supported by the query service.
133+
func (qs QueryService) GetFeatures() QueryServiceFeature {
134+
return QueryServiceFeature{
135+
SupportArchive: qs.options.isSupportsArchive(),
136+
}
137+
}
138+
125139
// InitArchiveStorage tries to initialize archive storage reader/writer if storage factory supports them.
126140
func (opts *QueryServiceOptions) InitArchiveStorage(storageFactory storage.Factory, logger *zap.Logger) bool {
127141
archiveFactory, ok := storageFactory.(storage.ArchiveFactory)
@@ -151,3 +165,8 @@ func (opts *QueryServiceOptions) InitArchiveStorage(storageFactory storage.Facto
151165
opts.ArchiveSpanWriter = writer
152166
return true
153167
}
168+
169+
// isSupportsArchive returns true if archive storage reader/writer are initialized.
170+
func (opts *QueryServiceOptions) isSupportsArchive() bool {
171+
return opts.ArchiveSpanReader != nil && opts.ArchiveSpanWriter != nil
172+
}

cmd/query/app/querysvc/query_service_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,24 @@ func TestGetDependencies(t *testing.T) {
285285
assert.Equal(t, expectedDependencies, actualDependencies)
286286
}
287287

288+
// Test QueryService.GetFeatures()
289+
func TestGetFeatures(t *testing.T) {
290+
tqs := initializeTestService()
291+
expectedQueryServiceFeature := QueryServiceFeature{
292+
SupportArchive: false,
293+
}
294+
assert.Equal(t, expectedQueryServiceFeature, tqs.queryService.GetFeatures())
295+
}
296+
297+
func TestGetFeaturesWithSupportsArchive(t *testing.T) {
298+
tqs := initializeTestService(withArchiveSpanReader(), withArchiveSpanWriter())
299+
300+
expectedQueryServiceFeature := QueryServiceFeature{
301+
SupportArchive: true,
302+
}
303+
assert.Equal(t, expectedQueryServiceFeature, tqs.queryService.GetFeatures())
304+
}
305+
288306
type fakeStorageFactory1 struct{}
289307

290308
type fakeStorageFactory2 struct {

cmd/query/app/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func createHTTPServer(querySvc *querysvc.QueryService, metricsQuerySvc querysvc.
172172
}
173173

174174
apiHandler.RegisterRoutes(r)
175-
RegisterStaticHandler(r, logger, queryOpts)
175+
RegisterStaticHandler(r, logger, queryOpts, querySvc.GetFeatures())
176176
var handler http.Handler = r
177177
handler = additionalHeadersHandler(handler, queryOpts.AdditionalHeaders)
178178
if queryOpts.BearerTokenPropagation {

cmd/query/app/static_handler.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/gorilla/mux"
3131
"go.uber.org/zap"
3232

33+
"github.com/jaegertracing/jaeger/cmd/query/app/querysvc"
3334
"github.com/jaegertracing/jaeger/cmd/query/app/ui"
3435
"github.com/jaegertracing/jaeger/pkg/fswatcher"
3536
"github.com/jaegertracing/jaeger/pkg/version"
@@ -44,10 +45,11 @@ var (
4445
)
4546

4647
// RegisterStaticHandler adds handler for static assets to the router.
47-
func RegisterStaticHandler(r *mux.Router, logger *zap.Logger, qOpts *QueryOptions) {
48+
func RegisterStaticHandler(r *mux.Router, logger *zap.Logger, qOpts *QueryOptions, qFeatures querysvc.QueryServiceFeature) {
4849
staticHandler, err := NewStaticAssetsHandler(qOpts.StaticAssets.Path, StaticAssetsHandlerOptions{
4950
BasePath: qOpts.BasePath,
5051
UIConfigPath: qOpts.UIConfig,
52+
Features: qFeatures,
5153
Logger: logger,
5254
LogAccess: qOpts.StaticAssets.LogAccess,
5355
})
@@ -71,12 +73,14 @@ type StaticAssetsHandlerOptions struct {
7173
BasePath string
7274
UIConfigPath string
7375
LogAccess bool
76+
Features querysvc.QueryServiceFeature
7477
Logger *zap.Logger
7578
}
7679

7780
type loadedConfig struct {
78-
regexp *regexp.Regexp
79-
config []byte
81+
regexp *regexp.Regexp
82+
backendSupportsArchive bool
83+
config []byte
8084
}
8185

8286
// NewStaticAssetsHandler returns a StaticAssetsHandler
@@ -118,7 +122,7 @@ func loadAndEnrichIndexHTML(open func(string) (http.File, error), options Static
118122
return nil, fmt.Errorf("cannot load index.html: %w", err)
119123
}
120124
// replace UI config
121-
if configObject, err := loadUIConfig(options.UIConfigPath); err != nil {
125+
if configObject, err := loadUIConfig(options.UIConfigPath, options.Features); err != nil {
122126
return nil, err
123127
} else if configObject != nil {
124128
indexBytes = configObject.regexp.ReplaceAll(indexBytes, configObject.config)
@@ -164,7 +168,7 @@ func loadIndexHTML(open func(string) (http.File, error)) ([]byte, error) {
164168
return indexBytes, nil
165169
}
166170

167-
func loadUIConfig(uiConfig string) (*loadedConfig, error) {
171+
func loadUIConfig(uiConfig string, features querysvc.QueryServiceFeature) (*loadedConfig, error) {
168172
if uiConfig == "" {
169173
return nil, nil
170174
}
@@ -185,8 +189,9 @@ func loadUIConfig(uiConfig string) (*loadedConfig, error) {
185189
r, _ = json.Marshal(c)
186190

187191
return &loadedConfig{
188-
regexp: configPattern,
189-
config: append([]byte("JAEGER_CONFIG = "), append(r, byte(';'))...),
192+
regexp: configPattern,
193+
config: append([]byte("JAEGER_CONFIG = "), append(r, byte(';'))...),
194+
backendSupportsArchive: features.SupportArchive,
190195
}, nil
191196
case ".js":
192197
r = bytes.TrimSpace(bytesConfig)
@@ -196,8 +201,9 @@ func loadUIConfig(uiConfig string) (*loadedConfig, error) {
196201
}
197202

198203
return &loadedConfig{
199-
regexp: configJsPattern,
200-
config: r,
204+
regexp: configJsPattern,
205+
config: r,
206+
backendSupportsArchive: features.SupportArchive,
201207
}, nil
202208
default:
203209
return nil, fmt.Errorf("unrecognized UI config file format, expecting .js or .json file: %v", uiConfig)

cmd/query/app/static_handler_test.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"go.uber.org/zap/zapcore"
3434
"go.uber.org/zap/zaptest/observer"
3535

36+
"github.com/jaegertracing/jaeger/cmd/query/app/querysvc"
3637
"github.com/jaegertracing/jaeger/pkg/testutils"
3738
)
3839

@@ -58,6 +59,7 @@ func TestRegisterStaticHandlerPanic(t *testing.T) {
5859
},
5960
},
6061
},
62+
querysvc.QueryServiceFeature{SupportArchive: false},
6163
)
6264
})
6365
assert.Contains(t, buf.String(), "Could not create static assets handler")
@@ -117,7 +119,9 @@ func TestRegisterStaticHandler(t *testing.T) {
117119
BasePath: testCase.basePath,
118120
UIConfig: testCase.UIConfigPath,
119121
},
120-
})
122+
},
123+
querysvc.QueryServiceFeature{SupportArchive: false},
124+
)
121125

122126
server := httptest.NewServer(r)
123127
defer server.Close()
@@ -206,13 +210,14 @@ func TestHotReloadUIConfig(t *testing.T) {
206210
func TestLoadUIConfig(t *testing.T) {
207211
type testCase struct {
208212
configFile string
213+
features querysvc.QueryServiceFeature
209214
expected *loadedConfig
210215
expectedError string
211216
}
212217

213218
run := func(description string, testCase testCase) {
214219
t.Run(description, func(t *testing.T) {
215-
config, err := loadUIConfig(testCase.configFile)
220+
config, err := loadUIConfig(testCase.configFile, testCase.features)
216221
if testCase.expectedError != "" {
217222
assert.EqualError(t, err, testCase.expectedError)
218223
} else {
@@ -237,9 +242,11 @@ func TestLoadUIConfig(t *testing.T) {
237242
})
238243
run("json", testCase{
239244
configFile: "fixture/ui-config.json",
245+
features: querysvc.QueryServiceFeature{SupportArchive: true},
240246
expected: &loadedConfig{
241-
config: []byte(`JAEGER_CONFIG = {"x":"y"};`),
242-
regexp: configPattern,
247+
config: []byte(`JAEGER_CONFIG = {"x":"y"};`),
248+
backendSupportsArchive: true,
249+
regexp: configPattern,
243250
},
244251
})
245252
c, _ := json.Marshal(map[string]interface{}{
@@ -253,8 +260,9 @@ func TestLoadUIConfig(t *testing.T) {
253260
run("json-menu", testCase{
254261
configFile: "fixture/ui-config-menu.json",
255262
expected: &loadedConfig{
256-
config: append([]byte("JAEGER_CONFIG = "), append(c, byte(';'))...),
257-
regexp: configPattern,
263+
config: append([]byte("JAEGER_CONFIG = "), append(c, byte(';'))...),
264+
backendSupportsArchive: false,
265+
regexp: configPattern,
258266
},
259267
})
260268
run("malformed js config", testCase{
@@ -264,7 +272,8 @@ func TestLoadUIConfig(t *testing.T) {
264272
run("js", testCase{
265273
configFile: "fixture/ui-config.js",
266274
expected: &loadedConfig{
267-
regexp: configJsPattern,
275+
regexp: configJsPattern,
276+
backendSupportsArchive: false,
268277
config: []byte(`function UIConfig(){
269278
return {
270279
x: "y"
@@ -275,7 +284,8 @@ func TestLoadUIConfig(t *testing.T) {
275284
run("js-menu", testCase{
276285
configFile: "fixture/ui-config-menu.js",
277286
expected: &loadedConfig{
278-
regexp: configJsPattern,
287+
regexp: configJsPattern,
288+
backendSupportsArchive: false,
279289
config: []byte(`function UIConfig(){
280290
return {
281291
menu: [

0 commit comments

Comments
 (0)