diff --git a/Makefile b/Makefile index c29341b81489..e598eaae7e81 100644 --- a/Makefile +++ b/Makefile @@ -348,7 +348,7 @@ generate-zipkin-swagger: idl-submodule .PHONY: install-mockery install-mockery: - go get -u github.com/vektra/mockery + go get -u github.com/vektra/mockery/.../ .PHONY: generate-mocks generate-mocks: install-mockery diff --git a/pkg/es/client.go b/pkg/es/client.go index 30e03aa9cbb4..e3a29bf25158 100644 --- a/pkg/es/client.go +++ b/pkg/es/client.go @@ -25,6 +25,7 @@ import ( type Client interface { IndexExists(index string) IndicesExistsService CreateIndex(index string) IndicesCreateService + CreateTemplate(id string) TemplateCreateService Index() IndexService Search(indices ...string) SearchService MultiSearch() MultiSearchService @@ -42,6 +43,12 @@ type IndicesCreateService interface { Do(ctx context.Context) (*elastic.IndicesCreateResult, error) } +// TemplateCreateService is an abstraction for creating a mapping +type TemplateCreateService interface { + Body(mapping string) TemplateCreateService + Do(ctx context.Context) (*elastic.IndicesPutTemplateResponse, error) +} + // IndexService is an abstraction for elastic BulkService type IndexService interface { Index(index string) IndexService diff --git a/pkg/es/mocks/Client.go b/pkg/es/mocks/Client.go index fd4d82be9378..ff0a1febbcb4 100644 --- a/pkg/es/mocks/Client.go +++ b/pkg/es/mocks/Client.go @@ -1,6 +1,6 @@ -// Code generated by mockery v1.0.0 +// Code generated by mockery v1.0.0. DO NOT EDIT. -// Copyright (c) 2018 The Jaeger Authors. +// Copyright (c) 2019 The Jaeger Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. + package mocks import es "github.com/jaegertracing/jaeger/pkg/es" @@ -54,6 +55,22 @@ func (_m *Client) CreateIndex(index string) es.IndicesCreateService { return r0 } +// CreateTemplate provides a mock function with given fields: id +func (_m *Client) CreateTemplate(id string) es.TemplateCreateService { + ret := _m.Called(id) + + var r0 es.TemplateCreateService + if rf, ok := ret.Get(0).(func(string) es.TemplateCreateService); ok { + r0 = rf(id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(es.TemplateCreateService) + } + } + + return r0 +} + // Index provides a mock function with given fields: func (_m *Client) Index() es.IndexService { ret := _m.Called() diff --git a/pkg/es/mocks/IndexService.go b/pkg/es/mocks/IndexService.go index a17caf235333..89d373ac1d89 100644 --- a/pkg/es/mocks/IndexService.go +++ b/pkg/es/mocks/IndexService.go @@ -1,6 +1,6 @@ -// Code generated by mockery v1.0.0 +// Code generated by mockery v1.0.0. DO NOT EDIT. -// Copyright (c) 2018 The Jaeger Authors. +// Copyright (c) 2019 The Jaeger Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. + package mocks import es "github.com/jaegertracing/jaeger/pkg/es" diff --git a/pkg/es/mocks/IndicesCreateService.go b/pkg/es/mocks/IndicesCreateService.go index 5c2fcda996f5..79dc25fc4363 100644 --- a/pkg/es/mocks/IndicesCreateService.go +++ b/pkg/es/mocks/IndicesCreateService.go @@ -1,6 +1,6 @@ -// Code generated by mockery v1.0.0 +// Code generated by mockery v1.0.0. DO NOT EDIT. -// Copyright (c) 2018 The Jaeger Authors. +// Copyright (c) 2019 The Jaeger Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. + package mocks import context "context" diff --git a/pkg/es/mocks/IndicesExistsService.go b/pkg/es/mocks/IndicesExistsService.go index 432348467166..7ab21af3e256 100644 --- a/pkg/es/mocks/IndicesExistsService.go +++ b/pkg/es/mocks/IndicesExistsService.go @@ -1,6 +1,6 @@ -// Code generated by mockery v1.0.0 +// Code generated by mockery v1.0.0. DO NOT EDIT. -// Copyright (c) 2018 The Jaeger Authors. +// Copyright (c) 2019 The Jaeger Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. + package mocks import context "context" diff --git a/pkg/es/mocks/MultiSearchService.go b/pkg/es/mocks/MultiSearchService.go index fbb8db3d7cb2..b7bab92ddae2 100644 --- a/pkg/es/mocks/MultiSearchService.go +++ b/pkg/es/mocks/MultiSearchService.go @@ -1,6 +1,6 @@ -// Code generated by mockery v1.0.0 +// Code generated by mockery v1.0.0. DO NOT EDIT. -// Copyright (c) 2018 The Jaeger Authors. +// Copyright (c) 2019 The Jaeger Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. + package mocks import context "context" diff --git a/pkg/es/mocks/SearchService.go b/pkg/es/mocks/SearchService.go index 46d6b84c101e..83fdb63c6f0b 100644 --- a/pkg/es/mocks/SearchService.go +++ b/pkg/es/mocks/SearchService.go @@ -1,6 +1,6 @@ -// Code generated by mockery v1.0.0 +// Code generated by mockery v1.0.0. DO NOT EDIT. -// Copyright (c) 2018 The Jaeger Authors. +// Copyright (c) 2019 The Jaeger Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. + package mocks import context "context" diff --git a/pkg/es/mocks/TemplateCreateService.go b/pkg/es/mocks/TemplateCreateService.go new file mode 100644 index 000000000000..b140c4d34510 --- /dev/null +++ b/pkg/es/mocks/TemplateCreateService.go @@ -0,0 +1,67 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +// Copyright (c) 2019 The Jaeger Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +package mocks + +import context "context" +import elastic "gopkg.in/olivere/elastic.v5" +import es "github.com/jaegertracing/jaeger/pkg/es" +import mock "github.com/stretchr/testify/mock" + +// TemplateCreateService is an autogenerated mock type for the TemplateCreateService type +type TemplateCreateService struct { + mock.Mock +} + +// Body provides a mock function with given fields: mapping +func (_m *TemplateCreateService) Body(mapping string) es.TemplateCreateService { + ret := _m.Called(mapping) + + var r0 es.TemplateCreateService + if rf, ok := ret.Get(0).(func(string) es.TemplateCreateService); ok { + r0 = rf(mapping) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(es.TemplateCreateService) + } + } + + return r0 +} + +// Do provides a mock function with given fields: ctx +func (_m *TemplateCreateService) Do(ctx context.Context) (*elastic.IndicesPutTemplateResponse, error) { + ret := _m.Called(ctx) + + var r0 *elastic.IndicesPutTemplateResponse + if rf, ok := ret.Get(0).(func(context.Context) *elastic.IndicesPutTemplateResponse); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*elastic.IndicesPutTemplateResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/pkg/es/wrapper/wrapper.go b/pkg/es/wrapper/wrapper.go index 1438694396c7..bd4c409f5a52 100644 --- a/pkg/es/wrapper/wrapper.go +++ b/pkg/es/wrapper/wrapper.go @@ -45,6 +45,11 @@ func (c ClientWrapper) CreateIndex(index string) es.IndicesCreateService { return WrapESIndicesCreateService(c.client.CreateIndex(index)) } +// CreateTemplate calls this function to internal client. +func (c ClientWrapper) CreateTemplate(ttype string) es.TemplateCreateService { + return WrapESTemplateCreateService(c.client.IndexPutTemplate(ttype)) +} + // Index calls this function to internal client. func (c ClientWrapper) Index() es.IndexService { r := elastic.NewBulkIndexRequest() @@ -105,6 +110,26 @@ func (c IndicesCreateServiceWrapper) Do(ctx context.Context) (*elastic.IndicesCr return c.indicesCreateService.Do(ctx) } +// TemplateCreateServiceWrapper is a wrapper around elastic.IndicesPutTemplateService. +type TemplateCreateServiceWrapper struct { + mappingCreateService *elastic.IndicesPutTemplateService +} + +// WrapESTemplateCreateService creates an TemplateCreateService out of *elastic.IndicesPutTemplateService. +func WrapESTemplateCreateService(mappingCreateService *elastic.IndicesPutTemplateService) TemplateCreateServiceWrapper { + return TemplateCreateServiceWrapper{mappingCreateService: mappingCreateService} +} + +// Body calls this function to internal service. +func (c TemplateCreateServiceWrapper) Body(mapping string) es.TemplateCreateService { + return WrapESTemplateCreateService(c.mappingCreateService.BodyString(mapping)) +} + +// Do calls this function to internal service. +func (c TemplateCreateServiceWrapper) Do(ctx context.Context) (*elastic.IndicesPutTemplateResponse, error) { + return c.mappingCreateService.Do(ctx) +} + // --- // IndexServiceWrapper is a wrapper around elastic.ESIndexService. diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index daeef3b96e55..e588dba6dc93 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -126,20 +126,18 @@ func loadTagsFromFile(filePath string) ([]string, error) { // CreateArchiveSpanReader implements storage.ArchiveFactory func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { - cfg := f.Options.Get(archiveNamespace) - if !cfg.Enabled { + if !f.archiveConfig.IsEnabled() { return nil, nil } - return createSpanReader(f.metricsFactory, f.logger, f.archiveClient, cfg, true) + return createSpanReader(f.metricsFactory, f.logger, f.archiveClient, f.archiveConfig, true) } // CreateArchiveSpanWriter implements storage.ArchiveFactory func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - cfg := f.Options.Get(archiveNamespace) - if !cfg.Enabled { + if !f.archiveConfig.IsEnabled() { return nil, nil } - return createSpanWriter(f.metricsFactory, f.logger, f.archiveClient, cfg, true) + return createSpanWriter(f.metricsFactory, f.logger, f.archiveClient, f.archiveConfig, true) } func createSpanReader( @@ -179,7 +177,7 @@ func createSpanWriter( } spanMapping, serviceMapping := GetMappings(cfg.GetNumShards(), cfg.GetNumReplicas()) - return esSpanStore.NewSpanWriter(esSpanStore.SpanWriterParams{ + writer := esSpanStore.NewSpanWriter(esSpanStore.SpanWriterParams{ Client: client, Logger: logger, MetricsFactory: mFactory, @@ -189,9 +187,12 @@ func createSpanWriter( TagDotReplacement: cfg.GetTagDotReplacement(), Archive: archive, UseReadWriteAliases: cfg.GetUseReadWriteAliases(), - SpanMapping: spanMapping, - ServiceMapping: serviceMapping, - }), nil + }) + err := writer.CreateTemplates(spanMapping, serviceMapping) + if err != nil { + return nil, err + } + return writer, nil } // GetMappings returns span and service mappings diff --git a/plugin/storage/es/factory_test.go b/plugin/storage/es/factory_test.go index 3856678b189e..7bf9e17923ff 100644 --- a/plugin/storage/es/factory_test.go +++ b/plugin/storage/es/factory_test.go @@ -15,6 +15,7 @@ package es import ( + "context" "errors" "io/ioutil" "os" @@ -22,6 +23,7 @@ import ( "strings" "testing" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/uber/jaeger-lib/metrics" @@ -39,11 +41,17 @@ var _ storage.Factory = new(Factory) type mockClientBuilder struct { escfg.Configuration err error + createTemplateError error } func (m *mockClientBuilder) NewClient(logger *zap.Logger, metricsFactory metrics.Factory) (es.Client, error) { if m.err == nil { - return &mocks.Client{}, nil + c := &mocks.Client{} + tService := &mocks.TemplateCreateService{} + tService.On("Body", mock.Anything).Return(tService) + tService.On("Do", context.Background()).Return(nil, m.createTemplateError) + c.On("CreateTemplate", mock.Anything).Return(tService) + return c, nil } return nil, m.err } @@ -149,9 +157,20 @@ func TestFactory_LoadMapping(t *testing.T) { } } +func TestCreateTemplateError(t *testing.T) { + f := NewFactory() + f.primaryConfig = &mockClientBuilder{createTemplateError: errors.New("template-error"), Configuration: escfg.Configuration{Enabled: true}} + f.archiveConfig = &mockClientBuilder{} + err := f.Initialize(metrics.NullFactory, zap.NewNop()) + require.NoError(t, err) + w, err := f.CreateSpanWriter() + assert.Nil(t, w) + assert.Error(t, err, "template-error") +} + func TestArchiveDisabled(t *testing.T) { f := NewFactory() - f.Options.Get(archiveNamespace).Enabled = false + f.archiveConfig = &mockClientBuilder{Configuration: escfg.Configuration{Enabled: false}} w, err := f.CreateArchiveSpanWriter() assert.Nil(t, w) assert.Nil(t, err) @@ -163,10 +182,9 @@ func TestArchiveDisabled(t *testing.T) { func TestArchiveEnabled(t *testing.T) { f := NewFactory() f.primaryConfig = &mockClientBuilder{} - f.archiveConfig = &mockClientBuilder{} + f.archiveConfig = &mockClientBuilder{Configuration: escfg.Configuration{Enabled: true}} err := f.Initialize(metrics.NullFactory, zap.NewNop()) require.NoError(t, err) - f.Options.Get(archiveNamespace).Enabled = true w, err := f.CreateArchiveSpanWriter() require.NoError(t, err) assert.NotNil(t, w) diff --git a/plugin/storage/es/spanstore/writer.go b/plugin/storage/es/spanstore/writer.go index d57f9ea3e4cc..08d70c5de2c1 100644 --- a/plugin/storage/es/spanstore/writer.go +++ b/plugin/storage/es/spanstore/writer.go @@ -16,13 +16,10 @@ package spanstore import ( "context" - "sync" "time" - "github.com/pkg/errors" "github.com/uber/jaeger-lib/metrics" "go.uber.org/zap" - "gopkg.in/olivere/elastic.v5" "github.com/jaegertracing/jaeger/model" "github.com/jaegertracing/jaeger/pkg/cache" @@ -49,12 +46,9 @@ type SpanWriter struct { logger *zap.Logger writerMetrics spanWriterMetrics // TODO: build functions to wrap around each Do fn indexCache cache.Cache - indexMutex sync.Mutex serviceWriter serviceWriter spanConverter dbmodel.FromDomain spanServiceIndex spanAndServiceIndexFn - spanMapping string - serviceMapping string } // SpanWriterParams holds constructor parameters for NewSpanWriter @@ -68,8 +62,6 @@ type SpanWriterParams struct { TagDotReplacement string Archive bool UseReadWriteAliases bool - SpanMapping string - ServiceMapping string } // NewSpanWriter creates a new SpanWriter for use @@ -92,13 +84,24 @@ func NewSpanWriter(p SpanWriterParams) *SpanWriter { TTL: 48 * time.Hour, }, ), - spanMapping: p.SpanMapping, - serviceMapping: p.ServiceMapping, spanConverter: dbmodel.NewFromDomain(p.AllTagsAsFields, p.TagKeysAsFields, p.TagDotReplacement), spanServiceIndex: getSpanAndServiceIndexFn(p.Archive, p.UseReadWriteAliases, p.IndexPrefix), } } +// CreateTemplates creates index templates. +func (s *SpanWriter) CreateTemplates(spanTemplate, serviceTemplate string) error { + _, err := s.client.CreateTemplate("jaeger-span").Body(spanTemplate).Do(context.Background()) + if err != nil { + return err + } + _, err = s.client.CreateTemplate("jaeger-service").Body(serviceTemplate).Do(context.Background()) + if err != nil { + return err + } + return nil +} + // spanAndServiceIndexFn returns names of span and service indices type spanAndServiceIndexFn func(spanTime time.Time) (string, string) @@ -132,14 +135,8 @@ func (s *SpanWriter) WriteSpan(span *model.Span) error { spanIndexName, serviceIndexName := s.spanServiceIndex(span.StartTime) jsonSpan := s.spanConverter.FromDomainEmbedProcess(span) if serviceIndexName != "" { - if err := s.createIndex(serviceIndexName, s.serviceMapping, jsonSpan); err != nil { - return err - } s.writeService(serviceIndexName, jsonSpan) } - if err := s.createIndex(spanIndexName, s.spanMapping, jsonSpan); err != nil { - return err - } s.writeSpan(spanIndexName, jsonSpan) return nil } @@ -149,39 +146,6 @@ func (s *SpanWriter) Close() error { return s.client.Close() } -func (s *SpanWriter) createIndex(indexName string, mapping string, jsonSpan *dbmodel.Span) error { - if !keyInCache(indexName, s.indexCache) { - s.indexMutex.Lock() - defer s.indexMutex.Unlock() - - // re-check if index exists in case other goroutine did the job under lock for us - if keyInCache(indexName, s.indexCache) { - return nil - } - - start := time.Now() - exists, _ := s.client.IndexExists(indexName).Do(s.ctx) // don't need to check the error because the exists variable will be false anyway if there is an error - if !exists { - // if there are multiple collectors writing to the same elasticsearch host a race condition can occur - create the index multiple times - // we check for the error type to minimize errors - _, err := s.client.CreateIndex(indexName).Body(mapping).Do(s.ctx) - s.writerMetrics.indexCreate.Emit(err, time.Since(start)) - if err != nil { - eErr, ok := err.(*elastic.Error) - if !ok || eErr.Details != nil && - // ES 5.x - (eErr.Details.Type != "index_already_exists_exception" && - // ES 6.x - eErr.Details.Type != "resource_already_exists_exception") { - return s.logError(jsonSpan, err, "Failed to create index", s.logger) - } - } - } - writeCache(indexName, s.indexCache) - } - return nil -} - func keyInCache(key string, c cache.Cache) bool { return c.Get(key) != nil } @@ -197,12 +161,3 @@ func (s *SpanWriter) writeService(indexName string, jsonSpan *dbmodel.Span) { func (s *SpanWriter) writeSpan(indexName string, jsonSpan *dbmodel.Span) { s.client.Index().Index(indexName).Type(spanType).BodyJson(&jsonSpan).Add() } - -func (s *SpanWriter) logError(span *dbmodel.Span, err error, msg string, logger *zap.Logger) error { - logger. - With(zap.String("trace_id", string(span.TraceID))). - With(zap.String("span_id", string(span.SpanID))). - With(zap.Error(err)). - Error(msg) - return errors.Wrap(err, msg) -} diff --git a/plugin/storage/es/spanstore/writer_test.go b/plugin/storage/es/spanstore/writer_test.go index ae603fa03423..c4880c6a2822 100644 --- a/plugin/storage/es/spanstore/writer_test.go +++ b/plugin/storage/es/spanstore/writer_test.go @@ -15,6 +15,7 @@ package spanstore import ( + "context" "errors" "strings" "testing" @@ -108,26 +109,9 @@ func TestSpanWriter_WriteSpan(t *testing.T) { testCases := []struct { caption string serviceIndexExists bool - spanIndexExists bool - serviceIndexCreateError error - spanIndexCreateError error expectedError string expectedLogs []string }{ - { - caption: "index creation error", - - serviceIndexExists: false, - - serviceIndexCreateError: errors.New("index creation error"), - expectedError: "Failed to create index: index creation error", - expectedLogs: []string{ - `"msg":"Failed to create index"`, - `"trace_id":"1"`, - `"span_id":"0"`, - `"error":"index creation error"`, - }, - }, { caption: "span insertion error", @@ -136,21 +120,6 @@ func TestSpanWriter_WriteSpan(t *testing.T) { expectedError: "", expectedLogs: []string{}, }, - { - caption: "span index dne error", - - serviceIndexExists: true, - spanIndexExists: false, - - spanIndexCreateError: errors.New("span index creation error"), - expectedError: "Failed to create index: span index creation error", - expectedLogs: []string{ - `"msg":"Failed to create index"`, - `"trace_id":"1"`, - `"span_id":"0"`, - `"error":"span index creation error"`, - }, - }, } for _, tc := range testCases { testCase := tc @@ -173,20 +142,6 @@ func TestSpanWriter_WriteSpan(t *testing.T) { serviceIndexName := "jaeger-service-1995-04-21" serviceHash := "de3b5a8f1a79989d" - serviceExistsService := &mocks.IndicesExistsService{} - spanExistsService := &mocks.IndicesExistsService{} - - serviceExistsService.On("Do", mock.AnythingOfType("*context.emptyCtx")).Return(testCase.serviceIndexExists, nil) - spanExistsService.On("Do", mock.AnythingOfType("*context.emptyCtx")).Return(testCase.spanIndexExists, nil) - - serviceCreateService := &mocks.IndicesCreateService{} - serviceCreateService.On("Body", mock.AnythingOfType("string")).Return(serviceCreateService) - serviceCreateService.On("Do", mock.AnythingOfType("*context.emptyCtx")).Return(nil, testCase.serviceIndexCreateError) - - spanCreateService := &mocks.IndicesCreateService{} - spanCreateService.On("Body", mock.AnythingOfType("string")).Return(spanCreateService) - spanCreateService.On("Do", mock.AnythingOfType("*context.emptyCtx")).Return(nil, testCase.spanIndexCreateError) - indexService := &mocks.IndexService{} indexServicePut := &mocks.IndexService{} indexSpanPut := &mocks.IndexService{} @@ -205,10 +160,6 @@ func TestSpanWriter_WriteSpan(t *testing.T) { indexSpanPut.On("BodyJson", mock.AnythingOfType("**dbmodel.Span")).Return(indexSpanPut) indexSpanPut.On("Add") - w.client.On("IndexExists", stringMatcher(spanIndexName)).Return(spanExistsService) - w.client.On("CreateIndex", stringMatcher(spanIndexName)).Return(spanCreateService) - w.client.On("IndexExists", stringMatcher(serviceIndexName)).Return(serviceExistsService) - w.client.On("CreateIndex", stringMatcher(serviceIndexName)).Return(serviceCreateService) w.client.On("Index").Return(indexService) err = w.writer.WriteSpan(span) @@ -232,6 +183,70 @@ func TestSpanWriter_WriteSpan(t *testing.T) { } } +func TestCreateTemplates(t *testing.T) { + tests := []struct{ + err string + spanTemplateService func() *mocks.TemplateCreateService + serviceTemplateService func() *mocks.TemplateCreateService + }{ + { + spanTemplateService: func() *mocks.TemplateCreateService { + tService := &mocks.TemplateCreateService{} + tService.On("Body", mock.Anything).Return(tService) + tService.On("Do", context.Background()).Return(nil, nil) + return tService + }, + serviceTemplateService: func() *mocks.TemplateCreateService { + tService := &mocks.TemplateCreateService{} + tService.On("Body", mock.Anything).Return(tService) + tService.On("Do", context.Background()).Return(nil, nil) + return tService + }, + }, + { + err: "span-template-error", + spanTemplateService: func() *mocks.TemplateCreateService { + tService := new(mocks.TemplateCreateService) + tService.On("Body", mock.Anything).Return(tService) + tService.On("Do", context.Background()).Return(nil, errors.New("span-template-error")) + return tService + }, + serviceTemplateService: func() *mocks.TemplateCreateService { + tService := new(mocks.TemplateCreateService) + tService.On("Body", mock.Anything).Return(tService) + tService.On("Do", context.Background()).Return(nil, nil) + return tService + }, + }, + { + err: "service-template-error", + spanTemplateService: func() *mocks.TemplateCreateService { + tService := new(mocks.TemplateCreateService) + tService.On("Body", mock.Anything).Return(tService) + tService.On("Do", context.Background()).Return(nil, nil) + return tService + }, + serviceTemplateService: func() *mocks.TemplateCreateService { + tService := new(mocks.TemplateCreateService) + tService.On("Body", mock.Anything).Return(tService) + tService.On("Do", context.Background()).Return(nil, errors.New("service-template-error")) + return tService + }, + }, + } + + for _, test := range tests { + withSpanWriter(func(w *spanWriterTest) { + w.client.On("CreateTemplate", "jaeger-span").Return(test.spanTemplateService()) + w.client.On("CreateTemplate", "jaeger-service").Return(test.serviceTemplateService()) + err := w.writer.CreateTemplates(mock.Anything, mock.Anything) + if test.err != "" { + assert.Error(t, err, test.err) + } + }) + } +} + func TestSpanIndexName(t *testing.T) { date, err := time.Parse(time.RFC3339, "1995-04-21T22:08:41+00:00") require.NoError(t, err) diff --git a/plugin/storage/integration/elasticsearch_test.go b/plugin/storage/integration/elasticsearch_test.go index 619a67ff5074..9661e152ca5c 100644 --- a/plugin/storage/integration/elasticsearch_test.go +++ b/plugin/storage/integration/elasticsearch_test.go @@ -92,7 +92,7 @@ func (s *ESStorageIntegration) initSpanstore(allTagsAsFields, archive bool) { bp, _ := s.client.BulkProcessor().BulkActions(1).FlushInterval(time.Nanosecond).Do(context.Background()) client := eswrapper.WrapESClient(s.client, bp) spanMapping, serviceMapping := es.GetMappings(5, 1) - s.SpanWriter = spanstore.NewSpanWriter( + w := spanstore.NewSpanWriter( spanstore.SpanWriterParams{ Client: client, Logger: s.logger, @@ -100,10 +100,10 @@ func (s *ESStorageIntegration) initSpanstore(allTagsAsFields, archive bool) { IndexPrefix: indexPrefix, AllTagsAsFields: allTagsAsFields, TagDotReplacement: tagKeyDeDotChar, - SpanMapping: spanMapping, - ServiceMapping: serviceMapping, Archive: archive, }) + w.CreateTemplates(spanMapping, serviceMapping) + s.SpanWriter = w s.SpanReader = spanstore.NewSpanReader(spanstore.SpanReaderParams{ Client: client, Logger: s.logger,