From befc6bd1e57a0c19d8cd4480a75e1be1fd2e2a38 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Fri, 17 Jan 2025 18:11:58 -0500 Subject: [PATCH 01/74] Change ES Options To Only Hold One Namespace Signed-off-by: Mahad Zaryab --- plugin/storage/es/options.go | 37 +++--------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/plugin/storage/es/options.go b/plugin/storage/es/options.go index ee52d718032..be1ecf41ad0 100644 --- a/plugin/storage/es/options.go +++ b/plugin/storage/es/options.go @@ -84,9 +84,8 @@ var defaultIndexOptions = config.IndexOptions{ // to bind them to command line flag and apply overlays, so that some configurations // (e.g. archive) may be underspecified and infer the rest of its parameters from primary. type Options struct { + // TODO: remove indirection Primary namespaceConfig `mapstructure:",squash"` - - others map[string]*namespaceConfig } type namespaceConfig struct { @@ -95,24 +94,14 @@ type namespaceConfig struct { } // NewOptions creates a new Options struct. -func NewOptions(primaryNamespace string, otherNamespaces ...string) *Options { +func NewOptions(namespace string) *Options { // TODO all default values should be defined via cobra flags defaultConfig := DefaultConfig() options := &Options{ Primary: namespaceConfig{ - Configuration: defaultConfig, - namespace: primaryNamespace, - }, - others: make(map[string]*namespaceConfig, len(otherNamespaces)), - } - - // Other namespaces need to be explicitly enabled. - defaultConfig.Enabled = false - for _, namespace := range otherNamespaces { - options.others[namespace] = &namespaceConfig{ Configuration: defaultConfig, namespace: namespace, - } + }, } return options @@ -127,9 +116,6 @@ func (cfg *namespaceConfig) getTLSFlagsConfig() tlscfg.ClientFlagsConfig { // AddFlags adds flags for Options func (opt *Options) AddFlags(flagSet *flag.FlagSet) { addFlags(flagSet, &opt.Primary) - for _, cfg := range opt.others { - addFlags(flagSet, cfg) - } } func addFlags(flagSet *flag.FlagSet, nsConfig *namespaceConfig) { @@ -305,9 +291,6 @@ func addFlags(flagSet *flag.FlagSet, nsConfig *namespaceConfig) { // InitFromViper initializes Options with properties from viper func (opt *Options) InitFromViper(v *viper.Viper) { initFromViper(&opt.Primary, v) - for _, cfg := range opt.others { - initFromViper(cfg, v) - } } func initFromViper(cfg *namespaceConfig, v *viper.Viper) { @@ -392,20 +375,6 @@ func (opt *Options) GetPrimary() *config.Configuration { return &opt.Primary.Configuration } -// Get returns auxiliary named configuration. -func (opt *Options) Get(namespace string) *config.Configuration { - nsCfg, ok := opt.others[namespace] - if !ok { - nsCfg = &namespaceConfig{} - opt.others[namespace] = nsCfg - } - nsCfg.Configuration.ApplyDefaults(&opt.Primary.Configuration) - if len(nsCfg.Configuration.Servers) == 0 { - nsCfg.Servers = opt.Primary.Servers - } - return &nsCfg.Configuration -} - // stripWhiteSpace removes all whitespace characters from a string func stripWhiteSpace(str string) string { return strings.ReplaceAll(str, " ", "") From ab1180bf8e8b5c08600b1143aa13f6703d3427e3 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Fri, 17 Jan 2025 18:22:15 -0500 Subject: [PATCH 02/74] Add Configuration Fields For Suffixes Signed-off-by: Mahad Zaryab --- pkg/es/config/config.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/es/config/config.go b/pkg/es/config/config.go index d0ae9c6ad3d..6a40a016223 100644 --- a/pkg/es/config/config.go +++ b/pkg/es/config/config.go @@ -114,7 +114,9 @@ type Configuration struct { // UseReadWriteAliases, if set to true, will use read and write aliases for indices. // Use this option with Elasticsearch rollover API. It requires an external component // to create aliases before startup and then performing its management. - UseReadWriteAliases bool `mapstructure:"use_aliases"` + UseReadWriteAliases bool `mapstructure:"use_aliases"` + ReadAliasSuffix string `mapstructure:"-"` + WriteAliasSuffix string `mapstructure:"-"` // CreateIndexTemplates, if set to true, creates index templates at application startup. // This configuration should be set to false when templates are installed manually. CreateIndexTemplates bool `mapstructure:"create_mappings"` From e1d6f7d6168bd13e89a4e2e52f747164a96cb285 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Fri, 17 Jan 2025 18:22:43 -0500 Subject: [PATCH 03/74] Adjust ES Factory To Hold One Config Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory.go | 169 ++++++++++------------------------- 1 file changed, 49 insertions(+), 120 deletions(-) diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index e1c7ae807a4..a1614da26c3 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -42,11 +42,10 @@ const ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ storage.ArchiveFactory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) - _ storage.Purger = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ storage.Purger = (*Factory)(nil) ) // Factory implements storage.Factory for Elasticsearch backend. @@ -59,11 +58,9 @@ type Factory struct { newClientFn func(c *config.Configuration, logger *zap.Logger, metricsFactory metrics.Factory) (es.Client, error) - primaryConfig *config.Configuration - archiveConfig *config.Configuration + config *config.Configuration - primaryClient atomic.Pointer[es.Client] - archiveClient atomic.Pointer[es.Client] + client atomic.Pointer[es.Client] watchers []*fswatcher.FSWatcher } @@ -71,7 +68,28 @@ type Factory struct { // NewFactory creates a new Factory. func NewFactory() *Factory { return &Factory{ - Options: NewOptions(primaryNamespace, archiveNamespace), + Options: NewOptions(primaryNamespace), + newClientFn: config.NewClient, + tracer: otel.GetTracerProvider(), + } +} + +func NewArchiveFactory() *Factory { + opts := NewOptions(archiveNamespace) + + aliasSuffix := "archive" + if opts.Primary.UseReadWriteAliases { + opts.Primary.ReadAliasSuffix = aliasSuffix + "-read" + opts.Primary.WriteAliasSuffix = aliasSuffix + "-write" + } else { + opts.Primary.ReadAliasSuffix = aliasSuffix + opts.Primary.WriteAliasSuffix = aliasSuffix + } + + opts.Primary.UseReadWriteAliases = true + + return &Factory{ + Options: opts, newClientFn: config.NewClient, tracer: otel.GetTracerProvider(), } @@ -89,20 +107,11 @@ func NewFactoryWithConfig( defaultConfig := DefaultConfig() cfg.ApplyDefaults(&defaultConfig) - archive := make(map[string]*namespaceConfig) - archive[archiveNamespace] = &namespaceConfig{ - Configuration: cfg, - namespace: archiveNamespace, + f := &Factory{ + config: &cfg, + newClientFn: config.NewClient, + tracer: otel.GetTracerProvider(), } - - f := NewFactory() - f.configureFromOptions(&Options{ - Primary: namespaceConfig{ - Configuration: cfg, - namespace: primaryNamespace, - }, - others: archive, - }) err := f.Initialize(metricsFactory, logger) if err != nil { return nil, err @@ -124,8 +133,7 @@ func (f *Factory) InitFromViper(v *viper.Viper, _ *zap.Logger) { // configureFromOptions configures factory from Options struct. func (f *Factory) configureFromOptions(o *Options) { f.Options = o - f.primaryConfig = f.Options.GetPrimary() - f.archiveConfig = f.Options.Get(archiveNamespace) + f.config = f.Options.GetPrimary() } // Initialize implements storage.Factory. @@ -133,48 +141,25 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) f.metricsFactory = metricsFactory f.logger = logger - primaryClient, err := f.newClientFn(f.primaryConfig, logger, metricsFactory) + primaryClient, err := f.newClientFn(f.config, logger, metricsFactory) if err != nil { return fmt.Errorf("failed to create primary Elasticsearch client: %w", err) } - f.primaryClient.Store(&primaryClient) + f.client.Store(&primaryClient) - if f.primaryConfig.Authentication.BasicAuthentication.PasswordFilePath != "" { - primaryWatcher, err := fswatcher.New([]string{f.primaryConfig.Authentication.BasicAuthentication.PasswordFilePath}, f.onPrimaryPasswordChange, f.logger) + if f.config.Authentication.BasicAuthentication.PasswordFilePath != "" { + primaryWatcher, err := fswatcher.New([]string{f.config.Authentication.BasicAuthentication.PasswordFilePath}, f.onPrimaryPasswordChange, f.logger) if err != nil { return fmt.Errorf("failed to create watcher for primary ES client's password: %w", err) } f.watchers = append(f.watchers, primaryWatcher) } - if f.archiveConfig.Enabled { - archiveClient, err := f.newClientFn(f.archiveConfig, logger, metricsFactory) - if err != nil { - return fmt.Errorf("failed to create archive Elasticsearch client: %w", err) - } - f.archiveClient.Store(&archiveClient) - - if f.archiveConfig.Authentication.BasicAuthentication.PasswordFilePath != "" { - archiveWatcher, err := fswatcher.New([]string{f.archiveConfig.Authentication.BasicAuthentication.PasswordFilePath}, f.onArchivePasswordChange, f.logger) - if err != nil { - return fmt.Errorf("failed to create watcher for archive ES client's password: %w", err) - } - f.watchers = append(f.watchers, archiveWatcher) - } - } - return nil } func (f *Factory) getPrimaryClient() es.Client { - if c := f.primaryClient.Load(); c != nil { - return *c - } - return nil -} - -func (f *Factory) getArchiveClient() es.Client { - if c := f.archiveClient.Load(); c != nil { + if c := f.client.Load(); c != nil { return *c } return nil @@ -182,7 +167,7 @@ func (f *Factory) getArchiveClient() es.Client { // CreateSpanReader implements storage.Factory func (f *Factory) CreateSpanReader() (spanstore.Reader, error) { - sr, err := createSpanReader(f.getPrimaryClient, f.primaryConfig, f.logger, f.tracer, "", f.primaryConfig.UseReadWriteAliases) + sr, err := createSpanReader(f.getPrimaryClient, f.config, f.logger, f.tracer, f.config.ReadAliasSuffix, f.config.UseReadWriteAliases) if err != nil { return nil, err } @@ -191,54 +176,12 @@ func (f *Factory) CreateSpanReader() (spanstore.Reader, error) { // CreateSpanWriter implements storage.Factory func (f *Factory) CreateSpanWriter() (spanstore.Writer, error) { - return createSpanWriter(f.getPrimaryClient, f.primaryConfig, f.metricsFactory, f.logger, "", f.primaryConfig.UseReadWriteAliases) + return createSpanWriter(f.getPrimaryClient, f.config, f.metricsFactory, f.logger, f.config.WriteAliasSuffix, f.config.UseReadWriteAliases) } // CreateDependencyReader implements storage.Factory func (f *Factory) CreateDependencyReader() (dependencystore.Reader, error) { - return createDependencyReader(f.getPrimaryClient, f.primaryConfig, f.logger) -} - -// CreateArchiveSpanReader implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { - if !f.archiveConfig.Enabled { - return nil, nil - } - readAliasSuffix := "archive" - if f.archiveConfig.UseReadWriteAliases { - readAliasSuffix += "-read" - } - sr, err := createSpanReader(f.getArchiveClient, f.archiveConfig, f.logger, f.tracer, readAliasSuffix, true) - if err != nil { - return nil, err - } - archiveMetricsFactory := f.metricsFactory.Namespace( - metrics.NSOptions{ - Tags: map[string]string{ - "role": "archive", - }, - }, - ) - return spanstoremetrics.NewReaderDecorator(sr, archiveMetricsFactory), nil -} - -// CreateArchiveSpanWriter implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - if !f.archiveConfig.Enabled { - return nil, nil - } - writeAliasSuffix := "archive" - if f.archiveConfig.UseReadWriteAliases { - writeAliasSuffix += "-write" - } - archiveMetricsFactory := f.metricsFactory.Namespace( - metrics.NSOptions{ - Tags: map[string]string{ - "role": "archive", - }, - }, - ) - return createSpanWriter(f.getArchiveClient, f.archiveConfig, archiveMetricsFactory, f.logger, writeAliasSuffix, true) + return createDependencyReader(f.getPrimaryClient, f.config, f.logger) } func createSpanReader( @@ -319,16 +262,16 @@ func (f *Factory) CreateSamplingStore(int /* maxBuckets */) (samplingstore.Store params := esSampleStore.Params{ Client: f.getPrimaryClient, Logger: f.logger, - IndexPrefix: f.primaryConfig.Indices.IndexPrefix, - IndexDateLayout: f.primaryConfig.Indices.Sampling.DateLayout, - IndexRolloverFrequency: config.RolloverFrequencyAsNegativeDuration(f.primaryConfig.Indices.Sampling.RolloverFrequency), - Lookback: f.primaryConfig.AdaptiveSamplingLookback, - MaxDocCount: f.primaryConfig.MaxDocCount, + IndexPrefix: f.config.Indices.IndexPrefix, + IndexDateLayout: f.config.Indices.Sampling.DateLayout, + IndexRolloverFrequency: config.RolloverFrequencyAsNegativeDuration(f.config.Indices.Sampling.RolloverFrequency), + Lookback: f.config.AdaptiveSamplingLookback, + MaxDocCount: f.config.MaxDocCount, } store := esSampleStore.NewSamplingStore(params) - if f.primaryConfig.CreateIndexTemplates && !f.primaryConfig.UseILM { - mappingBuilder := mappingBuilderFromConfig(f.primaryConfig) + if f.config.CreateIndexTemplates && !f.config.UseILM { + mappingBuilder := mappingBuilderFromConfig(f.config) samplingMapping, err := mappingBuilder.GetSamplingMappings() if err != nil { return nil, err @@ -376,26 +319,12 @@ func (f *Factory) Close() error { errs = append(errs, w.Close()) } errs = append(errs, f.getPrimaryClient().Close()) - if client := f.getArchiveClient(); client != nil { - errs = append(errs, client.Close()) - } return errors.Join(errs...) } func (f *Factory) onPrimaryPasswordChange() { - f.onClientPasswordChange(f.primaryConfig, &f.primaryClient, f.metricsFactory) -} - -func (f *Factory) onArchivePasswordChange() { - archiveMetricsFactory := f.metricsFactory.Namespace( - metrics.NSOptions{ - Tags: map[string]string{ - "role": "archive", - }, - }, - ) - f.onClientPasswordChange(f.archiveConfig, &f.archiveClient, archiveMetricsFactory) + f.onClientPasswordChange(f.config, &f.client, f.metricsFactory) } func (f *Factory) onClientPasswordChange(cfg *config.Configuration, client *atomic.Pointer[es.Client], mf metrics.Factory) { From 51726465c067ff45e895a0a4fb1b84e539b56924 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 09:21:23 -0500 Subject: [PATCH 04/74] Change Meta Factory To Initialize Archive Separately Signed-off-by: Mahad Zaryab --- plugin/storage/factory.go | 61 +++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index be1b808c46e..3fcb5f6aec4 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -85,6 +85,7 @@ type Factory struct { FactoryConfig metricsFactory metrics.Factory factories map[string]storage.Factory + archiveFactories map[string]storage.Factory downsamplingFlagsAdded bool } @@ -103,12 +104,18 @@ func NewFactory(config FactoryConfig) (*Factory, error) { uniqueTypes[f.SamplingStorageType] = struct{}{} } f.factories = make(map[string]storage.Factory) + f.archiveFactories = make(map[string]storage.Factory) for t := range uniqueTypes { ff, err := f.getFactoryOfType(t) if err != nil { return nil, err } f.factories[t] = ff + + af, err := f.getArchiveFactoryOfType(t) + if err == nil { + f.archiveFactories[t] = af + } } return f, nil } @@ -134,20 +141,38 @@ func (*Factory) getFactoryOfType(factoryType string) (storage.Factory, error) { } } +func (*Factory) getArchiveFactoryOfType(factoryType string) (storage.Factory, error) { + switch factoryType { + case elasticsearchStorageType, opensearchStorageType: + return es.NewArchiveFactory(), nil + default: + return nil, fmt.Errorf("archive storage factory not available for %s", factoryType) + } +} + // Initialize implements storage.Factory. func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) error { f.metricsFactory = metricsFactory - for kind, factory := range f.factories { - mf := metricsFactory.Namespace(metrics.NSOptions{ - Name: "storage", - Tags: map[string]string{ - "kind": kind, - "role": "primary", // can be overiden in the storage factory for archive/sampling stores - }, - }) - if err := factory.Initialize(mf, logger); err != nil { - return err + initializeFactories := func(factories map[string]storage.Factory, role string) error { + for kind, factory := range factories { + mf := metricsFactory.Namespace(metrics.NSOptions{ + Name: "storage", + Tags: map[string]string{ + "kind": kind, + "role": role, + }, + }) + if err := factory.Initialize(mf, logger); err != nil { + return err + } } + return nil + } + if err := initializeFactories(f.factories, "primary"); err != nil { + return err + } + if err := initializeFactories(f.archiveFactories, "archive"); err != nil { + return err } f.publishOpts() @@ -292,28 +317,20 @@ func (f *Factory) initDownsamplingFromViper(v *viper.Viper) { // CreateArchiveSpanReader implements storage.ArchiveFactory func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { - factory, ok := f.factories[f.SpanReaderType] + factory, ok := f.archiveFactories[f.SpanReaderType] if !ok { return nil, fmt.Errorf("no %s backend registered for span store", f.SpanReaderType) } - archive, ok := factory.(storage.ArchiveFactory) - if !ok { - return nil, storage.ErrArchiveStorageNotSupported - } - return archive.CreateArchiveSpanReader() + return factory.CreateSpanReader() } // CreateArchiveSpanWriter implements storage.ArchiveFactory func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - factory, ok := f.factories[f.SpanWriterTypes[0]] + factory, ok := f.archiveFactories[f.SpanWriterTypes[0]] if !ok { return nil, fmt.Errorf("no %s backend registered for span store", f.SpanWriterTypes[0]) } - archive, ok := factory.(storage.ArchiveFactory) - if !ok { - return nil, storage.ErrArchiveStorageNotSupported - } - return archive.CreateArchiveSpanWriter() + return factory.CreateSpanWriter() } var _ io.Closer = (*Factory)(nil) From 820b36079ce4ea11678f51b4ac8e25c8ea48bf02 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 09:33:35 -0500 Subject: [PATCH 05/74] Phase Out Distinction In Cassandra Factory Signed-off-by: Mahad Zaryab --- plugin/storage/cassandra/factory.go | 98 +++++++---------------------- plugin/storage/cassandra/options.go | 37 ++--------- plugin/storage/factory.go | 2 + 3 files changed, 30 insertions(+), 107 deletions(-) diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 884eed5a772..2db8f18654d 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -43,7 +43,6 @@ const ( var ( // interface comformance checks _ storage.Factory = (*Factory)(nil) _ storage.Purger = (*Factory)(nil) - _ storage.ArchiveFactory = (*Factory)(nil) _ storage.SamplingStoreFactory = (*Factory)(nil) _ io.Closer = (*Factory)(nil) _ plugin.Configurable = (*Factory)(nil) @@ -57,11 +56,9 @@ type Factory struct { logger *zap.Logger tracer trace.TracerProvider - primaryConfig config.Configuration - archiveConfig *config.Configuration + config config.Configuration - primarySession cassandra.Session - archiveSession cassandra.Session + session cassandra.Session // tests can override this sessionBuilderFn func(*config.Configuration) (cassandra.Session, error) @@ -71,7 +68,15 @@ type Factory struct { func NewFactory() *Factory { return &Factory{ tracer: otel.GetTracerProvider(), - Options: NewOptions(primaryStorageConfig, archiveStorageConfig), + Options: NewOptions(primaryStorageConfig), + sessionBuilderFn: NewSession, + } +} + +func NewArchiveFactory() *Factory { + return &Factory{ + tracer: otel.GetTracerProvider(), + Options: NewOptions(archiveStorageConfig), sessionBuilderFn: NewSession, } } @@ -128,12 +133,7 @@ func (f *Factory) InitFromViper(v *viper.Viper, _ *zap.Logger) { // InitFromOptions initializes factory from options. func (f *Factory) configureFromOptions(o *Options) { f.Options = o - // TODO this is a hack because we do not define defaults in Options - if o.others == nil { - o.others = make(map[string]*NamespaceConfig) - } - f.primaryConfig = o.GetPrimary() - f.archiveConfig = f.Options.Get(archiveStorageConfig) + f.config = o.GetPrimary() } // Initialize implements storage.Factory @@ -141,21 +141,12 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) f.metricsFactory = metricsFactory f.logger = logger - primarySession, err := f.sessionBuilderFn(&f.primaryConfig) + primarySession, err := f.sessionBuilderFn(&f.config) if err != nil { return err } - f.primarySession = primarySession - - if f.archiveConfig != nil { - archiveSession, err := f.sessionBuilderFn(f.archiveConfig) - if err != nil { - return err - } - f.archiveSession = archiveSession - } else { - logger.Info("Cassandra archive storage configuration is empty, skipping") - } + f.session = primarySession + return nil } @@ -203,7 +194,7 @@ func NewSession(c *config.Configuration) (cassandra.Session, error) { // CreateSpanReader implements storage.Factory func (f *Factory) CreateSpanReader() (spanstore.Reader, error) { - sr, err := cSpanStore.NewSpanReader(f.primarySession, f.metricsFactory, f.logger, f.tracer.Tracer("cSpanStore.SpanReader")) + sr, err := cSpanStore.NewSpanReader(f.session, f.metricsFactory, f.logger, f.tracer.Tracer("cSpanStore.SpanReader")) if err != nil { return nil, err } @@ -216,51 +207,13 @@ func (f *Factory) CreateSpanWriter() (spanstore.Writer, error) { if err != nil { return nil, err } - return cSpanStore.NewSpanWriter(f.primarySession, f.Options.SpanStoreWriteCacheTTL, f.metricsFactory, f.logger, options...) + return cSpanStore.NewSpanWriter(f.session, f.Options.SpanStoreWriteCacheTTL, f.metricsFactory, f.logger, options...) } // CreateDependencyReader implements storage.Factory func (f *Factory) CreateDependencyReader() (dependencystore.Reader, error) { - version := cDepStore.GetDependencyVersion(f.primarySession) - return cDepStore.NewDependencyStore(f.primarySession, f.metricsFactory, f.logger, version) -} - -// CreateArchiveSpanReader implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { - if f.archiveSession == nil { - return nil, storage.ErrArchiveStorageNotConfigured - } - archiveMetricsFactory := f.metricsFactory.Namespace( - metrics.NSOptions{ - Tags: map[string]string{ - "role": "archive", - }, - }, - ) - sr, err := cSpanStore.NewSpanReader(f.archiveSession, archiveMetricsFactory, f.logger, f.tracer.Tracer("cSpanStore.SpanReader")) - if err != nil { - return nil, err - } - return spanstoremetrics.NewReaderDecorator(sr, archiveMetricsFactory), nil -} - -// CreateArchiveSpanWriter implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - if f.archiveSession == nil { - return nil, storage.ErrArchiveStorageNotConfigured - } - options, err := writerOptions(f.Options) - if err != nil { - return nil, err - } - archiveMetricsFactory := f.metricsFactory.Namespace( - metrics.NSOptions{ - Tags: map[string]string{ - "role": "archive", - }, - }, - ) - return cSpanStore.NewSpanWriter(f.archiveSession, f.Options.SpanStoreWriteCacheTTL, archiveMetricsFactory, f.logger, options...) + version := cDepStore.GetDependencyVersion(f.session) + return cDepStore.NewDependencyStore(f.session, f.metricsFactory, f.logger, version) } // CreateLock implements storage.SamplingStoreFactory @@ -271,7 +224,7 @@ func (f *Factory) CreateLock() (distributedlock.Lock, error) { } f.logger.Info("Using unique participantName in the distributed lock", zap.String("participantName", hostId)) - return cLock.NewLock(f.primarySession, hostId), nil + return cLock.NewLock(f.session, hostId), nil } // CreateSamplingStore implements storage.SamplingStoreFactory @@ -283,7 +236,7 @@ func (f *Factory) CreateSamplingStore(int /* maxBuckets */) (samplingstore.Store }, }, ) - return cSamplingStore.New(f.primarySession, samplingMetricsFactory, f.logger), nil + return cSamplingStore.New(f.session, samplingMetricsFactory, f.logger), nil } func writerOptions(opts *Options) ([]cSpanStore.Option, error) { @@ -319,16 +272,13 @@ var _ io.Closer = (*Factory)(nil) // Close closes the resources held by the factory func (f *Factory) Close() error { - if f.primarySession != nil { - f.primarySession.Close() - } - if f.archiveSession != nil { - f.archiveSession.Close() + if f.session != nil { + f.session.Close() } return nil } func (f *Factory) Purge(_ context.Context) error { - return f.primarySession.Query("TRUNCATE traces").Exec() + return f.session.Query("TRUNCATE traces").Exec() } diff --git a/plugin/storage/cassandra/options.go b/plugin/storage/cassandra/options.go index ae2ba2d1d05..04451bb60be 100644 --- a/plugin/storage/cassandra/options.go +++ b/plugin/storage/cassandra/options.go @@ -49,9 +49,8 @@ const ( // (e.g. archive) may be underspecified and infer the rest of its parameters from primary. type Options struct { Primary NamespaceConfig `mapstructure:",squash"` - others map[string]*NamespaceConfig - SpanStoreWriteCacheTTL time.Duration `mapstructure:"span_store_write_cache_ttl"` - Index IndexConfig `mapstructure:"index"` + SpanStoreWriteCacheTTL time.Duration `mapstructure:"span_store_write_cache_ttl"` + Index IndexConfig `mapstructure:"index"` } // IndexConfig configures indexing. @@ -74,31 +73,23 @@ type NamespaceConfig struct { } // NewOptions creates a new Options struct. -func NewOptions(primaryNamespace string, otherNamespaces ...string) *Options { +func NewOptions(namespace string) *Options { // TODO all default values should be defined via cobra flags options := &Options{ Primary: NamespaceConfig{ Configuration: config.DefaultConfiguration(), - namespace: primaryNamespace, + namespace: namespace, Enabled: true, }, - others: make(map[string]*NamespaceConfig, len(otherNamespaces)), SpanStoreWriteCacheTTL: time.Hour * 12, } - for _, namespace := range otherNamespaces { - options.others[namespace] = &NamespaceConfig{namespace: namespace} - } - return options } // AddFlags adds flags for Options func (opt *Options) AddFlags(flagSet *flag.FlagSet) { addFlags(flagSet, opt.Primary) - for _, cfg := range opt.others { - addFlags(flagSet, *cfg) - } flagSet.Duration(opt.Primary.namespace+suffixSpanStoreWriteCacheTTL, opt.SpanStoreWriteCacheTTL, "The duration to wait before rewriting an existing service or operation name") @@ -206,9 +197,6 @@ func addFlags(flagSet *flag.FlagSet, nsConfig NamespaceConfig) { // InitFromViper initializes Options with properties from viper func (opt *Options) InitFromViper(v *viper.Viper) { opt.Primary.initFromViper(v) - for _, cfg := range opt.others { - cfg.initFromViper(v) - } opt.SpanStoreWriteCacheTTL = v.GetDuration(opt.Primary.namespace + suffixSpanStoreWriteCacheTTL) opt.Index.TagBlackList = stripWhiteSpace(v.GetString(opt.Primary.namespace + suffixIndexTagsBlacklist)) opt.Index.TagWhiteList = stripWhiteSpace(v.GetString(opt.Primary.namespace + suffixIndexTagsWhitelist)) @@ -260,23 +248,6 @@ func (opt *Options) GetPrimary() config.Configuration { return opt.Primary.Configuration } -// Get returns auxiliary named configuration. -func (opt *Options) Get(namespace string) *config.Configuration { - nsCfg, ok := opt.others[namespace] - if !ok { - nsCfg = &NamespaceConfig{} - opt.others[namespace] = nsCfg - } - if !nsCfg.Enabled { - return nil - } - nsCfg.Configuration.ApplyDefaults(&opt.Primary.Configuration) - if len(nsCfg.Connection.Servers) == 0 { - nsCfg.Connection.Servers = opt.Primary.Connection.Servers - } - return &nsCfg.Configuration -} - // TagIndexBlacklist returns the list of blacklisted tags func (opt *Options) TagIndexBlacklist() []string { if len(opt.Index.TagBlackList) > 0 { diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index 3fcb5f6aec4..d923758dab6 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -143,6 +143,8 @@ func (*Factory) getFactoryOfType(factoryType string) (storage.Factory, error) { func (*Factory) getArchiveFactoryOfType(factoryType string) (storage.Factory, error) { switch factoryType { + case cassandraStorageType: + return cassandra.NewArchiveFactory(), nil case elasticsearchStorageType, opensearchStorageType: return es.NewArchiveFactory(), nil default: From 6dcd07700167dc9df75bb2499a7fbf4f21529da8 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 09:45:04 -0500 Subject: [PATCH 06/74] Remove Comment Signed-off-by: Mahad Zaryab --- plugin/storage/badger/factory.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plugin/storage/badger/factory.go b/plugin/storage/badger/factory.go index 01758c2eab1..da07f1f9adf 100644 --- a/plugin/storage/badger/factory.go +++ b/plugin/storage/badger/factory.go @@ -38,14 +38,10 @@ const ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) - _ storage.Purger = (*Factory)(nil) - - // TODO badger could implement archive storage - // _ storage.ArchiveFactory = (*Factory)(nil) - + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ storage.Purger = (*Factory)(nil) _ storage.SamplingStoreFactory = (*Factory)(nil) ) From 2dc7d19b11e298fec288468378fd6a212a9082ff Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 09:45:21 -0500 Subject: [PATCH 07/74] Remove Archive Factory From Blackhole Signed-off-by: Mahad Zaryab --- plugin/storage/blackhole/factory.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/plugin/storage/blackhole/factory.go b/plugin/storage/blackhole/factory.go index ad149593633..521b20e41cf 100644 --- a/plugin/storage/blackhole/factory.go +++ b/plugin/storage/blackhole/factory.go @@ -14,8 +14,7 @@ import ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ storage.ArchiveFactory = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) ) // Factory implements storage.Factory and creates blackhole storage components. @@ -48,16 +47,6 @@ func (f *Factory) CreateSpanWriter() (spanstore.Writer, error) { return f.store, nil } -// CreateArchiveSpanReader implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { - return f.store, nil -} - -// CreateArchiveSpanWriter implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - return f.store, nil -} - // CreateDependencyReader implements storage.Factory func (f *Factory) CreateDependencyReader() (dependencystore.Reader, error) { return f.store, nil From 00c105ceb22d994f7be31ef92c5634cfc4ea26f2 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 09:46:09 -0500 Subject: [PATCH 08/74] Remove Archive Factory From Memory Signed-off-by: Mahad Zaryab --- plugin/storage/memory/factory.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/plugin/storage/memory/factory.go b/plugin/storage/memory/factory.go index 0a7b7b34a24..a784c5e22dc 100644 --- a/plugin/storage/memory/factory.go +++ b/plugin/storage/memory/factory.go @@ -24,7 +24,6 @@ import ( var ( // interface comformance checks _ storage.Factory = (*Factory)(nil) - _ storage.ArchiveFactory = (*Factory)(nil) _ storage.SamplingStoreFactory = (*Factory)(nil) _ plugin.Configurable = (*Factory)(nil) _ storage.Purger = (*Factory)(nil) @@ -90,23 +89,6 @@ func (f *Factory) CreateSpanWriter() (spanstore.Writer, error) { return f.store, nil } -// CreateArchiveSpanReader implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { - archiveMetricsFactory := f.metricsFactory.Namespace( - metrics.NSOptions{ - Tags: map[string]string{ - "role": "archive", - }, - }, - ) - return spanstoremetrics.NewReaderDecorator(f.store, archiveMetricsFactory), nil -} - -// CreateArchiveSpanWriter implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - return f.store, nil -} - // CreateDependencyReader implements storage.Factory func (f *Factory) CreateDependencyReader() (dependencystore.Reader, error) { return f.store, nil From b57e488f3f032fedc12afc81611b58bc8795a27f Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 10:25:07 -0500 Subject: [PATCH 09/74] Remove Archive Helper From Adapter Signed-off-by: Mahad Zaryab --- storage_v2/v1adapter/archive.go | 43 ---------- storage_v2/v1adapter/archive_test.go | 112 --------------------------- 2 files changed, 155 deletions(-) delete mode 100644 storage_v2/v1adapter/archive.go delete mode 100644 storage_v2/v1adapter/archive_test.go diff --git a/storage_v2/v1adapter/archive.go b/storage_v2/v1adapter/archive.go deleted file mode 100644 index bdf31fbf6bc..00000000000 --- a/storage_v2/v1adapter/archive.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2025 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package v1adapter - -import ( - "errors" - - "go.uber.org/zap" - - "github.com/jaegertracing/jaeger/storage" -) - -func InitializeArchiveStorage( - storageFactory storage.BaseFactory, - logger *zap.Logger, -) (*TraceReader, *TraceWriter) { - archiveFactory, ok := storageFactory.(storage.ArchiveFactory) - if !ok { - logger.Info("Archive storage not supported by the factory") - return nil, nil - } - reader, err := archiveFactory.CreateArchiveSpanReader() - if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { - logger.Info("Archive storage not created", zap.String("reason", err.Error())) - return nil, nil - } - if err != nil { - logger.Error("Cannot init archive storage reader", zap.Error(err)) - return nil, nil - } - writer, err := archiveFactory.CreateArchiveSpanWriter() - if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { - logger.Info("Archive storage not created", zap.String("reason", err.Error())) - return nil, nil - } - if err != nil { - logger.Error("Cannot init archive storage writer", zap.Error(err)) - return nil, nil - } - - return NewTraceReader(reader), NewTraceWriter(writer) -} diff --git a/storage_v2/v1adapter/archive_test.go b/storage_v2/v1adapter/archive_test.go deleted file mode 100644 index 1dc1c854851..00000000000 --- a/storage_v2/v1adapter/archive_test.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2025 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package v1adapter - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.uber.org/zap" - - "github.com/jaegertracing/jaeger/pkg/metrics" - "github.com/jaegertracing/jaeger/storage" - "github.com/jaegertracing/jaeger/storage/dependencystore" - "github.com/jaegertracing/jaeger/storage/spanstore" - spanstoremocks "github.com/jaegertracing/jaeger/storage/spanstore/mocks" -) - -type fakeStorageFactory1 struct{} - -type fakeStorageFactory2 struct { - fakeStorageFactory1 - r spanstore.Reader - w spanstore.Writer - rErr error - wErr error -} - -func (*fakeStorageFactory1) Initialize(metrics.Factory, *zap.Logger) error { - return nil -} -func (*fakeStorageFactory1) CreateSpanReader() (spanstore.Reader, error) { return nil, nil } -func (*fakeStorageFactory1) CreateSpanWriter() (spanstore.Writer, error) { return nil, nil } -func (*fakeStorageFactory1) CreateDependencyReader() (dependencystore.Reader, error) { return nil, nil } - -func (f *fakeStorageFactory2) CreateArchiveSpanReader() (spanstore.Reader, error) { return f.r, f.rErr } -func (f *fakeStorageFactory2) CreateArchiveSpanWriter() (spanstore.Writer, error) { return f.w, f.wErr } - -var ( - _ storage.Factory = new(fakeStorageFactory1) - _ storage.ArchiveFactory = new(fakeStorageFactory2) -) - -func TestInitializeArchiveStorage(t *testing.T) { - tests := []struct { - name string - factory storage.Factory - wantReader spanstore.Reader - wantWriter spanstore.Writer - }{ - { - name: "Archive storage not supported by the factory", - factory: new(fakeStorageFactory1), - wantReader: nil, - wantWriter: nil, - }, - { - name: "Archive storage not configured", - factory: &fakeStorageFactory2{rErr: storage.ErrArchiveStorageNotConfigured}, - wantReader: nil, - wantWriter: nil, - }, - { - name: "Archive storage not supported for reader", - factory: &fakeStorageFactory2{rErr: storage.ErrArchiveStorageNotSupported}, - wantReader: nil, - wantWriter: nil, - }, - { - name: "Error initializing archive span reader", - factory: &fakeStorageFactory2{rErr: assert.AnError}, - wantReader: nil, - wantWriter: nil, - }, - { - name: "Archive storage not supported for writer", - factory: &fakeStorageFactory2{wErr: storage.ErrArchiveStorageNotSupported}, - wantReader: nil, - wantWriter: nil, - }, - { - name: "Error initializing archive span writer", - factory: &fakeStorageFactory2{wErr: assert.AnError}, - wantReader: nil, - wantWriter: nil, - }, - { - name: "Successfully initialize archive storage", - factory: &fakeStorageFactory2{r: &spanstoremocks.Reader{}, w: &spanstoremocks.Writer{}}, - wantReader: &spanstoremocks.Reader{}, - wantWriter: &spanstoremocks.Writer{}, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - logger := zap.NewNop() - reader, writer := InitializeArchiveStorage(test.factory, logger) - if test.wantReader != nil { - require.Equal(t, test.wantReader, reader.spanReader) - } else { - require.Nil(t, reader) - } - if test.wantWriter != nil { - require.Equal(t, test.wantWriter, writer.spanWriter) - } else { - require.Nil(t, writer) - } - }) - } -} From e90efe7c68609140131c74e5d6fac618076af816 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 10:25:55 -0500 Subject: [PATCH 10/74] Remove Concept of Archive From GRPC Storage Signed-off-by: Mahad Zaryab --- plugin/storage/grpc/factory.go | 45 ++-------------------- plugin/storage/grpc/shared/grpc_client.go | 5 +-- plugin/storage/grpc/shared/grpc_handler.go | 5 --- plugin/storage/grpc/shared/interface.go | 7 ---- 4 files changed, 5 insertions(+), 57 deletions(-) diff --git a/plugin/storage/grpc/factory.go b/plugin/storage/grpc/factory.go index e316ceb7d3e..7e4fb5bf6b1 100644 --- a/plugin/storage/grpc/factory.go +++ b/plugin/storage/grpc/factory.go @@ -34,10 +34,9 @@ import ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ storage.ArchiveFactory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) ) // Factory implements storage.Factory and creates storage components backed by a storage plugin. @@ -158,7 +157,6 @@ func (f *Factory) newRemoteStorage( return &ClientPluginServices{ PluginServices: shared.PluginServices{ Store: grpcClient, - ArchiveStore: grpcClient, StreamingSpanWriter: grpcClient, }, Capabilities: grpcClient, @@ -185,43 +183,6 @@ func (f *Factory) CreateDependencyReader() (dependencystore.Reader, error) { return f.services.Store.DependencyReader(), nil } -// CreateArchiveSpanReader implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { - if f.services.Capabilities == nil { - return nil, storage.ErrArchiveStorageNotSupported - } - capabilities, err := f.services.Capabilities.Capabilities() - if err != nil { - return nil, err - } - if capabilities == nil || !capabilities.ArchiveSpanReader { - return nil, storage.ErrArchiveStorageNotSupported - } - archiveMetricsFactory := f.telset.Metrics.Namespace( - metrics.NSOptions{ - Tags: map[string]string{ - "role": "archive", - }, - }, - ) - return spanstoremetrics.NewReaderDecorator(f.services.ArchiveStore.ArchiveSpanReader(), archiveMetricsFactory), nil -} - -// CreateArchiveSpanWriter implements storage.ArchiveFactory -func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - if f.services.Capabilities == nil { - return nil, storage.ErrArchiveStorageNotSupported - } - capabilities, err := f.services.Capabilities.Capabilities() - if err != nil { - return nil, err - } - if capabilities == nil || !capabilities.ArchiveSpanWriter { - return nil, storage.ErrArchiveStorageNotSupported - } - return f.services.ArchiveStore.ArchiveSpanWriter(), nil -} - // Close closes the resources held by the factory func (f *Factory) Close() error { var errs []error diff --git a/plugin/storage/grpc/shared/grpc_client.go b/plugin/storage/grpc/shared/grpc_client.go index f6323be4568..a68a5c67071 100644 --- a/plugin/storage/grpc/shared/grpc_client.go +++ b/plugin/storage/grpc/shared/grpc_client.go @@ -25,9 +25,8 @@ import ( const BearerTokenKey = "bearer.token" var ( - _ StoragePlugin = (*GRPCClient)(nil) - _ ArchiveStoragePlugin = (*GRPCClient)(nil) - _ PluginCapabilities = (*GRPCClient)(nil) + _ StoragePlugin = (*GRPCClient)(nil) + _ PluginCapabilities = (*GRPCClient)(nil) ) // GRPCClient implements shared.StoragePlugin and reads/writes spans and dependencies diff --git a/plugin/storage/grpc/shared/grpc_handler.go b/plugin/storage/grpc/shared/grpc_handler.go index 28dc0adf8cb..197a4cd0d0e 100644 --- a/plugin/storage/grpc/shared/grpc_handler.go +++ b/plugin/storage/grpc/shared/grpc_handler.go @@ -52,7 +52,6 @@ func NewGRPCHandler(impl *GRPCHandlerStorageImpl) *GRPCHandler { // NewGRPCHandler creates a handler given implementations grouped by plugin services. func NewGRPCHandlerWithPlugins( mainImpl StoragePlugin, - archiveImpl ArchiveStoragePlugin, streamImpl StreamingSpanWriterPlugin, ) *GRPCHandler { impl := &GRPCHandlerStorageImpl{ @@ -64,10 +63,6 @@ func NewGRPCHandlerWithPlugins( ArchiveSpanWriter: func() spanstore.Writer { return nil }, StreamingSpanWriter: func() spanstore.Writer { return nil }, } - if archiveImpl != nil { - impl.ArchiveSpanReader = archiveImpl.ArchiveSpanReader - impl.ArchiveSpanWriter = archiveImpl.ArchiveSpanWriter - } if streamImpl != nil { impl.StreamingSpanWriter = streamImpl.StreamingSpanWriter } diff --git a/plugin/storage/grpc/shared/interface.go b/plugin/storage/grpc/shared/interface.go index 9abc2f75dce..593db99c45c 100644 --- a/plugin/storage/grpc/shared/interface.go +++ b/plugin/storage/grpc/shared/interface.go @@ -15,12 +15,6 @@ type StoragePlugin interface { DependencyReader() dependencystore.Reader } -// ArchiveStoragePlugin is the interface we're exposing as a plugin. -type ArchiveStoragePlugin interface { - ArchiveSpanReader() spanstore.Reader - ArchiveSpanWriter() spanstore.Writer -} - // StreamingSpanWriterPlugin is the interface we're exposing as a plugin. type StreamingSpanWriterPlugin interface { StreamingSpanWriter() spanstore.Writer @@ -41,6 +35,5 @@ type Capabilities struct { // PluginServices defines services plugin can expose type PluginServices struct { Store StoragePlugin - ArchiveStore ArchiveStoragePlugin StreamingSpanWriter StreamingSpanWriterPlugin } From 1780ea50f5a3c771267007e9fd4bd79b16b7c08b Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 10:27:06 -0500 Subject: [PATCH 11/74] Remove Usages of InitArchiveStorage Signed-off-by: Mahad Zaryab --- cmd/query/app/flags.go | 37 ++++++++++++--- cmd/query/app/querysvc/query_service.go | 33 ------------- cmd/query/app/querysvc/query_service_test.go | 50 +------------------- cmd/remote-storage/app/server.go | 34 +++++++++---- plugin/storage/factory.go | 9 ++-- 5 files changed, 58 insertions(+), 105 deletions(-) diff --git a/cmd/query/app/flags.go b/cmd/query/app/flags.go index 23072b16d90..43f7fc11811 100644 --- a/cmd/query/app/flags.go +++ b/cmd/query/app/flags.go @@ -29,8 +29,9 @@ import ( "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/config/tlscfg" "github.com/jaegertracing/jaeger/pkg/tenancy" + "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" - "github.com/jaegertracing/jaeger/storage" + "github.com/jaegertracing/jaeger/storage/spanstore" "github.com/jaegertracing/jaeger/storage_v2/v1adapter" ) @@ -139,9 +140,13 @@ func (qOpts *QueryOptions) InitFromViper(v *viper.Viper, logger *zap.Logger) (*Q } // BuildQueryServiceOptions creates a QueryServiceOptions struct with appropriate adjusters and archive config -func (qOpts *QueryOptions) BuildQueryServiceOptions(storageFactory storage.BaseFactory, logger *zap.Logger) *querysvc.QueryServiceOptions { +func (qOpts *QueryOptions) BuildQueryServiceOptions(storageFactory *storage.Factory, logger *zap.Logger) *querysvc.QueryServiceOptions { opts := &querysvc.QueryServiceOptions{} - if !opts.InitArchiveStorage(storageFactory, logger) { + ar, aw := initArchiveStorage(storageFactory, logger) + if ar != nil && aw != nil { + opts.ArchiveSpanReader = ar + opts.ArchiveSpanWriter = aw + } else { logger.Info("Archive storage not initialized") } @@ -150,13 +155,13 @@ func (qOpts *QueryOptions) BuildQueryServiceOptions(storageFactory storage.BaseF return opts } -func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(storageFactory storage.BaseFactory, logger *zap.Logger) *v2querysvc.QueryServiceOptions { +func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(storageFactory *storage.Factory, logger *zap.Logger) *v2querysvc.QueryServiceOptions { opts := &v2querysvc.QueryServiceOptions{} - ar, aw := v1adapter.InitializeArchiveStorage(storageFactory, logger) + ar, aw := initArchiveStorage(storageFactory, logger) if ar != nil && aw != nil { - opts.ArchiveTraceReader = ar - opts.ArchiveTraceWriter = aw + opts.ArchiveTraceReader = v1adapter.NewTraceReader(ar) + opts.ArchiveTraceWriter = v1adapter.NewTraceWriter(aw) } else { logger.Info("Archive storage not initialized") } @@ -166,6 +171,24 @@ func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(storageFactory storage.Bas return opts } +func initArchiveStorage( + storageFactory *storage.Factory, + logger *zap.Logger, +) (spanstore.Reader, spanstore.Writer) { + reader, err := storageFactory.CreateArchiveSpanReader() + if err != nil { + logger.Error("Cannot init archive storage reader", zap.Error(err)) + return nil, nil + } + writer, err := storageFactory.CreateArchiveSpanWriter() + if err != nil { + logger.Error("Cannot init archive storage writer", zap.Error(err)) + return nil, nil + } + + return reader, writer +} + // stringSliceAsHeader parses a slice of strings and returns a http.Header. // Each string in the slice is expected to be in the format "key: value" func stringSliceAsHeader(slice []string) (http.Header, error) { diff --git a/cmd/query/app/querysvc/query_service.go b/cmd/query/app/querysvc/query_service.go index ca241c71500..86731c5abc7 100644 --- a/cmd/query/app/querysvc/query_service.go +++ b/cmd/query/app/querysvc/query_service.go @@ -8,11 +8,8 @@ import ( "errors" "time" - "go.uber.org/zap" - "github.com/jaegertracing/jaeger/model" "github.com/jaegertracing/jaeger/model/adjuster" - "github.com/jaegertracing/jaeger/storage" "github.com/jaegertracing/jaeger/storage/spanstore" "github.com/jaegertracing/jaeger/storage_v2/depstore" "github.com/jaegertracing/jaeger/storage_v2/tracestore" @@ -164,36 +161,6 @@ func (qs QueryService) GetCapabilities() StorageCapabilities { } } -// InitArchiveStorage tries to initialize archive storage reader/writer if storage factory supports them. -func (opts *QueryServiceOptions) InitArchiveStorage(storageFactory storage.BaseFactory, logger *zap.Logger) bool { - archiveFactory, ok := storageFactory.(storage.ArchiveFactory) - if !ok { - logger.Info("Archive storage not supported by the factory") - return false - } - reader, err := archiveFactory.CreateArchiveSpanReader() - if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { - logger.Info("Archive storage not created", zap.String("reason", err.Error())) - return false - } - if err != nil { - logger.Error("Cannot init archive storage reader", zap.Error(err)) - return false - } - writer, err := archiveFactory.CreateArchiveSpanWriter() - if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { - logger.Info("Archive storage not created", zap.String("reason", err.Error())) - return false - } - if err != nil { - logger.Error("Cannot init archive storage writer", zap.Error(err)) - return false - } - opts.ArchiveSpanReader = reader - opts.ArchiveSpanWriter = writer - return true -} - // hasArchiveStorage returns true if archive storage reader/writer are initialized. func (opts *QueryServiceOptions) hasArchiveStorage() bool { return opts.ArchiveSpanReader != nil && opts.ArchiveSpanWriter != nil diff --git a/cmd/query/app/querysvc/query_service_test.go b/cmd/query/app/querysvc/query_service_test.go index 7a77d6c7016..bd9b3187191 100644 --- a/cmd/query/app/querysvc/query_service_test.go +++ b/cmd/query/app/querysvc/query_service_test.go @@ -451,14 +451,6 @@ func TestGetCapabilitiesWithSupportsArchive(t *testing.T) { type fakeStorageFactory1 struct{} -type fakeStorageFactory2 struct { - fakeStorageFactory1 - r spanstore.Reader - w spanstore.Writer - rErr error - wErr error -} - func (*fakeStorageFactory1) Initialize(metrics.Factory, *zap.Logger) error { return nil } @@ -466,50 +458,10 @@ func (*fakeStorageFactory1) CreateSpanReader() (spanstore.Reader, error) func (*fakeStorageFactory1) CreateSpanWriter() (spanstore.Writer, error) { return nil, nil } func (*fakeStorageFactory1) CreateDependencyReader() (dependencystore.Reader, error) { return nil, nil } -func (f *fakeStorageFactory2) CreateArchiveSpanReader() (spanstore.Reader, error) { return f.r, f.rErr } -func (f *fakeStorageFactory2) CreateArchiveSpanWriter() (spanstore.Writer, error) { return f.w, f.wErr } - var ( - _ storage.Factory = new(fakeStorageFactory1) - _ storage.ArchiveFactory = new(fakeStorageFactory2) + _ storage.Factory = new(fakeStorageFactory1) ) -func TestInitArchiveStorageErrors(t *testing.T) { - opts := &QueryServiceOptions{} - logger := zap.NewNop() - - assert.False(t, opts.InitArchiveStorage(new(fakeStorageFactory1), logger)) - assert.False(t, opts.InitArchiveStorage( - &fakeStorageFactory2{rErr: storage.ErrArchiveStorageNotConfigured}, - logger, - )) - assert.False(t, opts.InitArchiveStorage( - &fakeStorageFactory2{rErr: errors.New("error")}, - logger, - )) - assert.False(t, opts.InitArchiveStorage( - &fakeStorageFactory2{wErr: storage.ErrArchiveStorageNotConfigured}, - logger, - )) - assert.False(t, opts.InitArchiveStorage( - &fakeStorageFactory2{wErr: errors.New("error")}, - logger, - )) -} - -func TestInitArchiveStorage(t *testing.T) { - opts := &QueryServiceOptions{} - logger := zap.NewNop() - reader := &spanstoremocks.Reader{} - writer := &spanstoremocks.Writer{} - assert.True(t, opts.InitArchiveStorage( - &fakeStorageFactory2{r: reader, w: writer}, - logger, - )) - assert.Equal(t, reader, opts.ArchiveSpanReader) - assert.Equal(t, writer, opts.ArchiveSpanWriter) -} - func TestMain(m *testing.M) { testutils.VerifyGoLeaks(m) } diff --git a/cmd/remote-storage/app/server.go b/cmd/remote-storage/app/server.go index 66529595a88..e4a2924030f 100644 --- a/cmd/remote-storage/app/server.go +++ b/cmd/remote-storage/app/server.go @@ -17,12 +17,11 @@ import ( "google.golang.org/grpc/health" "google.golang.org/grpc/reflection" - "github.com/jaegertracing/jaeger/cmd/query/app/querysvc" "github.com/jaegertracing/jaeger/pkg/bearertoken" "github.com/jaegertracing/jaeger/pkg/telemetry" "github.com/jaegertracing/jaeger/pkg/tenancy" + "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/plugin/storage/grpc/shared" - "github.com/jaegertracing/jaeger/storage" "github.com/jaegertracing/jaeger/storage/dependencystore" "github.com/jaegertracing/jaeger/storage/spanstore" ) @@ -37,7 +36,7 @@ type Server struct { } // NewServer creates and initializes Server. -func NewServer(options *Options, storageFactory storage.BaseFactory, tm *tenancy.Manager, telset telemetry.Settings) (*Server, error) { +func NewServer(options *Options, storageFactory *storage.Factory, tm *tenancy.Manager, telset telemetry.Settings) (*Server, error) { handler, err := createGRPCHandler(storageFactory, telset.Logger) if err != nil { return nil, err @@ -55,7 +54,7 @@ func NewServer(options *Options, storageFactory storage.BaseFactory, tm *tenancy }, nil } -func createGRPCHandler(f storage.BaseFactory, logger *zap.Logger) (*shared.GRPCHandler, error) { +func createGRPCHandler(f *storage.Factory, logger *zap.Logger) (*shared.GRPCHandler, error) { reader, err := f.CreateSpanReader() if err != nil { return nil, err @@ -76,12 +75,9 @@ func createGRPCHandler(f storage.BaseFactory, logger *zap.Logger) (*shared.GRPCH StreamingSpanWriter: func() spanstore.Writer { return nil }, } - // borrow code from Query service for archive storage - qOpts := &querysvc.QueryServiceOptions{} - // when archive storage not initialized (returns false), the reader/writer will be nil - _ = qOpts.InitArchiveStorage(f, logger) - impl.ArchiveSpanReader = func() spanstore.Reader { return qOpts.ArchiveSpanReader } - impl.ArchiveSpanWriter = func() spanstore.Writer { return qOpts.ArchiveSpanWriter } + ar, aw := initArchiveStorage(f, logger) + impl.ArchiveSpanReader = func() spanstore.Reader { return ar } + impl.ArchiveSpanWriter = func() spanstore.Writer { return aw } handler := shared.NewGRPCHandler(impl) return handler, nil @@ -143,3 +139,21 @@ func (s *Server) Close() error { s.telset.ReportStatus(componentstatus.NewEvent(componentstatus.StatusStopped)) return nil } + +func initArchiveStorage( + storageFactory *storage.Factory, + logger *zap.Logger, +) (spanstore.Reader, spanstore.Writer) { + reader, err := storageFactory.CreateArchiveSpanReader() + if err != nil { + logger.Error("Cannot init archive storage reader", zap.Error(err)) + return nil, nil + } + writer, err := storageFactory.CreateArchiveSpanWriter() + if err != nil { + logger.Error("Cannot init archive storage writer", zap.Error(err)) + return nil, nil + } + + return reader, writer +} diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index d923758dab6..de103da5b8d 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -74,10 +74,9 @@ func AllSamplingStorageTypes() []string { } var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ storage.ArchiveFactory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) ) // Factory implements storage.Factory interface as a meta-factory for storage components. @@ -317,7 +316,6 @@ func (f *Factory) initDownsamplingFromViper(v *viper.Viper) { f.FactoryConfig.DownsamplingHashSalt = v.GetString(downsamplingHashSalt) } -// CreateArchiveSpanReader implements storage.ArchiveFactory func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { factory, ok := f.archiveFactories[f.SpanReaderType] if !ok { @@ -326,7 +324,6 @@ func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { return factory.CreateSpanReader() } -// CreateArchiveSpanWriter implements storage.ArchiveFactory func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { factory, ok := f.archiveFactories[f.SpanWriterTypes[0]] if !ok { From 146826095539c72f76ea8074f72b575b67ec6511 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 10:29:47 -0500 Subject: [PATCH 12/74] Remove Archive Factory Signed-off-by: Mahad Zaryab --- storage/factory.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/storage/factory.go b/storage/factory.go index fdac5e9d17b..c677390c4d9 100644 --- a/storage/factory.go +++ b/storage/factory.go @@ -6,7 +6,6 @@ package storage import ( "context" - "errors" "go.uber.org/zap" @@ -61,23 +60,6 @@ type SamplingStoreFactory interface { CreateSamplingStore(maxBuckets int) (samplingstore.Store, error) } -var ( - // ErrArchiveStorageNotConfigured can be returned by the ArchiveFactory when the archive storage is not configured. - ErrArchiveStorageNotConfigured = errors.New("archive storage not configured") - - // ErrArchiveStorageNotSupported can be returned by the ArchiveFactory when the archive storage is not supported by the backend. - ErrArchiveStorageNotSupported = errors.New("archive storage not supported") -) - -// ArchiveFactory is an additional interface that can be implemented by a factory to support trace archiving. -type ArchiveFactory interface { - // CreateArchiveSpanReader creates a spanstore.Reader. - CreateArchiveSpanReader() (spanstore.Reader, error) - - // CreateArchiveSpanWriter creates a spanstore.Writer. - CreateArchiveSpanWriter() (spanstore.Writer, error) -} - // MetricStoreFactory defines an interface for a factory that can create implementations of different metrics storage components. // Implementations are also encouraged to implement plugin.Configurable interface. // From 43b76043afb08af2c9d590a4534a3c59182b734a Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 11:13:13 -0500 Subject: [PATCH 13/74] Fix Cassandra Integration Test Signed-off-by: Mahad Zaryab --- plugin/storage/integration/cassandra_test.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/plugin/storage/integration/cassandra_test.go b/plugin/storage/integration/cassandra_test.go index 59f26b46d00..52fda2db35d 100644 --- a/plugin/storage/integration/cassandra_test.go +++ b/plugin/storage/integration/cassandra_test.go @@ -24,7 +24,8 @@ import ( type CassandraStorageIntegration struct { StorageIntegration - factory *cassandra.Factory + factory *cassandra.Factory + archiveFactory *cassandra.Factory } func newCassandraStorageIntegration() *CassandraStorageIntegration { @@ -43,9 +44,9 @@ func (s *CassandraStorageIntegration) cleanUp(t *testing.T) { require.NoError(t, s.factory.Purge(context.Background())) } -func (*CassandraStorageIntegration) initializeCassandraFactory(t *testing.T, flags []string) *cassandra.Factory { +func (*CassandraStorageIntegration) initializeCassandraFactory(t *testing.T, flags []string, factoryInit func() *cassandra.Factory) *cassandra.Factory { logger := zaptest.NewLogger(t, zaptest.WrapOptions(zap.AddCaller())) - f := cassandra.NewFactory() + f := factoryInit() v, command := config.Viperize(f.AddFlags) require.NoError(t, command.ParseFlags(flags)) f.InitFromViper(v, logger) @@ -64,14 +65,17 @@ func (s *CassandraStorageIntegration) initializeCassandra(t *testing.T) { "--cassandra.password=" + password, "--cassandra.username=" + username, "--cassandra.keyspace=jaeger_v1_dc1", + }, cassandra.NewFactory) + af := s.initializeCassandraFactory(t, []string{ "--cassandra-archive.keyspace=jaeger_v1_dc1_archive", "--cassandra-archive.enabled=true", "--cassandra-archive.servers=127.0.0.1", "--cassandra-archive.basic.allowed-authenticators=org.apache.cassandra.auth.PasswordAuthenticator", "--cassandra-archive.password=" + password, "--cassandra-archive.username=" + username, - }) + }, cassandra.NewArchiveFactory) s.factory = f + s.archiveFactory = af var err error spanWriter, err := f.CreateSpanWriter() require.NoError(t, err) @@ -79,9 +83,9 @@ func (s *CassandraStorageIntegration) initializeCassandra(t *testing.T) { spanReader, err := f.CreateSpanReader() require.NoError(t, err) s.TraceReader = v1adapter.NewTraceReader(spanReader) - s.ArchiveSpanReader, err = f.CreateArchiveSpanReader() + s.ArchiveSpanReader, err = af.CreateSpanReader() require.NoError(t, err) - s.ArchiveSpanWriter, err = f.CreateArchiveSpanWriter() + s.ArchiveSpanWriter, err = af.CreateSpanWriter() require.NoError(t, err) s.SamplingStore, err = f.CreateSamplingStore(0) require.NoError(t, err) From 7c4c43e594a043284cdfdfffde161f1fbc625d19 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 11:17:38 -0500 Subject: [PATCH 14/74] Fix ES Integration Test Signed-off-by: Mahad Zaryab --- .../storage/integration/elasticsearch_test.go | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/plugin/storage/integration/elasticsearch_test.go b/plugin/storage/integration/elasticsearch_test.go index a708a6c512f..1cc4f305590 100644 --- a/plugin/storage/integration/elasticsearch_test.go +++ b/plugin/storage/integration/elasticsearch_test.go @@ -52,7 +52,8 @@ type ESStorageIntegration struct { client *elastic.Client v8Client *elasticsearch8.Client - factory *es.Factory + factory *es.Factory + archiveFactory *es.Factory } func (s *ESStorageIntegration) getVersion() (uint, error) { @@ -102,23 +103,10 @@ func (s *ESStorageIntegration) esCleanUp(t *testing.T) { require.NoError(t, s.factory.Purge(context.Background())) } -func (*ESStorageIntegration) initializeESFactory(t *testing.T, allTagsAsFields bool) *es.Factory { +func (*ESStorageIntegration) initializeESFactory(t *testing.T, args []string, factoryInit func() *es.Factory) *es.Factory { logger := zaptest.NewLogger(t, zaptest.WrapOptions(zap.AddCaller())) - f := es.NewFactory() + f := factoryInit() v, command := config.Viperize(f.AddFlags) - args := []string{ - fmt.Sprintf("--es.num-shards=%v", 5), - fmt.Sprintf("--es.num-replicas=%v", 1), - fmt.Sprintf("--es.index-prefix=%v", indexPrefix), - fmt.Sprintf("--es.use-ilm=%v", false), - fmt.Sprintf("--es.service-cache-ttl=%v", 1*time.Second), - fmt.Sprintf("--es.tags-as-fields.all=%v", allTagsAsFields), - fmt.Sprintf("--es.bulk.actions=%v", 1), - fmt.Sprintf("--es.bulk.flush-interval=%v", time.Nanosecond), - "--es-archive.enabled=true", - fmt.Sprintf("--es-archive.tags-as-fields.all=%v", allTagsAsFields), - fmt.Sprintf("--es-archive.index-prefix=%v", indexPrefix), - } require.NoError(t, command.ParseFlags(args)) f.InitFromViper(v, logger) require.NoError(t, f.Initialize(metrics.NullFactory, logger)) @@ -130,8 +118,23 @@ func (*ESStorageIntegration) initializeESFactory(t *testing.T, allTagsAsFields b } func (s *ESStorageIntegration) initSpanstore(t *testing.T, allTagsAsFields bool) { - f := s.initializeESFactory(t, allTagsAsFields) + f := s.initializeESFactory(t, []string{ + fmt.Sprintf("--es.num-shards=%v", 5), + fmt.Sprintf("--es.num-replicas=%v", 1), + fmt.Sprintf("--es.index-prefix=%v", indexPrefix), + fmt.Sprintf("--es.use-ilm=%v", false), + fmt.Sprintf("--es.service-cache-ttl=%v", 1*time.Second), + fmt.Sprintf("--es.tags-as-fields.all=%v", allTagsAsFields), + fmt.Sprintf("--es.bulk.actions=%v", 1), + fmt.Sprintf("--es.bulk.flush-interval=%v", time.Nanosecond), + "--es-archive.enabled=true", + }, es.NewFactory) + af := s.initializeESFactory(t, []string{ + fmt.Sprintf("--es-archive.tags-as-fields.all=%v", allTagsAsFields), + fmt.Sprintf("--es-archive.index-prefix=%v", indexPrefix), + }, es.NewArchiveFactory) s.factory = f + s.archiveFactory = af var err error spanWriter, err := f.CreateSpanWriter() require.NoError(t, err) @@ -139,9 +142,9 @@ func (s *ESStorageIntegration) initSpanstore(t *testing.T, allTagsAsFields bool) spanReader, err := f.CreateSpanReader() require.NoError(t, err) s.TraceReader = v1adapter.NewTraceReader(spanReader) - s.ArchiveSpanReader, err = f.CreateArchiveSpanReader() + s.ArchiveSpanReader, err = af.CreateSpanReader() require.NoError(t, err) - s.ArchiveSpanWriter, err = f.CreateArchiveSpanWriter() + s.ArchiveSpanWriter, err = af.CreateSpanWriter() require.NoError(t, err) dependencyReader, err := f.CreateDependencyReader() From 0b2280ad6d355e52910977adb10e338c8d26e95a Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 11:26:41 -0500 Subject: [PATCH 15/74] Fix GRPC Integration Tests Signed-off-by: Mahad Zaryab --- plugin/storage/integration/grpc_test.go | 27 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/plugin/storage/integration/grpc_test.go b/plugin/storage/integration/grpc_test.go index 9d8e85bc29e..3ef124c2b09 100644 --- a/plugin/storage/integration/grpc_test.go +++ b/plugin/storage/integration/grpc_test.go @@ -20,22 +20,29 @@ import ( type GRPCStorageIntegrationTestSuite struct { StorageIntegration - flags []string - factory *grpc.Factory - remoteStorage *RemoteMemoryStorage + flags []string + factory *grpc.Factory + archiveFactory *grpc.Factory + remoteStorage *RemoteMemoryStorage } func (s *GRPCStorageIntegrationTestSuite) initialize(t *testing.T) { logger := zaptest.NewLogger(t, zaptest.WrapOptions(zap.AddCaller())) s.remoteStorage = StartNewRemoteMemoryStorage(t) + initFactory := func(f *grpc.Factory) { + v, command := config.Viperize(f.AddFlags) + err := command.ParseFlags(s.flags) + require.NoError(t, err) + f.InitFromViper(v, logger) + require.NoError(t, f.Initialize(metrics.NullFactory, logger)) + } f := grpc.NewFactory() - v, command := config.Viperize(f.AddFlags) - err := command.ParseFlags(s.flags) - require.NoError(t, err) - f.InitFromViper(v, logger) - require.NoError(t, f.Initialize(metrics.NullFactory, logger)) + af := grpc.NewFactory() + initFactory(f) + initFactory(af) s.factory = f + s.archiveFactory = af spanWriter, err := f.CreateSpanWriter() require.NoError(t, err) @@ -43,9 +50,9 @@ func (s *GRPCStorageIntegrationTestSuite) initialize(t *testing.T) { spanReader, err := f.CreateSpanReader() require.NoError(t, err) s.TraceReader = v1adapter.NewTraceReader(spanReader) - s.ArchiveSpanReader, err = f.CreateArchiveSpanReader() + s.ArchiveSpanReader, err = af.CreateSpanReader() require.NoError(t, err) - s.ArchiveSpanWriter, err = f.CreateArchiveSpanWriter() + s.ArchiveSpanWriter, err = af.CreateSpanWriter() require.NoError(t, err) // TODO DependencyWriter is not implemented in grpc store From 5a06df6c135aeea7a495200a5ccafdcdf69d074b Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 11:33:43 -0500 Subject: [PATCH 16/74] Fix Typo Signed-off-by: Mahad Zaryab --- plugin/storage/integration/elasticsearch_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/storage/integration/elasticsearch_test.go b/plugin/storage/integration/elasticsearch_test.go index 1cc4f305590..ed082a117a1 100644 --- a/plugin/storage/integration/elasticsearch_test.go +++ b/plugin/storage/integration/elasticsearch_test.go @@ -127,9 +127,9 @@ func (s *ESStorageIntegration) initSpanstore(t *testing.T, allTagsAsFields bool) fmt.Sprintf("--es.tags-as-fields.all=%v", allTagsAsFields), fmt.Sprintf("--es.bulk.actions=%v", 1), fmt.Sprintf("--es.bulk.flush-interval=%v", time.Nanosecond), - "--es-archive.enabled=true", }, es.NewFactory) af := s.initializeESFactory(t, []string{ + "--es-archive.enabled=true", fmt.Sprintf("--es-archive.tags-as-fields.all=%v", allTagsAsFields), fmt.Sprintf("--es-archive.index-prefix=%v", indexPrefix), }, es.NewArchiveFactory) From 69363443f9fccabdf6cb5f1010d3572984bd6709 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 14:09:58 -0500 Subject: [PATCH 17/74] Fix Integration Test Cleanup Signed-off-by: Mahad Zaryab --- plugin/storage/integration/cassandra_test.go | 1 + plugin/storage/integration/elasticsearch_test.go | 1 + plugin/storage/integration/grpc_test.go | 1 + 3 files changed, 3 insertions(+) diff --git a/plugin/storage/integration/cassandra_test.go b/plugin/storage/integration/cassandra_test.go index 52fda2db35d..5f218ae5ee4 100644 --- a/plugin/storage/integration/cassandra_test.go +++ b/plugin/storage/integration/cassandra_test.go @@ -42,6 +42,7 @@ func newCassandraStorageIntegration() *CassandraStorageIntegration { func (s *CassandraStorageIntegration) cleanUp(t *testing.T) { require.NoError(t, s.factory.Purge(context.Background())) + require.NoError(t, s.archiveFactory.Purge(context.Background())) } func (*CassandraStorageIntegration) initializeCassandraFactory(t *testing.T, flags []string, factoryInit func() *cassandra.Factory) *cassandra.Factory { diff --git a/plugin/storage/integration/elasticsearch_test.go b/plugin/storage/integration/elasticsearch_test.go index ed082a117a1..819ee41bd96 100644 --- a/plugin/storage/integration/elasticsearch_test.go +++ b/plugin/storage/integration/elasticsearch_test.go @@ -101,6 +101,7 @@ func (s *ESStorageIntegration) initializeES(t *testing.T, c *http.Client, allTag func (s *ESStorageIntegration) esCleanUp(t *testing.T) { require.NoError(t, s.factory.Purge(context.Background())) + require.NoError(t, s.archiveFactory.Purge(context.Background())) } func (*ESStorageIntegration) initializeESFactory(t *testing.T, args []string, factoryInit func() *es.Factory) *es.Factory { diff --git a/plugin/storage/integration/grpc_test.go b/plugin/storage/integration/grpc_test.go index 3ef124c2b09..98beb6c6271 100644 --- a/plugin/storage/integration/grpc_test.go +++ b/plugin/storage/integration/grpc_test.go @@ -62,6 +62,7 @@ func (s *GRPCStorageIntegrationTestSuite) initialize(t *testing.T) { func (s *GRPCStorageIntegrationTestSuite) close(t *testing.T) { require.NoError(t, s.factory.Close()) + require.NoError(t, s.archiveFactory.Close()) s.remoteStorage.Close(t) } From 9b8571d9b6a5d61df5a2d3e03fb210822a3375da Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 14:17:46 -0500 Subject: [PATCH 18/74] Move Init Function To Factory Struct Signed-off-by: Mahad Zaryab --- cmd/query/app/flags.go | 23 ++--------------------- cmd/remote-storage/app/server.go | 20 +------------------- plugin/storage/factory.go | 21 +++++++++++++++++++-- 3 files changed, 22 insertions(+), 42 deletions(-) diff --git a/cmd/query/app/flags.go b/cmd/query/app/flags.go index 43f7fc11811..fc3b3ceb9eb 100644 --- a/cmd/query/app/flags.go +++ b/cmd/query/app/flags.go @@ -31,7 +31,6 @@ import ( "github.com/jaegertracing/jaeger/pkg/tenancy" "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" - "github.com/jaegertracing/jaeger/storage/spanstore" "github.com/jaegertracing/jaeger/storage_v2/v1adapter" ) @@ -142,7 +141,7 @@ func (qOpts *QueryOptions) InitFromViper(v *viper.Viper, logger *zap.Logger) (*Q // BuildQueryServiceOptions creates a QueryServiceOptions struct with appropriate adjusters and archive config func (qOpts *QueryOptions) BuildQueryServiceOptions(storageFactory *storage.Factory, logger *zap.Logger) *querysvc.QueryServiceOptions { opts := &querysvc.QueryServiceOptions{} - ar, aw := initArchiveStorage(storageFactory, logger) + ar, aw := storageFactory.InitArchiveStorage(logger) if ar != nil && aw != nil { opts.ArchiveSpanReader = ar opts.ArchiveSpanWriter = aw @@ -158,7 +157,7 @@ func (qOpts *QueryOptions) BuildQueryServiceOptions(storageFactory *storage.Fact func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(storageFactory *storage.Factory, logger *zap.Logger) *v2querysvc.QueryServiceOptions { opts := &v2querysvc.QueryServiceOptions{} - ar, aw := initArchiveStorage(storageFactory, logger) + ar, aw := storageFactory.InitArchiveStorage(logger) if ar != nil && aw != nil { opts.ArchiveTraceReader = v1adapter.NewTraceReader(ar) opts.ArchiveTraceWriter = v1adapter.NewTraceWriter(aw) @@ -171,24 +170,6 @@ func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(storageFactory *storage.Fa return opts } -func initArchiveStorage( - storageFactory *storage.Factory, - logger *zap.Logger, -) (spanstore.Reader, spanstore.Writer) { - reader, err := storageFactory.CreateArchiveSpanReader() - if err != nil { - logger.Error("Cannot init archive storage reader", zap.Error(err)) - return nil, nil - } - writer, err := storageFactory.CreateArchiveSpanWriter() - if err != nil { - logger.Error("Cannot init archive storage writer", zap.Error(err)) - return nil, nil - } - - return reader, writer -} - // stringSliceAsHeader parses a slice of strings and returns a http.Header. // Each string in the slice is expected to be in the format "key: value" func stringSliceAsHeader(slice []string) (http.Header, error) { diff --git a/cmd/remote-storage/app/server.go b/cmd/remote-storage/app/server.go index e4a2924030f..dcd4a4aa7dd 100644 --- a/cmd/remote-storage/app/server.go +++ b/cmd/remote-storage/app/server.go @@ -75,7 +75,7 @@ func createGRPCHandler(f *storage.Factory, logger *zap.Logger) (*shared.GRPCHand StreamingSpanWriter: func() spanstore.Writer { return nil }, } - ar, aw := initArchiveStorage(f, logger) + ar, aw := f.InitArchiveStorage(logger) impl.ArchiveSpanReader = func() spanstore.Reader { return ar } impl.ArchiveSpanWriter = func() spanstore.Writer { return aw } @@ -139,21 +139,3 @@ func (s *Server) Close() error { s.telset.ReportStatus(componentstatus.NewEvent(componentstatus.StatusStopped)) return nil } - -func initArchiveStorage( - storageFactory *storage.Factory, - logger *zap.Logger, -) (spanstore.Reader, spanstore.Writer) { - reader, err := storageFactory.CreateArchiveSpanReader() - if err != nil { - logger.Error("Cannot init archive storage reader", zap.Error(err)) - return nil, nil - } - writer, err := storageFactory.CreateArchiveSpanWriter() - if err != nil { - logger.Error("Cannot init archive storage writer", zap.Error(err)) - return nil, nil - } - - return reader, writer -} diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index de103da5b8d..07c0eb7e93c 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -316,7 +316,7 @@ func (f *Factory) initDownsamplingFromViper(v *viper.Viper) { f.FactoryConfig.DownsamplingHashSalt = v.GetString(downsamplingHashSalt) } -func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { +func (f *Factory) createArchiveSpanReader() (spanstore.Reader, error) { factory, ok := f.archiveFactories[f.SpanReaderType] if !ok { return nil, fmt.Errorf("no %s backend registered for span store", f.SpanReaderType) @@ -324,7 +324,7 @@ func (f *Factory) CreateArchiveSpanReader() (spanstore.Reader, error) { return factory.CreateSpanReader() } -func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { +func (f *Factory) createArchiveSpanWriter() (spanstore.Writer, error) { factory, ok := f.archiveFactories[f.SpanWriterTypes[0]] if !ok { return nil, fmt.Errorf("no %s backend registered for span store", f.SpanWriterTypes[0]) @@ -332,6 +332,23 @@ func (f *Factory) CreateArchiveSpanWriter() (spanstore.Writer, error) { return factory.CreateSpanWriter() } +func (f *Factory) InitArchiveStorage( + logger *zap.Logger, +) (spanstore.Reader, spanstore.Writer) { + reader, err := f.createArchiveSpanReader() + if err != nil { + logger.Error("Cannot init archive storage reader", zap.Error(err)) + return nil, nil + } + writer, err := f.createArchiveSpanWriter() + if err != nil { + logger.Error("Cannot init archive storage writer", zap.Error(err)) + return nil, nil + } + + return reader, writer +} + var _ io.Closer = (*Factory)(nil) // Close closes the resources held by the factory From 8fc468035c2eb41323f3e041169464abd6d8f0b0 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 14:24:38 -0500 Subject: [PATCH 19/74] Refactor Cassandra Configuration Signed-off-by: Mahad Zaryab --- .../extension/jaegerstorage/config.go | 2 +- plugin/storage/cassandra/factory.go | 16 +++---- plugin/storage/cassandra/options.go | 45 +++++++++---------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/cmd/jaeger/internal/extension/jaegerstorage/config.go b/cmd/jaeger/internal/extension/jaegerstorage/config.go index 460e5cbc78f..0612a805019 100644 --- a/cmd/jaeger/internal/extension/jaegerstorage/config.go +++ b/cmd/jaeger/internal/extension/jaegerstorage/config.go @@ -74,7 +74,7 @@ func (cfg *TraceBackend) Unmarshal(conf *confmap.Conf) error { } if conf.IsSet("cassandra") { cfg.Cassandra = &cassandra.Options{ - Primary: cassandra.NamespaceConfig{ + NamespaceConfig: cassandra.NamespaceConfig{ Configuration: casCfg.DefaultConfiguration(), Enabled: true, }, diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 2db8f18654d..15eef48f7a5 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -36,8 +36,8 @@ import ( ) const ( - primaryStorageConfig = "cassandra" - archiveStorageConfig = "cassandra-archive" + primaryStorageNamespace = "cassandra" + archiveStorageNamespace = "cassandra-archive" ) var ( // interface comformance checks @@ -68,7 +68,7 @@ type Factory struct { func NewFactory() *Factory { return &Factory{ tracer: otel.GetTracerProvider(), - Options: NewOptions(primaryStorageConfig), + Options: NewOptions(primaryStorageNamespace), sessionBuilderFn: NewSession, } } @@ -76,7 +76,7 @@ func NewFactory() *Factory { func NewArchiveFactory() *Factory { return &Factory{ tracer: otel.GetTracerProvider(), - Options: NewOptions(archiveStorageConfig), + Options: NewOptions(archiveStorageNamespace), sessionBuilderFn: NewSession, } } @@ -109,7 +109,7 @@ type withConfigBuilder struct { func (b *withConfigBuilder) build() (*Factory, error) { b.f.configureFromOptions(b.opts) - if err := b.opts.Primary.Validate(); err != nil { + if err := b.opts.NamespaceConfig.Validate(); err != nil { return nil, err } err := b.initializer(b.metricsFactory, b.logger) @@ -133,7 +133,7 @@ func (f *Factory) InitFromViper(v *viper.Viper, _ *zap.Logger) { // InitFromOptions initializes factory from options. func (f *Factory) configureFromOptions(o *Options) { f.Options = o - f.config = o.GetPrimary() + f.config = o.GetConfig() } // Initialize implements storage.Factory @@ -141,11 +141,11 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) f.metricsFactory = metricsFactory f.logger = logger - primarySession, err := f.sessionBuilderFn(&f.config) + session, err := f.sessionBuilderFn(&f.config) if err != nil { return err } - f.session = primarySession + f.session = session return nil } diff --git a/plugin/storage/cassandra/options.go b/plugin/storage/cassandra/options.go index 04451bb60be..8745c4c8fbb 100644 --- a/plugin/storage/cassandra/options.go +++ b/plugin/storage/cassandra/options.go @@ -48,9 +48,9 @@ const ( // to bind them to command line flag and apply overlays, so that some configurations // (e.g. archive) may be underspecified and infer the rest of its parameters from primary. type Options struct { - Primary NamespaceConfig `mapstructure:",squash"` - SpanStoreWriteCacheTTL time.Duration `mapstructure:"span_store_write_cache_ttl"` - Index IndexConfig `mapstructure:"index"` + NamespaceConfig `mapstructure:",squash"` + SpanStoreWriteCacheTTL time.Duration `mapstructure:"span_store_write_cache_ttl"` + Index IndexConfig `mapstructure:"index"` } // IndexConfig configures indexing. @@ -76,7 +76,7 @@ type NamespaceConfig struct { func NewOptions(namespace string) *Options { // TODO all default values should be defined via cobra flags options := &Options{ - Primary: NamespaceConfig{ + NamespaceConfig: NamespaceConfig{ Configuration: config.DefaultConfiguration(), namespace: namespace, Enabled: true, @@ -89,28 +89,28 @@ func NewOptions(namespace string) *Options { // AddFlags adds flags for Options func (opt *Options) AddFlags(flagSet *flag.FlagSet) { - addFlags(flagSet, opt.Primary) - flagSet.Duration(opt.Primary.namespace+suffixSpanStoreWriteCacheTTL, + addFlags(flagSet, opt.NamespaceConfig) + flagSet.Duration(opt.namespace+suffixSpanStoreWriteCacheTTL, opt.SpanStoreWriteCacheTTL, "The duration to wait before rewriting an existing service or operation name") flagSet.String( - opt.Primary.namespace+suffixIndexTagsBlacklist, + opt.namespace+suffixIndexTagsBlacklist, opt.Index.TagBlackList, "The comma-separated list of span tags to blacklist from being indexed. All other tags will be indexed. Mutually exclusive with the whitelist option.") flagSet.String( - opt.Primary.namespace+suffixIndexTagsWhitelist, + opt.namespace+suffixIndexTagsWhitelist, opt.Index.TagWhiteList, "The comma-separated list of span tags to whitelist for being indexed. All other tags will not be indexed. Mutually exclusive with the blacklist option.") flagSet.Bool( - opt.Primary.namespace+suffixIndexLogs, + opt.namespace+suffixIndexLogs, !opt.Index.Logs, "Controls log field indexing. Set to false to disable.") flagSet.Bool( - opt.Primary.namespace+suffixIndexTags, + opt.namespace+suffixIndexTags, !opt.Index.Tags, "Controls tag indexing. Set to false to disable.") flagSet.Bool( - opt.Primary.namespace+suffixIndexProcessTags, + opt.namespace+suffixIndexProcessTags, !opt.Index.ProcessTags, "Controls process tag indexing. Set to false to disable.") } @@ -119,7 +119,7 @@ func addFlags(flagSet *flag.FlagSet, nsConfig NamespaceConfig) { tlsFlagsConfig := tlsFlagsConfig(nsConfig.namespace) tlsFlagsConfig.AddFlags(flagSet) - if nsConfig.namespace != primaryStorageConfig { + if nsConfig.namespace != primaryStorageNamespace { flagSet.Bool( nsConfig.namespace+suffixEnabled, false, @@ -196,13 +196,13 @@ func addFlags(flagSet *flag.FlagSet, nsConfig NamespaceConfig) { // InitFromViper initializes Options with properties from viper func (opt *Options) InitFromViper(v *viper.Viper) { - opt.Primary.initFromViper(v) - opt.SpanStoreWriteCacheTTL = v.GetDuration(opt.Primary.namespace + suffixSpanStoreWriteCacheTTL) - opt.Index.TagBlackList = stripWhiteSpace(v.GetString(opt.Primary.namespace + suffixIndexTagsBlacklist)) - opt.Index.TagWhiteList = stripWhiteSpace(v.GetString(opt.Primary.namespace + suffixIndexTagsWhitelist)) - opt.Index.Tags = v.GetBool(opt.Primary.namespace + suffixIndexTags) - opt.Index.Logs = v.GetBool(opt.Primary.namespace + suffixIndexLogs) - opt.Index.ProcessTags = v.GetBool(opt.Primary.namespace + suffixIndexProcessTags) + opt.NamespaceConfig.initFromViper(v) + opt.SpanStoreWriteCacheTTL = v.GetDuration(opt.NamespaceConfig.namespace + suffixSpanStoreWriteCacheTTL) + opt.Index.TagBlackList = stripWhiteSpace(v.GetString(opt.NamespaceConfig.namespace + suffixIndexTagsBlacklist)) + opt.Index.TagWhiteList = stripWhiteSpace(v.GetString(opt.NamespaceConfig.namespace + suffixIndexTagsWhitelist)) + opt.Index.Tags = v.GetBool(opt.NamespaceConfig.namespace + suffixIndexTags) + opt.Index.Logs = v.GetBool(opt.NamespaceConfig.namespace + suffixIndexLogs) + opt.Index.ProcessTags = v.GetBool(opt.NamespaceConfig.namespace + suffixIndexProcessTags) } func tlsFlagsConfig(namespace string) tlscfg.ClientFlagsConfig { @@ -213,7 +213,7 @@ func tlsFlagsConfig(namespace string) tlscfg.ClientFlagsConfig { func (cfg *NamespaceConfig) initFromViper(v *viper.Viper) { tlsFlagsConfig := tlsFlagsConfig(cfg.namespace) - if cfg.namespace != primaryStorageConfig { + if cfg.namespace != primaryStorageNamespace { cfg.Enabled = v.GetBool(cfg.namespace + suffixEnabled) } cfg.Connection.ConnectionsPerHost = v.GetInt(cfg.namespace + suffixConnPerHost) @@ -243,9 +243,8 @@ func (cfg *NamespaceConfig) initFromViper(v *viper.Viper) { cfg.Connection.TLS = tlsCfg } -// GetPrimary returns primary configuration. -func (opt *Options) GetPrimary() config.Configuration { - return opt.Primary.Configuration +func (opt *Options) GetConfig() config.Configuration { + return opt.NamespaceConfig.Configuration } // TagIndexBlacklist returns the list of blacklisted tags From 71273b5ce26298f4f161e29aa0563eda478a754d Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 14:28:55 -0500 Subject: [PATCH 20/74] Refactor ES Configuration Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory.go | 44 ++++++++++++++++++------------------ plugin/storage/es/options.go | 12 +++++----- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index a1614da26c3..1c3ea30ade9 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -78,15 +78,15 @@ func NewArchiveFactory() *Factory { opts := NewOptions(archiveNamespace) aliasSuffix := "archive" - if opts.Primary.UseReadWriteAliases { - opts.Primary.ReadAliasSuffix = aliasSuffix + "-read" - opts.Primary.WriteAliasSuffix = aliasSuffix + "-write" + if opts.Config.UseReadWriteAliases { + opts.Config.ReadAliasSuffix = aliasSuffix + "-read" + opts.Config.WriteAliasSuffix = aliasSuffix + "-write" } else { - opts.Primary.ReadAliasSuffix = aliasSuffix - opts.Primary.WriteAliasSuffix = aliasSuffix + opts.Config.ReadAliasSuffix = aliasSuffix + opts.Config.WriteAliasSuffix = aliasSuffix } - opts.Primary.UseReadWriteAliases = true + opts.Config.UseReadWriteAliases = true return &Factory{ Options: opts, @@ -133,7 +133,7 @@ func (f *Factory) InitFromViper(v *viper.Viper, _ *zap.Logger) { // configureFromOptions configures factory from Options struct. func (f *Factory) configureFromOptions(o *Options) { f.Options = o - f.config = f.Options.GetPrimary() + f.config = f.Options.GetConfig() } // Initialize implements storage.Factory. @@ -141,24 +141,24 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) f.metricsFactory = metricsFactory f.logger = logger - primaryClient, err := f.newClientFn(f.config, logger, metricsFactory) + client, err := f.newClientFn(f.config, logger, metricsFactory) if err != nil { - return fmt.Errorf("failed to create primary Elasticsearch client: %w", err) + return fmt.Errorf("failed to create Elasticsearch client: %w", err) } - f.client.Store(&primaryClient) + f.client.Store(&client) if f.config.Authentication.BasicAuthentication.PasswordFilePath != "" { - primaryWatcher, err := fswatcher.New([]string{f.config.Authentication.BasicAuthentication.PasswordFilePath}, f.onPrimaryPasswordChange, f.logger) + watcher, err := fswatcher.New([]string{f.config.Authentication.BasicAuthentication.PasswordFilePath}, f.onPasswordChange, f.logger) if err != nil { - return fmt.Errorf("failed to create watcher for primary ES client's password: %w", err) + return fmt.Errorf("failed to create watcher for ES client's password: %w", err) } - f.watchers = append(f.watchers, primaryWatcher) + f.watchers = append(f.watchers, watcher) } return nil } -func (f *Factory) getPrimaryClient() es.Client { +func (f *Factory) getClient() es.Client { if c := f.client.Load(); c != nil { return *c } @@ -167,7 +167,7 @@ func (f *Factory) getPrimaryClient() es.Client { // CreateSpanReader implements storage.Factory func (f *Factory) CreateSpanReader() (spanstore.Reader, error) { - sr, err := createSpanReader(f.getPrimaryClient, f.config, f.logger, f.tracer, f.config.ReadAliasSuffix, f.config.UseReadWriteAliases) + sr, err := createSpanReader(f.getClient, f.config, f.logger, f.tracer, f.config.ReadAliasSuffix, f.config.UseReadWriteAliases) if err != nil { return nil, err } @@ -176,12 +176,12 @@ func (f *Factory) CreateSpanReader() (spanstore.Reader, error) { // CreateSpanWriter implements storage.Factory func (f *Factory) CreateSpanWriter() (spanstore.Writer, error) { - return createSpanWriter(f.getPrimaryClient, f.config, f.metricsFactory, f.logger, f.config.WriteAliasSuffix, f.config.UseReadWriteAliases) + return createSpanWriter(f.getClient, f.config, f.metricsFactory, f.logger, f.config.WriteAliasSuffix, f.config.UseReadWriteAliases) } // CreateDependencyReader implements storage.Factory func (f *Factory) CreateDependencyReader() (dependencystore.Reader, error) { - return createDependencyReader(f.getPrimaryClient, f.config, f.logger) + return createDependencyReader(f.getClient, f.config, f.logger) } func createSpanReader( @@ -260,7 +260,7 @@ func createSpanWriter( func (f *Factory) CreateSamplingStore(int /* maxBuckets */) (samplingstore.Store, error) { params := esSampleStore.Params{ - Client: f.getPrimaryClient, + Client: f.getClient, Logger: f.logger, IndexPrefix: f.config.Indices.IndexPrefix, IndexDateLayout: f.config.Indices.Sampling.DateLayout, @@ -276,7 +276,7 @@ func (f *Factory) CreateSamplingStore(int /* maxBuckets */) (samplingstore.Store if err != nil { return nil, err } - if _, err := f.getPrimaryClient().CreateTemplate(params.PrefixedIndexName()).Body(samplingMapping).Do(context.Background()); err != nil { + if _, err := f.getClient().CreateTemplate(params.PrefixedIndexName()).Body(samplingMapping).Do(context.Background()); err != nil { return nil, fmt.Errorf("failed to create template: %w", err) } } @@ -318,12 +318,12 @@ func (f *Factory) Close() error { for _, w := range f.watchers { errs = append(errs, w.Close()) } - errs = append(errs, f.getPrimaryClient().Close()) + errs = append(errs, f.getClient().Close()) return errors.Join(errs...) } -func (f *Factory) onPrimaryPasswordChange() { +func (f *Factory) onPasswordChange() { f.onClientPasswordChange(f.config, &f.client, f.metricsFactory) } @@ -351,7 +351,7 @@ func (f *Factory) onClientPasswordChange(cfg *config.Configuration, client *atom } func (f *Factory) Purge(ctx context.Context) error { - esClient := f.getPrimaryClient() + esClient := f.getClient() _, err := esClient.DeleteIndex("*").Do(ctx) return err } diff --git a/plugin/storage/es/options.go b/plugin/storage/es/options.go index be1ecf41ad0..8c604863372 100644 --- a/plugin/storage/es/options.go +++ b/plugin/storage/es/options.go @@ -85,7 +85,7 @@ var defaultIndexOptions = config.IndexOptions{ // (e.g. archive) may be underspecified and infer the rest of its parameters from primary. type Options struct { // TODO: remove indirection - Primary namespaceConfig `mapstructure:",squash"` + Config namespaceConfig `mapstructure:",squash"` } type namespaceConfig struct { @@ -98,7 +98,7 @@ func NewOptions(namespace string) *Options { // TODO all default values should be defined via cobra flags defaultConfig := DefaultConfig() options := &Options{ - Primary: namespaceConfig{ + Config: namespaceConfig{ Configuration: defaultConfig, namespace: namespace, }, @@ -115,7 +115,7 @@ func (cfg *namespaceConfig) getTLSFlagsConfig() tlscfg.ClientFlagsConfig { // AddFlags adds flags for Options func (opt *Options) AddFlags(flagSet *flag.FlagSet) { - addFlags(flagSet, &opt.Primary) + addFlags(flagSet, &opt.Config) } func addFlags(flagSet *flag.FlagSet, nsConfig *namespaceConfig) { @@ -290,7 +290,7 @@ func addFlags(flagSet *flag.FlagSet, nsConfig *namespaceConfig) { // InitFromViper initializes Options with properties from viper func (opt *Options) InitFromViper(v *viper.Viper) { - initFromViper(&opt.Primary, v) + initFromViper(&opt.Config, v) } func initFromViper(cfg *namespaceConfig, v *viper.Viper) { @@ -371,8 +371,8 @@ func initFromViper(cfg *namespaceConfig, v *viper.Viper) { } // GetPrimary returns primary configuration. -func (opt *Options) GetPrimary() *config.Configuration { - return &opt.Primary.Configuration +func (opt *Options) GetConfig() *config.Configuration { + return &opt.Config.Configuration } // stripWhiteSpace removes all whitespace characters from a string From 03a0768562a811d695b39932e512bf429a7d03d7 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 14:35:11 -0500 Subject: [PATCH 21/74] Simplify Construction of Factory Signed-off-by: Mahad Zaryab --- plugin/storage/integration/grpc_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugin/storage/integration/grpc_test.go b/plugin/storage/integration/grpc_test.go index 98beb6c6271..52bd78b83e4 100644 --- a/plugin/storage/integration/grpc_test.go +++ b/plugin/storage/integration/grpc_test.go @@ -30,17 +30,17 @@ func (s *GRPCStorageIntegrationTestSuite) initialize(t *testing.T) { logger := zaptest.NewLogger(t, zaptest.WrapOptions(zap.AddCaller())) s.remoteStorage = StartNewRemoteMemoryStorage(t) - initFactory := func(f *grpc.Factory) { + initFactory := func() *grpc.Factory { + f := grpc.NewFactory() v, command := config.Viperize(f.AddFlags) err := command.ParseFlags(s.flags) require.NoError(t, err) f.InitFromViper(v, logger) require.NoError(t, f.Initialize(metrics.NullFactory, logger)) + return f } - f := grpc.NewFactory() - af := grpc.NewFactory() - initFactory(f) - initFactory(af) + f := initFactory() + af := initFactory() s.factory = f s.archiveFactory = af From 2195e1da39dd15901549d5fa78570050a8f6f97b Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 14:40:02 -0500 Subject: [PATCH 22/74] Remove Unused Archive Fields Signed-off-by: Mahad Zaryab --- plugin/storage/grpc/shared/grpc_client.go | 34 +++++++---------------- plugin/storage/grpc/shared/interface.go | 2 -- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/plugin/storage/grpc/shared/grpc_client.go b/plugin/storage/grpc/shared/grpc_client.go index a68a5c67071..84f7a5e3545 100644 --- a/plugin/storage/grpc/shared/grpc_client.go +++ b/plugin/storage/grpc/shared/grpc_client.go @@ -31,24 +31,20 @@ var ( // GRPCClient implements shared.StoragePlugin and reads/writes spans and dependencies type GRPCClient struct { - readerClient storage_v1.SpanReaderPluginClient - writerClient storage_v1.SpanWriterPluginClient - archiveReaderClient storage_v1.ArchiveSpanReaderPluginClient - archiveWriterClient storage_v1.ArchiveSpanWriterPluginClient - capabilitiesClient storage_v1.PluginCapabilitiesClient - depsReaderClient storage_v1.DependenciesReaderPluginClient - streamWriterClient storage_v1.StreamingSpanWriterPluginClient + readerClient storage_v1.SpanReaderPluginClient + writerClient storage_v1.SpanWriterPluginClient + capabilitiesClient storage_v1.PluginCapabilitiesClient + depsReaderClient storage_v1.DependenciesReaderPluginClient + streamWriterClient storage_v1.StreamingSpanWriterPluginClient } func NewGRPCClient(tracedConn *grpc.ClientConn, untracedConn *grpc.ClientConn) *GRPCClient { return &GRPCClient{ - readerClient: storage_v1.NewSpanReaderPluginClient(tracedConn), - writerClient: storage_v1.NewSpanWriterPluginClient(untracedConn), - archiveReaderClient: storage_v1.NewArchiveSpanReaderPluginClient(tracedConn), - archiveWriterClient: storage_v1.NewArchiveSpanWriterPluginClient(untracedConn), - capabilitiesClient: storage_v1.NewPluginCapabilitiesClient(tracedConn), - depsReaderClient: storage_v1.NewDependenciesReaderPluginClient(tracedConn), - streamWriterClient: storage_v1.NewStreamingSpanWriterPluginClient(untracedConn), + readerClient: storage_v1.NewSpanReaderPluginClient(tracedConn), + writerClient: storage_v1.NewSpanWriterPluginClient(untracedConn), + capabilitiesClient: storage_v1.NewPluginCapabilitiesClient(tracedConn), + depsReaderClient: storage_v1.NewDependenciesReaderPluginClient(tracedConn), + streamWriterClient: storage_v1.NewStreamingSpanWriterPluginClient(untracedConn), } } @@ -71,14 +67,6 @@ func (c *GRPCClient) StreamingSpanWriter() spanstore.Writer { return newStreamingSpanWriter(c.streamWriterClient) } -func (c *GRPCClient) ArchiveSpanReader() spanstore.Reader { - return &archiveReader{client: c.archiveReaderClient} -} - -func (c *GRPCClient) ArchiveSpanWriter() spanstore.Writer { - return &archiveWriter{client: c.archiveWriterClient} -} - // GetTrace takes a traceID and returns a Trace associated with that traceID func (c *GRPCClient) GetTrace(ctx context.Context, query spanstore.GetTraceParameters) (*model.Trace, error) { stream, err := c.readerClient.GetTrace(ctx, &storage_v1.GetTraceRequest{ @@ -242,8 +230,6 @@ func (c *GRPCClient) Capabilities() (*Capabilities, error) { } return &Capabilities{ - ArchiveSpanReader: capabilities.ArchiveSpanReader, - ArchiveSpanWriter: capabilities.ArchiveSpanWriter, StreamingSpanWriter: capabilities.StreamingSpanWriter, }, nil } diff --git a/plugin/storage/grpc/shared/interface.go b/plugin/storage/grpc/shared/interface.go index 593db99c45c..42a7f91937f 100644 --- a/plugin/storage/grpc/shared/interface.go +++ b/plugin/storage/grpc/shared/interface.go @@ -27,8 +27,6 @@ type PluginCapabilities interface { // Capabilities contains information about plugin capabilities type Capabilities struct { - ArchiveSpanReader bool - ArchiveSpanWriter bool StreamingSpanWriter bool } From 42c575117ad6687ded6c0dff53de673437ebd89d Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 22:39:10 -0500 Subject: [PATCH 23/74] Fix GRPC Handler And Client Tests Signed-off-by: Mahad Zaryab --- .../storage/grpc/shared/grpc_client_test.go | 149 ++---------------- .../storage/grpc/shared/grpc_handler_test.go | 4 +- 2 files changed, 18 insertions(+), 135 deletions(-) diff --git a/plugin/storage/grpc/shared/grpc_client_test.go b/plugin/storage/grpc/shared/grpc_client_test.go index 85814a3163a..d7a16c39082 100644 --- a/plugin/storage/grpc/shared/grpc_client_test.go +++ b/plugin/storage/grpc/shared/grpc_client_test.go @@ -60,42 +60,34 @@ var ( ) type grpcClientTest struct { - client *GRPCClient - spanReader *grpcMocks.SpanReaderPluginClient - spanWriter *grpcMocks.SpanWriterPluginClient - archiveReader *grpcMocks.ArchiveSpanReaderPluginClient - archiveWriter *grpcMocks.ArchiveSpanWriterPluginClient - capabilities *grpcMocks.PluginCapabilitiesClient - depsReader *grpcMocks.DependenciesReaderPluginClient - streamWriter *grpcMocks.StreamingSpanWriterPluginClient + client *GRPCClient + spanReader *grpcMocks.SpanReaderPluginClient + spanWriter *grpcMocks.SpanWriterPluginClient + capabilities *grpcMocks.PluginCapabilitiesClient + depsReader *grpcMocks.DependenciesReaderPluginClient + streamWriter *grpcMocks.StreamingSpanWriterPluginClient } func withGRPCClient(fn func(r *grpcClientTest)) { spanReader := new(grpcMocks.SpanReaderPluginClient) - archiveReader := new(grpcMocks.ArchiveSpanReaderPluginClient) spanWriter := new(grpcMocks.SpanWriterPluginClient) - archiveWriter := new(grpcMocks.ArchiveSpanWriterPluginClient) depReader := new(grpcMocks.DependenciesReaderPluginClient) streamWriter := new(grpcMocks.StreamingSpanWriterPluginClient) capabilities := new(grpcMocks.PluginCapabilitiesClient) r := &grpcClientTest{ client: &GRPCClient{ - readerClient: spanReader, - writerClient: spanWriter, - archiveReaderClient: archiveReader, - archiveWriterClient: archiveWriter, - capabilitiesClient: capabilities, - depsReaderClient: depReader, - streamWriterClient: streamWriter, + readerClient: spanReader, + writerClient: spanWriter, + capabilitiesClient: capabilities, + depsReaderClient: depReader, + streamWriterClient: streamWriter, }, - spanReader: spanReader, - spanWriter: spanWriter, - archiveReader: archiveReader, - archiveWriter: archiveWriter, - depsReader: depReader, - capabilities: capabilities, - streamWriter: streamWriter, + spanReader: spanReader, + spanWriter: spanWriter, + depsReader: depReader, + capabilities: capabilities, + streamWriter: streamWriter, } fn(r) } @@ -107,8 +99,6 @@ func TestNewGRPCClient(t *testing.T) { assert.Implements(t, (*storage_v1.SpanReaderPluginClient)(nil), client.readerClient) assert.Implements(t, (*storage_v1.SpanWriterPluginClient)(nil), client.writerClient) - assert.Implements(t, (*storage_v1.ArchiveSpanReaderPluginClient)(nil), client.archiveReaderClient) - assert.Implements(t, (*storage_v1.ArchiveSpanWriterPluginClient)(nil), client.archiveWriterClient) assert.Implements(t, (*storage_v1.PluginCapabilitiesClient)(nil), client.capabilitiesClient) assert.Implements(t, (*storage_v1.DependenciesReaderPluginClient)(nil), client.depsReaderClient) assert.Implements(t, (*storage_v1.StreamingSpanWriterPluginClient)(nil), client.streamWriterClient) @@ -338,28 +328,6 @@ func TestGRPCClientGetDependencies(t *testing.T) { }) } -func TestGrpcClientWriteArchiveSpan(t *testing.T) { - withGRPCClient(func(r *grpcClientTest) { - r.archiveWriter.On("WriteArchiveSpan", mock.Anything, &storage_v1.WriteSpanRequest{ - Span: &mockTraceSpans[0], - }).Return(&storage_v1.WriteSpanResponse{}, nil) - - err := r.client.ArchiveSpanWriter().WriteSpan(context.Background(), &mockTraceSpans[0]) - require.NoError(t, err) - }) -} - -func TestGrpcClientWriteArchiveSpan_Error(t *testing.T) { - withGRPCClient(func(r *grpcClientTest) { - r.archiveWriter.On("WriteArchiveSpan", mock.Anything, &storage_v1.WriteSpanRequest{ - Span: &mockTraceSpans[0], - }).Return(nil, status.Error(codes.Internal, "internal error")) - - err := r.client.ArchiveSpanWriter().WriteSpan(context.Background(), &mockTraceSpans[0]) - require.Error(t, err) - }) -} - func TestGrpcClientStreamWriterWriteSpan(t *testing.T) { withGRPCClient(func(r *grpcClientTest) { stream := new(grpcMocks.StreamingSpanWriterPlugin_WriteSpanStreamClient) @@ -370,87 +338,6 @@ func TestGrpcClientStreamWriterWriteSpan(t *testing.T) { }) } -func TestGrpcClientGetArchiveTrace(t *testing.T) { - withGRPCClient(func(r *grpcClientTest) { - startTime := time.Date(2020, time.January, 1, 13, 0, 0, 0, time.UTC) - endTime := time.Date(2020, time.January, 1, 14, 0, 0, 0, time.UTC) - traceClient := new(grpcMocks.ArchiveSpanReaderPlugin_GetArchiveTraceClient) - traceClient.On("Recv").Return(&storage_v1.SpansResponseChunk{ - Spans: mockTraceSpans, - }, nil).Once() - traceClient.On("Recv").Return(nil, io.EOF) - r.archiveReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - StartTime: startTime, - EndTime: endTime, - }).Return(traceClient, nil) - - var expectedSpans []*model.Span - for i := range mockTraceSpans { - expectedSpans = append(expectedSpans, &mockTraceSpans[i]) - } - - s, err := r.client.ArchiveSpanReader().GetTrace(context.Background(), spanstore.GetTraceParameters{ - TraceID: mockTraceID, - StartTime: startTime, - EndTime: endTime, - }) - require.NoError(t, err) - assert.Equal(t, &model.Trace{ - Spans: expectedSpans, - }, s) - }) -} - -func TestGrpcClientGetArchiveTrace_StreamError(t *testing.T) { - withGRPCClient(func(r *grpcClientTest) { - traceClient := new(grpcMocks.ArchiveSpanReaderPlugin_GetArchiveTraceClient) - traceClient.On("Recv").Return(nil, errors.New("an error")) - r.archiveReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - }).Return(traceClient, nil) - - s, err := r.client.ArchiveSpanReader().GetTrace(context.Background(), spanstore.GetTraceParameters{ - TraceID: mockTraceID, - }) - require.Error(t, err) - assert.Nil(t, s) - }) -} - -func TestGrpcClientGetArchiveTrace_NoTrace(t *testing.T) { - withGRPCClient(func(r *grpcClientTest) { - r.archiveReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - }).Return(nil, spanstore.ErrTraceNotFound) - - s, err := r.client.ArchiveSpanReader().GetTrace( - context.Background(), - spanstore.GetTraceParameters{ - TraceID: mockTraceID, - }, - ) - require.Error(t, err) - assert.Nil(t, s) - }) -} - -func TestGrpcClientGetArchiveTrace_StreamErrorTraceNotFound(t *testing.T) { - withGRPCClient(func(r *grpcClientTest) { - traceClient := new(grpcMocks.ArchiveSpanReaderPlugin_GetArchiveTraceClient) - traceClient.On("Recv").Return(nil, spanstore.ErrTraceNotFound) - r.archiveReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - }).Return(traceClient, nil) - - s, err := r.client.ArchiveSpanReader().GetTrace(context.Background(), spanstore.GetTraceParameters{ - TraceID: mockTraceID, - }) - assert.Equal(t, spanstore.ErrTraceNotFound, err) - assert.Nil(t, s) - }) -} - func TestGrpcClientCapabilities(t *testing.T) { withGRPCClient(func(r *grpcClientTest) { r.capabilities.On("Capabilities", mock.Anything, &storage_v1.CapabilitiesRequest{}). @@ -459,8 +346,6 @@ func TestGrpcClientCapabilities(t *testing.T) { capabilities, err := r.client.Capabilities() require.NoError(t, err) assert.Equal(t, &Capabilities{ - ArchiveSpanReader: true, - ArchiveSpanWriter: true, StreamingSpanWriter: true, }, capabilities) }) @@ -474,8 +359,6 @@ func TestGrpcClientCapabilities_NotSupported(t *testing.T) { capabilities, err := r.client.Capabilities() require.NoError(t, err) assert.Equal(t, &Capabilities{ - ArchiveSpanReader: false, - ArchiveSpanWriter: false, StreamingSpanWriter: false, }, capabilities) }) diff --git a/plugin/storage/grpc/shared/grpc_handler_test.go b/plugin/storage/grpc/shared/grpc_handler_test.go index 726ea30c6b4..5bce060ad3f 100644 --- a/plugin/storage/grpc/shared/grpc_handler_test.go +++ b/plugin/storage/grpc/shared/grpc_handler_test.go @@ -80,7 +80,7 @@ func withGRPCServer(fn func(r *grpcServerTest)) { streamWriter: streamWriter, } - handler := NewGRPCHandlerWithPlugins(impl, impl, impl) + handler := NewGRPCHandlerWithPlugins(impl, impl) defer handler.Close(context.Background(), &storage_v1.CloseWriterRequest{}) r := &grpcServerTest{ server: handler, @@ -445,7 +445,7 @@ func TestNewGRPCHandlerWithPlugins_Nils(t *testing.T) { depsReader: depReader, } - handler := NewGRPCHandlerWithPlugins(impl, nil, nil) + handler := NewGRPCHandlerWithPlugins(impl, nil) assert.Nil(t, handler.impl.ArchiveSpanReader()) assert.Nil(t, handler.impl.ArchiveSpanWriter()) assert.Nil(t, handler.impl.StreamingSpanWriter()) From 0e4f7f7b946d776904f89de9bc47e75b3b03a948 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 22:47:12 -0500 Subject: [PATCH 24/74] Fix ES Unit Tests Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory_test.go | 124 ++++-------------------------- plugin/storage/es/options_test.go | 48 +++--------- 2 files changed, 23 insertions(+), 149 deletions(-) diff --git a/plugin/storage/es/factory_test.go b/plugin/storage/es/factory_test.go index 7dcd103ebf1..8ce8bdc3313 100644 --- a/plugin/storage/es/factory_test.go +++ b/plugin/storage/es/factory_test.go @@ -8,7 +8,6 @@ import ( "context" "encoding/base64" "errors" - "fmt" "net/http" "net/http/httptest" "os" @@ -70,7 +69,6 @@ func TestElasticsearchFactory(t *testing.T) { f.newClientFn = (&mockClientBuilder{err: errors.New("made-up error")}).NewClient require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "failed to create primary Elasticsearch client: made-up error") - f.archiveConfig.Enabled = true f.newClientFn = func(c *escfg.Configuration, logger *zap.Logger, metricsFactory metrics.Factory) (es.Client, error) { // to test archive storage error, pretend that primary client creation is successful // but override newClientFn so it fails for the next invocation @@ -91,12 +89,6 @@ func TestElasticsearchFactory(t *testing.T) { _, err = f.CreateDependencyReader() require.NoError(t, err) - _, err = f.CreateArchiveSpanReader() - require.NoError(t, err) - - _, err = f.CreateArchiveSpanWriter() - require.NoError(t, err) - _, err = f.CreateSamplingStore(1) require.NoError(t, err) @@ -105,12 +97,11 @@ func TestElasticsearchFactory(t *testing.T) { func TestElasticsearchTagsFileDoNotExist(t *testing.T) { f := NewFactory() - f.primaryConfig = &escfg.Configuration{ + f.config = &escfg.Configuration{ Tags: escfg.TagsAsFields{ File: "fixtures/file-does-not-exist.txt", }, } - f.archiveConfig = &escfg.Configuration{} f.newClientFn = (&mockClientBuilder{}).NewClient require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) defer f.Close() @@ -121,13 +112,9 @@ func TestElasticsearchTagsFileDoNotExist(t *testing.T) { func TestElasticsearchILMUsedWithoutReadWriteAliases(t *testing.T) { f := NewFactory() - f.primaryConfig = &escfg.Configuration{ + f.config = &escfg.Configuration{ UseILM: true, } - f.archiveConfig = &escfg.Configuration{ - Enabled: true, - UseILM: true, - } f.newClientFn = (&mockClientBuilder{}).NewClient require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) defer f.Close() @@ -138,10 +125,6 @@ func TestElasticsearchILMUsedWithoutReadWriteAliases(t *testing.T) { r, err := f.CreateSpanReader() require.EqualError(t, err, "--es.use-ilm must always be used in conjunction with --es.use-aliases to ensure ES writers and readers refer to the single index mapping") assert.Nil(t, r) - - ar, err := f.CreateArchiveSpanReader() - require.EqualError(t, err, "--es.use-ilm must always be used in conjunction with --es.use-aliases to ensure ES writers and readers refer to the single index mapping") - assert.Nil(t, ar) } func TestTagKeysAsFields(t *testing.T) { @@ -203,8 +186,7 @@ func TestTagKeysAsFields(t *testing.T) { func TestCreateTemplateError(t *testing.T) { f := NewFactory() - f.primaryConfig = &escfg.Configuration{CreateIndexTemplates: true} - f.archiveConfig = &escfg.Configuration{} + f.config = &escfg.Configuration{CreateIndexTemplates: true} f.newClientFn = (&mockClientBuilder{createTemplateError: errors.New("template-error")}).NewClient err := f.Initialize(metrics.NullFactory, zap.NewNop()) require.NoError(t, err) @@ -221,8 +203,7 @@ func TestCreateTemplateError(t *testing.T) { func TestILMDisableTemplateCreation(t *testing.T) { f := NewFactory() - f.primaryConfig = &escfg.Configuration{UseILM: true, UseReadWriteAliases: true, CreateIndexTemplates: true} - f.archiveConfig = &escfg.Configuration{} + f.config = &escfg.Configuration{UseILM: true, UseReadWriteAliases: true, CreateIndexTemplates: true} f.newClientFn = (&mockClientBuilder{createTemplateError: errors.New("template-error")}).NewClient err := f.Initialize(metrics.NullFactory, zap.NewNop()) defer f.Close() @@ -231,57 +212,13 @@ func TestILMDisableTemplateCreation(t *testing.T) { require.NoError(t, err) // as the createTemplate is not called, CreateSpanWriter should not return an error } -func TestArchiveDisabled(t *testing.T) { - f := NewFactory() - f.archiveConfig = &escfg.Configuration{Enabled: false} - f.newClientFn = (&mockClientBuilder{}).NewClient - w, err := f.CreateArchiveSpanWriter() - assert.Nil(t, w) - require.NoError(t, err) - r, err := f.CreateArchiveSpanReader() - assert.Nil(t, r) - require.NoError(t, err) -} - -func TestArchiveEnabled(t *testing.T) { - tests := []struct { - useReadWriteAliases bool - }{ - { - useReadWriteAliases: false, - }, - { - useReadWriteAliases: true, - }, - } - for _, test := range tests { - t.Run(fmt.Sprintf("useReadWriteAliases=%v", test.useReadWriteAliases), func(t *testing.T) { - f := NewFactory() - f.primaryConfig = &escfg.Configuration{} - f.archiveConfig = &escfg.Configuration{Enabled: true, UseReadWriteAliases: test.useReadWriteAliases} - f.newClientFn = (&mockClientBuilder{}).NewClient - err := f.Initialize(metrics.NullFactory, zap.NewNop()) - require.NoError(t, err) - defer f.Close() // Ensure resources are cleaned up if initialization is successful - w, err := f.CreateArchiveSpanWriter() - require.NoError(t, err) - assert.NotNil(t, w) - r, err := f.CreateArchiveSpanReader() - require.NoError(t, err) - assert.NotNil(t, r) - }) - } -} - func TestConfigureFromOptions(t *testing.T) { f := NewFactory() o := &Options{ - Primary: namespaceConfig{Configuration: escfg.Configuration{Servers: []string{"server"}}}, - others: map[string]*namespaceConfig{"es-archive": {Configuration: escfg.Configuration{Servers: []string{"server2"}}}}, + Config: namespaceConfig{Configuration: escfg.Configuration{Servers: []string{"server"}}}, } f.configureFromOptions(o) - assert.Equal(t, o.GetPrimary(), f.primaryConfig) - assert.Equal(t, o.Get(archiveNamespace), f.archiveConfig) + assert.Equal(t, o.GetConfig(), f.config) } func TestESStorageFactoryWithConfig(t *testing.T) { @@ -346,12 +283,7 @@ func TestPasswordFromFile(t *testing.T) { defer testutils.VerifyGoLeaksOnce(t) t.Run("primary client", func(t *testing.T) { f := NewFactory() - testPasswordFromFile(t, f, f.getPrimaryClient, f.CreateSpanWriter) - }) - - t.Run("archive client", func(t *testing.T) { - f2 := NewFactory() - testPasswordFromFile(t, f2, f2.getArchiveClient, f2.CreateArchiveSpanWriter) + testPasswordFromFile(t, f, f.getClient, f.CreateSpanWriter) }) t.Run("load token error", func(t *testing.T) { @@ -391,21 +323,7 @@ func testPasswordFromFile(t *testing.T, f *Factory, getClient func() es.Client, pwdFile := filepath.Join(t.TempDir(), "pwd") require.NoError(t, os.WriteFile(pwdFile, []byte(pwd1), 0o600)) - f.primaryConfig = &escfg.Configuration{ - Servers: []string{server.URL}, - LogLevel: "debug", - Authentication: escfg.Authentication{ - BasicAuthentication: escfg.BasicAuthentication{ - Username: "user", - PasswordFilePath: pwdFile, - }, - }, - BulkProcessing: escfg.BulkProcessing{ - MaxBytes: -1, // disable bulk; we want immediate flush - }, - } - f.archiveConfig = &escfg.Configuration{ - Enabled: true, + f.config = &escfg.Configuration{ Servers: []string{server.URL}, LogLevel: "debug", Authentication: escfg.Authentication{ @@ -464,8 +382,7 @@ func testPasswordFromFile(t *testing.T, f *Factory, getClient func() es.Client, func TestFactoryESClientsAreNil(t *testing.T) { f := &Factory{} - assert.Nil(t, f.getPrimaryClient()) - assert.Nil(t, f.getArchiveClient()) + assert.Nil(t, f.getClient()) } func TestPasswordFromFileErrors(t *testing.T) { @@ -479,16 +396,7 @@ func TestPasswordFromFileErrors(t *testing.T) { require.NoError(t, os.WriteFile(pwdFile, []byte("first password"), 0o600)) f := NewFactory() - f.primaryConfig = &escfg.Configuration{ - Servers: []string{server.URL}, - LogLevel: "debug", - Authentication: escfg.Authentication{ - BasicAuthentication: escfg.BasicAuthentication{ - PasswordFilePath: pwdFile, - }, - }, - } - f.archiveConfig = &escfg.Configuration{ + f.config = &escfg.Configuration{ Servers: []string{server.URL}, LogLevel: "debug", Authentication: escfg.Authentication{ @@ -502,16 +410,10 @@ func TestPasswordFromFileErrors(t *testing.T) { require.NoError(t, f.Initialize(metrics.NullFactory, logger)) defer f.Close() - f.primaryConfig.Servers = []string{} - f.onPrimaryPasswordChange() - assert.Contains(t, buf.String(), "no servers specified") - - f.archiveConfig.Servers = []string{} - buf.Reset() - f.onArchivePasswordChange() + f.config.Servers = []string{} + f.onPasswordChange() assert.Contains(t, buf.String(), "no servers specified") require.NoError(t, os.Remove(pwdFile)) - f.onPrimaryPasswordChange() - f.onArchivePasswordChange() + f.onPasswordChange() } diff --git a/plugin/storage/es/options_test.go b/plugin/storage/es/options_test.go index 87b2ce11d7f..f013319cf08 100644 --- a/plugin/storage/es/options_test.go +++ b/plugin/storage/es/options_test.go @@ -5,7 +5,6 @@ package es import ( - "net/http" "testing" "time" @@ -18,7 +17,7 @@ import ( func TestOptions(t *testing.T) { opts := NewOptions("foo") - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.Empty(t, primary.Authentication.BasicAuthentication.Username) assert.Empty(t, primary.Authentication.BasicAuthentication.Password) assert.Empty(t, primary.Authentication.BasicAuthentication.PasswordFilePath) @@ -35,16 +34,10 @@ func TestOptions(t *testing.T) { assert.Equal(t, 72*time.Hour, primary.MaxSpanAge) assert.False(t, primary.Sniffing.Enabled) assert.False(t, primary.Sniffing.UseHTTPS) - - aux := opts.Get("archive") - assert.Equal(t, primary.Authentication.BasicAuthentication.Username, aux.Authentication.BasicAuthentication.Username) - assert.Equal(t, primary.Authentication.BasicAuthentication.Password, aux.Authentication.BasicAuthentication.Password) - assert.Equal(t, primary.Authentication.BasicAuthentication.PasswordFilePath, aux.Authentication.BasicAuthentication.PasswordFilePath) - assert.Equal(t, primary.Servers, aux.Servers) } func TestOptionsWithFlags(t *testing.T) { - opts := NewOptions("es", "es.aux") + opts := NewOptions("es") v, command := config.Viperize(opts.AddFlags) err := command.ParseFlags([]string{ "--es.server-urls=1.1.1.1, 2.2.2.2", @@ -79,7 +72,7 @@ func TestOptionsWithFlags(t *testing.T) { require.NoError(t, err) opts.InitFromViper(v) - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.Equal(t, "hello", primary.Authentication.BasicAuthentication.Username) assert.Equal(t, "world", primary.Authentication.BasicAuthentication.Password) assert.Equal(t, "/foo/bar", primary.Authentication.BearerTokenAuthentication.FilePath) @@ -97,32 +90,11 @@ func TestOptionsWithFlags(t *testing.T) { assert.Equal(t, "test,tags", primary.Tags.Include) assert.Equal(t, "20060102", primary.Indices.Services.DateLayout) assert.Equal(t, "2006010215", primary.Indices.Spans.DateLayout) - aux := opts.Get("es.aux") - assert.Equal(t, []string{"3.3.3.3", "4.4.4.4"}, aux.Servers) - assert.Equal(t, "hello", aux.Authentication.BasicAuthentication.Username) - assert.Equal(t, "world", aux.Authentication.BasicAuthentication.Password) - assert.EqualValues(t, 5, aux.Indices.Spans.Shards) - assert.EqualValues(t, 5, aux.Indices.Services.Shards) - assert.EqualValues(t, 5, aux.Indices.Sampling.Shards) - assert.EqualValues(t, 5, aux.Indices.Dependencies.Shards) - assert.EqualValues(t, 10, aux.Indices.Spans.Replicas) - assert.EqualValues(t, 10, aux.Indices.Services.Replicas) - assert.EqualValues(t, 10, aux.Indices.Sampling.Replicas) - assert.EqualValues(t, 10, aux.Indices.Dependencies.Replicas) - assert.Equal(t, 24*time.Hour, aux.MaxSpanAge) - assert.True(t, aux.Sniffing.Enabled) - assert.True(t, aux.Tags.AllAsFields) - assert.Equal(t, "@", aux.Tags.DotReplacement) - assert.Equal(t, "./file.txt", aux.Tags.File) - assert.Equal(t, "test,tags", aux.Tags.Include) - assert.Equal(t, "2006.01.02", aux.Indices.Services.DateLayout) - assert.Equal(t, "2006.01.02.15", aux.Indices.Spans.DateLayout) assert.True(t, primary.UseILM) - assert.Equal(t, http.MethodPost, aux.SendGetBodyAs) } func TestEmptyRemoteReadClusters(t *testing.T) { - opts := NewOptions("es", "es.aux") + opts := NewOptions("es") v, command := config.Viperize(opts.AddFlags) err := command.ParseFlags([]string{ "--es.remote-read-clusters=", @@ -130,12 +102,12 @@ func TestEmptyRemoteReadClusters(t *testing.T) { require.NoError(t, err) opts.InitFromViper(v) - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.Equal(t, []string{}, primary.RemoteReadClusters) } func TestMaxSpanAgeSetErrorInArchiveMode(t *testing.T) { - opts := NewOptions("es", archiveNamespace) + opts := NewOptions(archiveNamespace) _, command := config.Viperize(opts.AddFlags) flags := []string{"--es-archive.max-span-age=24h"} err := command.ParseFlags(flags) @@ -153,12 +125,12 @@ func TestMaxDocCount(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - opts := NewOptions("es", "es.aux") + opts := NewOptions("es") v, command := config.Viperize(opts.AddFlags) command.ParseFlags(tc.flags) opts.InitFromViper(v) - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.Equal(t, tc.wantMaxDocCount, primary.MaxDocCount) }) } @@ -184,7 +156,7 @@ func TestIndexDateSeparator(t *testing.T) { command.ParseFlags(tc.flags) opts.InitFromViper(v) - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.Equal(t, tc.wantDateLayout, primary.Indices.Spans.DateLayout) }) } @@ -238,7 +210,7 @@ func TestIndexRollover(t *testing.T) { v, command := config.Viperize(opts.AddFlags) command.ParseFlags(tc.flags) opts.InitFromViper(v) - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.Equal(t, tc.wantSpanDateLayout, primary.Indices.Spans.DateLayout) assert.Equal(t, tc.wantServiceDateLayout, primary.Indices.Services.DateLayout) assert.Equal(t, tc.wantSpanIndexRolloverFrequency, escfg.RolloverFrequencyAsNegativeDuration(primary.Indices.Spans.RolloverFrequency)) From a14a64979dddd3ca3a6ee1cccd61b5ca58c73048 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 22:53:00 -0500 Subject: [PATCH 25/74] Fix Cassandra Tests Signed-off-by: Mahad Zaryab --- plugin/storage/cassandra/factory_test.go | 37 ++++---------------- plugin/storage/cassandra/options_test.go | 43 +++--------------------- 2 files changed, 10 insertions(+), 70 deletions(-) diff --git a/plugin/storage/cassandra/factory_test.go b/plugin/storage/cassandra/factory_test.go index 20f7ca54d5f..a0864631f75 100644 --- a/plugin/storage/cassandra/factory_test.go +++ b/plugin/storage/cassandra/factory_test.go @@ -46,7 +46,7 @@ func (m *mockSessionBuilder) build(*config.Configuration) (cassandra.Session, er } func TestCassandraFactory(t *testing.T) { - logger, logBuf := testutils.NewLogger() + logger, _ := testutils.NewLogger() f := NewFactory() v, command := viperize.Viperize(f.AddFlags) command.ParseFlags([]string{"--cassandra-archive.enabled=true"}) @@ -67,10 +67,8 @@ func TestCassandraFactory(t *testing.T) { add(nil, errors.New("made-up archive error")).build require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "made-up archive error") - f.archiveConfig = nil f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).build require.NoError(t, f.Initialize(metrics.NullFactory, logger)) - assert.Contains(t, logBuf.String(), "Cassandra archive storage configuration is empty, skipping") _, err := f.CreateSpanReader() require.NoError(t, err) @@ -81,22 +79,9 @@ func TestCassandraFactory(t *testing.T) { _, err = f.CreateDependencyReader() require.NoError(t, err) - _, err = f.CreateArchiveSpanReader() - require.EqualError(t, err, "archive storage not configured") - - _, err = f.CreateArchiveSpanWriter() - require.EqualError(t, err, "archive storage not configured") - - f.archiveConfig = &config.Configuration{} f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).add(session, nil).build require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) - _, err = f.CreateArchiveSpanReader() - require.NoError(t, err) - - _, err = f.CreateArchiveSpanWriter() - require.NoError(t, err) - _, err = f.CreateLock() require.NoError(t, err) @@ -117,15 +102,11 @@ func TestCreateSpanReaderError(t *testing.T) { mock.Anything).Return(query) query.On("Exec").Return(errors.New("table does not exist")) f := NewFactory() - f.archiveConfig = &config.Configuration{} f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).add(session, nil).build require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) r, err := f.CreateSpanReader() require.Error(t, err) require.Nil(t, r) - ar, err := f.CreateArchiveSpanReader() - require.Error(t, err) - require.Nil(t, ar) } func TestExclusiveWhitelistBlacklist(t *testing.T) { @@ -149,12 +130,8 @@ func TestExclusiveWhitelistBlacklist(t *testing.T) { _, err := f.CreateSpanWriter() require.EqualError(t, err, "only one of TagIndexBlacklist and TagIndexWhitelist can be specified") - f.archiveConfig = &config.Configuration{} f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).add(session, nil).build require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) - - _, err = f.CreateArchiveSpanWriter() - require.EqualError(t, err, "only one of TagIndexBlacklist and TagIndexWhitelist can be specified") } func TestWriterOptions(t *testing.T) { @@ -201,18 +178,16 @@ func TestWriterOptions(t *testing.T) { func TestConfigureFromOptions(t *testing.T) { f := NewFactory() - o := NewOptions("foo", archiveStorageConfig) - o.others[archiveStorageConfig].Enabled = true + o := NewOptions("foo") f.configureFromOptions(o) assert.Equal(t, o, f.Options) - assert.Equal(t, o.GetPrimary(), f.primaryConfig) - assert.Equal(t, o.Get(archiveStorageConfig), f.archiveConfig) + assert.Equal(t, o.GetConfig(), f.config) } func TestNewFactoryWithConfig(t *testing.T) { t.Run("valid configuration", func(t *testing.T) { opts := &Options{ - Primary: NamespaceConfig{ + NamespaceConfig: NamespaceConfig{ Configuration: config.DefaultConfiguration(), }, } @@ -230,7 +205,7 @@ func TestNewFactoryWithConfig(t *testing.T) { t.Run("connection error", func(t *testing.T) { expErr := errors.New("made-up error") opts := &Options{ - Primary: NamespaceConfig{ + NamespaceConfig: NamespaceConfig{ Configuration: config.DefaultConfiguration(), }, } @@ -260,7 +235,7 @@ func TestFactory_Purge(t *testing.T) { ) session.On("Query", mock.AnythingOfType("string"), mock.Anything).Return(query) query.On("Exec").Return(nil) - f.primarySession = session + f.session = session err := f.Purge(context.Background()) require.NoError(t, err) diff --git a/plugin/storage/cassandra/options_test.go b/plugin/storage/cassandra/options_test.go index 8ccd813c838..35976ebe8fb 100644 --- a/plugin/storage/cassandra/options_test.go +++ b/plugin/storage/cassandra/options_test.go @@ -6,36 +6,22 @@ package cassandra import ( "testing" - "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/jaegertracing/jaeger/pkg/config" ) func TestOptions(t *testing.T) { opts := NewOptions("foo") - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.NotEmpty(t, primary.Schema.Keyspace) assert.NotEmpty(t, primary.Connection.Servers) assert.Equal(t, 2, primary.Connection.ConnectionsPerHost) - - aux := opts.Get("archive") - assert.Nil(t, aux) - - assert.NotNil(t, opts.others["archive"]) - opts.others["archive"].Enabled = true - aux = opts.Get("archive") - require.NotNil(t, aux) - assert.Equal(t, primary.Schema.Keyspace, aux.Schema.Keyspace) - assert.Equal(t, primary.Connection.Servers, aux.Connection.Servers) - assert.Equal(t, primary.Connection.ConnectionsPerHost, aux.Connection.ConnectionsPerHost) - assert.Equal(t, primary.Connection.ReconnectInterval, aux.Connection.ReconnectInterval) } func TestOptionsWithFlags(t *testing.T) { - opts := NewOptions("cas", "cas-aux") + opts := NewOptions("cas") v, command := config.Viperize(opts.AddFlags) command.ParseFlags([]string{ "--cas.keyspace=jaeger", @@ -56,17 +42,10 @@ func TestOptionsWithFlags(t *testing.T) { "--cas.basic.allowed-authenticators=org.apache.cassandra.auth.PasswordAuthenticator,com.datastax.bdp.cassandra.auth.DseAuthenticator", "--cas.username=username", "--cas.password=password", - // enable aux with a couple overrides - "--cas-aux.enabled=true", - "--cas-aux.keyspace=jaeger-archive", - "--cas-aux.servers=3.3.3.3, 4.4.4.4", - "--cas-aux.username=username", - "--cas-aux.password=password", - "--cas-aux.basic.allowed-authenticators=org.apache.cassandra.auth.PasswordAuthenticator,com.ericsson.bss.cassandra.ecaudit.auth.AuditAuthenticator", }) opts.InitFromViper(v) - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.Equal(t, "jaeger", primary.Schema.Keyspace) assert.Equal(t, "mojave", primary.Connection.LocalDC) assert.Equal(t, []string{"1.1.1.1", "2.2.2.2"}, primary.Connection.Servers) @@ -77,20 +56,6 @@ func TestOptionsWithFlags(t *testing.T) { assert.True(t, opts.Index.Tags) assert.False(t, opts.Index.ProcessTags) assert.True(t, opts.Index.Logs) - - aux := opts.Get("cas-aux") - require.NotNil(t, aux) - assert.Equal(t, "jaeger-archive", aux.Schema.Keyspace) - assert.Equal(t, []string{"3.3.3.3", "4.4.4.4"}, aux.Connection.Servers) - assert.Equal(t, []string{"org.apache.cassandra.auth.PasswordAuthenticator", "com.ericsson.bss.cassandra.ecaudit.auth.AuditAuthenticator"}, aux.Connection.Authenticator.Basic.AllowedAuthenticators) - assert.Equal(t, 42, aux.Connection.ConnectionsPerHost) - assert.Equal(t, 42, aux.Query.MaxRetryAttempts) - assert.Equal(t, 42*time.Second, aux.Query.Timeout) - assert.Equal(t, 42*time.Second, aux.Connection.ReconnectInterval) - assert.Equal(t, 4242, aux.Connection.Port) - assert.Equal(t, "", aux.Query.Consistency, "aux storage does not inherit consistency from primary") - assert.Equal(t, 3, aux.Connection.ProtoVersion) - assert.Equal(t, 42*time.Second, aux.Connection.SocketKeepAlive) } func TestDefaultTlsHostVerify(t *testing.T) { @@ -101,7 +66,7 @@ func TestDefaultTlsHostVerify(t *testing.T) { }) opts.InitFromViper(v) - primary := opts.GetPrimary() + primary := opts.GetConfig() assert.False(t, primary.Connection.TLS.InsecureSkipVerify) } From bac94c8ad8b886beaaa31c5b3bff84be798b85fa Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 22:53:16 -0500 Subject: [PATCH 26/74] Fix Blackhole Test Signed-off-by: Mahad Zaryab --- plugin/storage/blackhole/factory_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugin/storage/blackhole/factory_test.go b/plugin/storage/blackhole/factory_test.go index 0ef1a783176..134e44047c1 100644 --- a/plugin/storage/blackhole/factory_test.go +++ b/plugin/storage/blackhole/factory_test.go @@ -27,12 +27,6 @@ func TestStorageFactory(t *testing.T) { writer, err := f.CreateSpanWriter() require.NoError(t, err) assert.Equal(t, f.store, writer) - reader, err = f.CreateArchiveSpanReader() - require.NoError(t, err) - assert.Equal(t, f.store, reader) - writer, err = f.CreateArchiveSpanWriter() - require.NoError(t, err) - assert.Equal(t, f.store, writer) depReader, err := f.CreateDependencyReader() require.NoError(t, err) assert.Equal(t, f.store, depReader) From f049b5a3455411950a73d1792636bfe5379436fd Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 22:55:02 -0500 Subject: [PATCH 27/74] Fix Meta Factory Tests Signed-off-by: Mahad Zaryab --- plugin/storage/factory_test.go | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/plugin/storage/factory_test.go b/plugin/storage/factory_test.go index c09f8e7504c..0271193add9 100644 --- a/plugin/storage/factory_test.go +++ b/plugin/storage/factory_test.go @@ -131,12 +131,6 @@ func TestCreate(t *testing.T) { assert.Equal(t, depReader, d) require.EqualError(t, err, "dep-reader-error") - _, err = f.CreateArchiveSpanReader() - require.EqualError(t, err, "archive storage not supported") - - _, err = f.CreateArchiveSpanWriter() - require.EqualError(t, err, "archive storage not supported") - mock.On("CreateSpanWriter").Return(spanWriter, nil) m := metrics.NullFactory l := zap.NewNop() @@ -229,14 +223,6 @@ func TestCreateArchive(t *testing.T) { mock.ArchiveFactory.On("CreateArchiveSpanReader").Return(archiveSpanReader, errors.New("archive-span-reader-error")) mock.ArchiveFactory.On("CreateArchiveSpanWriter").Return(archiveSpanWriter, errors.New("archive-span-writer-error")) - - ar, err := f.CreateArchiveSpanReader() - assert.Equal(t, archiveSpanReader, ar) - require.EqualError(t, err, "archive-span-reader-error") - - aw, err := f.CreateArchiveSpanWriter() - assert.Equal(t, archiveSpanWriter, aw) - require.EqualError(t, err, "archive-span-writer-error") } func TestCreateError(t *testing.T) { @@ -265,18 +251,6 @@ func TestCreateError(t *testing.T) { assert.Nil(t, d) require.EqualError(t, err, expectedErr) } - - { - r, err := f.CreateArchiveSpanReader() - assert.Nil(t, r) - require.EqualError(t, err, expectedErr) - } - - { - w, err := f.CreateArchiveSpanWriter() - assert.Nil(t, w) - require.EqualError(t, err, expectedErr) - } } func TestAllSamplingStorageTypes(t *testing.T) { From efb4353eef8089860ff02c41cfc09997eca35456 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 22:57:13 -0500 Subject: [PATCH 28/74] Fix GRPC Factory Tests Signed-off-by: Mahad Zaryab --- plugin/storage/grpc/factory_test.go | 49 +++++------------------------ 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/plugin/storage/grpc/factory_test.go b/plugin/storage/grpc/factory_test.go index a9bf26c49c4..4f24d5dcde1 100644 --- a/plugin/storage/grpc/factory_test.go +++ b/plugin/storage/grpc/factory_test.go @@ -28,7 +28,6 @@ import ( "github.com/jaegertracing/jaeger/pkg/tenancy" "github.com/jaegertracing/jaeger/plugin/storage/grpc/shared" "github.com/jaegertracing/jaeger/plugin/storage/grpc/shared/mocks" - "github.com/jaegertracing/jaeger/storage" "github.com/jaegertracing/jaeger/storage/dependencystore" dependencyStoreMocks "github.com/jaegertracing/jaeger/storage/dependencystore/mocks" "github.com/jaegertracing/jaeger/storage/spanstore" @@ -73,10 +72,6 @@ func makeMockServices() *ClientPluginServices { reader: new(spanStoreMocks.Reader), deps: new(dependencyStoreMocks.Reader), }, - ArchiveStore: &store{ - writer: new(spanStoreMocks.Writer), - reader: new(spanStoreMocks.Reader), - }, StreamingSpanWriter: &store{ writer: new(spanStoreMocks.Writer), }, @@ -189,20 +184,10 @@ func TestGRPCStorageFactory_Capabilities(t *testing.T) { capabilities := f.services.Capabilities.(*mocks.PluginCapabilities) capabilities.On("Capabilities"). Return(&shared.Capabilities{ - ArchiveSpanReader: true, - ArchiveSpanWriter: true, StreamingSpanWriter: true, - }, nil).Times(3) - - reader, err := f.CreateArchiveSpanReader() - require.NoError(t, err) - assert.NotNil(t, reader) - - writer, err := f.CreateArchiveSpanWriter() - require.NoError(t, err) - assert.NotNil(t, writer) + }, nil).Times(1) - writer, err = f.CreateSpanWriter() + writer, err := f.CreateSpanWriter() require.NoError(t, err) assert.NotNil(t, writer) } @@ -213,18 +198,10 @@ func TestGRPCStorageFactory_CapabilitiesDisabled(t *testing.T) { capabilities := f.services.Capabilities.(*mocks.PluginCapabilities) capabilities.On("Capabilities"). Return(&shared.Capabilities{ - ArchiveSpanReader: false, - ArchiveSpanWriter: false, StreamingSpanWriter: false, - }, nil).Times(3) - - reader, err := f.CreateArchiveSpanReader() - require.EqualError(t, err, storage.ErrArchiveStorageNotSupported.Error()) - assert.Nil(t, reader) - writer, err := f.CreateArchiveSpanWriter() - require.EqualError(t, err, storage.ErrArchiveStorageNotSupported.Error()) - assert.Nil(t, writer) - writer, err = f.CreateSpanWriter() + }, nil).Times(1) + + writer, err := f.CreateSpanWriter() require.NoError(t, err) assert.NotNil(t, writer, "regular span writer is available") } @@ -236,13 +213,7 @@ func TestGRPCStorageFactory_CapabilitiesError(t *testing.T) { customError := errors.New("made-up error") capabilities.On("Capabilities").Return(nil, customError) - reader, err := f.CreateArchiveSpanReader() - require.EqualError(t, err, customError.Error()) - assert.Nil(t, reader) - writer, err := f.CreateArchiveSpanWriter() - require.EqualError(t, err, customError.Error()) - assert.Nil(t, writer) - writer, err = f.CreateSpanWriter() + writer, err := f.CreateSpanWriter() require.NoError(t, err) assert.NotNil(t, writer, "regular span writer is available") } @@ -251,13 +222,7 @@ func TestGRPCStorageFactory_CapabilitiesNil(t *testing.T) { f := makeFactory(t) f.services.Capabilities = nil - reader, err := f.CreateArchiveSpanReader() - assert.Equal(t, err, storage.ErrArchiveStorageNotSupported) - assert.Nil(t, reader) - writer, err := f.CreateArchiveSpanWriter() - assert.Equal(t, err, storage.ErrArchiveStorageNotSupported) - assert.Nil(t, writer) - writer, err = f.CreateSpanWriter() + writer, err := f.CreateSpanWriter() require.NoError(t, err) assert.NotNil(t, writer, "regular span writer is available") } From 3a271cb3c71e38ded5ffe1fd10a8e9dfd2aa1b63 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 22:59:23 -0500 Subject: [PATCH 29/74] Remove Archive Mocks Signed-off-by: Mahad Zaryab --- storage/mocks/ArchiveFactory.go | 92 --------------------------------- 1 file changed, 92 deletions(-) delete mode 100644 storage/mocks/ArchiveFactory.go diff --git a/storage/mocks/ArchiveFactory.go b/storage/mocks/ArchiveFactory.go deleted file mode 100644 index 294b46dec58..00000000000 --- a/storage/mocks/ArchiveFactory.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 -// -// Run 'make generate-mocks' to regenerate. - -// Code generated by mockery. DO NOT EDIT. - -package mocks - -import ( - spanstore "github.com/jaegertracing/jaeger/storage/spanstore" - mock "github.com/stretchr/testify/mock" -) - -// ArchiveFactory is an autogenerated mock type for the ArchiveFactory type -type ArchiveFactory struct { - mock.Mock -} - -// CreateArchiveSpanReader provides a mock function with no fields -func (_m *ArchiveFactory) CreateArchiveSpanReader() (spanstore.Reader, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for CreateArchiveSpanReader") - } - - var r0 spanstore.Reader - var r1 error - if rf, ok := ret.Get(0).(func() (spanstore.Reader, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() spanstore.Reader); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(spanstore.Reader) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CreateArchiveSpanWriter provides a mock function with no fields -func (_m *ArchiveFactory) CreateArchiveSpanWriter() (spanstore.Writer, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for CreateArchiveSpanWriter") - } - - var r0 spanstore.Writer - var r1 error - if rf, ok := ret.Get(0).(func() (spanstore.Writer, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() spanstore.Writer); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(spanstore.Writer) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewArchiveFactory creates a new instance of ArchiveFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewArchiveFactory(t interface { - mock.TestingT - Cleanup(func()) -}) *ArchiveFactory { - mock := &ArchiveFactory{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} From 2120635568fdf4aebcbbe608ed84c6075699d5ff Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 18 Jan 2025 23:02:03 -0500 Subject: [PATCH 30/74] Run Formatter Signed-off-by: Mahad Zaryab --- cmd/jaeger/internal/extension/jaegerstorage/config_test.go | 2 +- cmd/query/app/querysvc/query_service_test.go | 4 +--- cmd/query/app/token_propagation_test.go | 2 +- plugin/storage/blackhole/factory.go | 5 ++--- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cmd/jaeger/internal/extension/jaegerstorage/config_test.go b/cmd/jaeger/internal/extension/jaegerstorage/config_test.go index 9f531caf255..c8e02148a7a 100644 --- a/cmd/jaeger/internal/extension/jaegerstorage/config_test.go +++ b/cmd/jaeger/internal/extension/jaegerstorage/config_test.go @@ -83,7 +83,7 @@ backends: `) cfg := createDefaultConfig().(*Config) require.NoError(t, conf.Unmarshal(cfg)) - assert.NotEmpty(t, cfg.TraceBackends["some_storage"].Cassandra.Primary.Connection.Servers) + assert.NotEmpty(t, cfg.TraceBackends["some_storage"].Cassandra.Configuration.Connection.Servers) } func TestConfigDefaultElasticsearch(t *testing.T) { diff --git a/cmd/query/app/querysvc/query_service_test.go b/cmd/query/app/querysvc/query_service_test.go index bd9b3187191..5114dcc32af 100644 --- a/cmd/query/app/querysvc/query_service_test.go +++ b/cmd/query/app/querysvc/query_service_test.go @@ -458,9 +458,7 @@ func (*fakeStorageFactory1) CreateSpanReader() (spanstore.Reader, error) func (*fakeStorageFactory1) CreateSpanWriter() (spanstore.Writer, error) { return nil, nil } func (*fakeStorageFactory1) CreateDependencyReader() (dependencystore.Reader, error) { return nil, nil } -var ( - _ storage.Factory = new(fakeStorageFactory1) -) +var _ storage.Factory = new(fakeStorageFactory1) func TestMain(m *testing.M) { testutils.VerifyGoLeaks(m) diff --git a/cmd/query/app/token_propagation_test.go b/cmd/query/app/token_propagation_test.go index 6c7177cb535..2af20349b2c 100644 --- a/cmd/query/app/token_propagation_test.go +++ b/cmd/query/app/token_propagation_test.go @@ -81,7 +81,7 @@ func runQueryService(t *testing.T, esURL string) *Server { })) f.InitFromViper(v, flagsSvc.Logger) // set AllowTokenFromContext manually because we don't register the respective CLI flag from query svc - f.Options.Primary.Authentication.BearerTokenAuthentication.AllowFromContext = true + f.Options.Config.Authentication.BearerTokenAuthentication.AllowFromContext = true require.NoError(t, f.Initialize(telset.Metrics, telset.Logger)) defer f.Close() diff --git a/plugin/storage/blackhole/factory.go b/plugin/storage/blackhole/factory.go index 521b20e41cf..7cbdd4ae2eb 100644 --- a/plugin/storage/blackhole/factory.go +++ b/plugin/storage/blackhole/factory.go @@ -13,9 +13,8 @@ import ( "github.com/jaegertracing/jaeger/storage/spanstore" ) -var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) -) +// interface comformance checks +var _ storage.Factory = (*Factory)(nil) // Factory implements storage.Factory and creates blackhole storage components. type Factory struct { From 23cca331b6ffacc9b037bf81389033b02b4b7692 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 10:13:35 -0500 Subject: [PATCH 31/74] Add Unit Test For InitArchiveStorage Signed-off-by: Mahad Zaryab --- plugin/storage/factory_test.go | 82 ++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/plugin/storage/factory_test.go b/plugin/storage/factory_test.go index 0271193add9..c0fa148ad48 100644 --- a/plugin/storage/factory_test.go +++ b/plugin/storage/factory_test.go @@ -20,6 +20,7 @@ import ( "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/metrics" + "github.com/jaegertracing/jaeger/pkg/testutils" "github.com/jaegertracing/jaeger/storage" "github.com/jaegertracing/jaeger/storage/dependencystore" depStoreMocks "github.com/jaegertracing/jaeger/storage/dependencystore/mocks" @@ -207,24 +208,6 @@ func TestCreateMulti(t *testing.T) { assert.Equal(t, spanstore.NewCompositeWriter(spanWriter, spanWriter2), w) } -func TestCreateArchive(t *testing.T) { - f, err := NewFactory(defaultCfg()) - require.NoError(t, err) - assert.NotEmpty(t, f.factories[cassandraStorageType]) - - mock := &struct { - mocks.Factory - mocks.ArchiveFactory - }{} - f.factories[cassandraStorageType] = mock - - archiveSpanReader := new(spanStoreMocks.Reader) - archiveSpanWriter := new(spanStoreMocks.Writer) - - mock.ArchiveFactory.On("CreateArchiveSpanReader").Return(archiveSpanReader, errors.New("archive-span-reader-error")) - mock.ArchiveFactory.On("CreateArchiveSpanWriter").Return(archiveSpanWriter, errors.New("archive-span-writer-error")) -} - func TestCreateError(t *testing.T) { f, err := NewFactory(defaultCfg()) require.NoError(t, err) @@ -375,6 +358,69 @@ func TestPublishOpts(t *testing.T) { assert.EqualValues(t, 1, expvar.Get(spanStorageType+"-"+f.SpanReaderType).(*expvar.Int).Value()) } +func TestInitArchiveStorage(t *testing.T) { + tests := []struct { + name string + setupMock func(*mocks.Factory) + expectedReader spanstore.Reader + expectedWriter spanstore.Writer + expectedLog string + }{ + { + name: "successful initialization", + setupMock: func(mock *mocks.Factory) { + spanReader := &spanStoreMocks.Reader{} + spanWriter := &spanStoreMocks.Writer{} + mock.On("CreateSpanReader").Return(spanReader, nil) + mock.On("CreateSpanWriter").Return(spanWriter, nil) + }, + expectedReader: &spanStoreMocks.Reader{}, + expectedWriter: &spanStoreMocks.Writer{}, + }, + { + name: "error initializing reader", + setupMock: func(mock *mocks.Factory) { + mock.On("CreateSpanReader").Return(nil, assert.AnError) + }, + expectedReader: nil, + expectedWriter: nil, + expectedLog: "Cannot init archive storage reader", + }, + { + name: "error initializing writer", + setupMock: func(mock *mocks.Factory) { + spanReader := new(spanStoreMocks.Reader) + mock.On("CreateSpanReader").Return(spanReader, nil) + mock.On("CreateSpanWriter").Return(nil, assert.AnError) + }, + expectedReader: nil, + expectedWriter: nil, + expectedLog: "Cannot init archive storage writer", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + logger, buf := testutils.NewLogger() + + f, err := NewFactory(defaultCfg()) + require.NoError(t, err) + assert.NotEmpty(t, f.factories) + assert.NotEmpty(t, f.factories[cassandraStorageType]) + + mock := new(mocks.Factory) + f.archiveFactories[cassandraStorageType] = mock + test.setupMock(mock) + + reader, writer := f.InitArchiveStorage(logger) + assert.Equal(t, test.expectedReader, reader) + assert.Equal(t, test.expectedWriter, writer) + + require.Contains(t, buf.String(), test.expectedLog) + }) + } +} + type errorFactory struct { closeErr error } From 82e568c08f5bb36546b0283907fadea82318206a Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 10:24:21 -0500 Subject: [PATCH 32/74] Fix Query App Flags Test Signed-off-by: Mahad Zaryab --- cmd/query/app/flags_test.go | 62 ++++++++++++++----------------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/cmd/query/app/flags_test.go b/cmd/query/app/flags_test.go index b56a17fc97a..4cd4b1a9b17 100644 --- a/cmd/query/app/flags_test.go +++ b/cmd/query/app/flags_test.go @@ -16,11 +16,20 @@ import ( "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/testutils" + "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" - "github.com/jaegertracing/jaeger/storage/mocks" - spanstore_mocks "github.com/jaegertracing/jaeger/storage/spanstore/mocks" ) +func defaultFactoryCfg() storage.FactoryConfig { + return storage.FactoryConfig{ + SpanWriterTypes: []string{"memory"}, + SpanReaderType: "memory", + DependenciesStorageType: "memory", + DownsamplingRatio: 1.0, + DownsamplingHashSalt: "", + } +} + func TestQueryBuilderFlags(t *testing.T) { v, command := config.Viperize(AddFlags) command.ParseFlags([]string{ @@ -92,28 +101,14 @@ func TestBuildQueryServiceOptions(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) - qSvcOpts := qOpts.BuildQueryServiceOptions(&mocks.Factory{}, zap.NewNop()) + f, err := storage.NewFactory(defaultFactoryCfg()) + require.NoError(t, err) + + qSvcOpts := qOpts.BuildQueryServiceOptions(f, zap.NewNop()) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) assert.Nil(t, qSvcOpts.ArchiveSpanReader) assert.Nil(t, qSvcOpts.ArchiveSpanWriter) - - comboFactory := struct { - *mocks.Factory - *mocks.ArchiveFactory - }{ - &mocks.Factory{}, - &mocks.ArchiveFactory{}, - } - - comboFactory.ArchiveFactory.On("CreateArchiveSpanReader").Return(&spanstore_mocks.Reader{}, nil) - comboFactory.ArchiveFactory.On("CreateArchiveSpanWriter").Return(&spanstore_mocks.Writer{}, nil) - - qSvcOpts = qOpts.BuildQueryServiceOptions(comboFactory, zap.NewNop()) - assert.NotNil(t, qSvcOpts) - assert.NotNil(t, qSvcOpts.Adjuster) - assert.NotNil(t, qSvcOpts.ArchiveSpanReader) - assert.NotNil(t, qSvcOpts.ArchiveSpanWriter) } func TestBuildQueryServiceOptionsV2(t *testing.T) { @@ -122,28 +117,14 @@ func TestBuildQueryServiceOptionsV2(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(&mocks.Factory{}, zap.NewNop()) + f, err := storage.NewFactory(defaultFactoryCfg()) + require.NoError(t, err) + + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(f, zap.NewNop()) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) assert.Nil(t, qSvcOpts.ArchiveTraceReader) assert.Nil(t, qSvcOpts.ArchiveTraceWriter) - - comboFactory := struct { - *mocks.Factory - *mocks.ArchiveFactory - }{ - &mocks.Factory{}, - &mocks.ArchiveFactory{}, - } - - comboFactory.ArchiveFactory.On("CreateArchiveSpanReader").Return(&spanstore_mocks.Reader{}, nil) - comboFactory.ArchiveFactory.On("CreateArchiveSpanWriter").Return(&spanstore_mocks.Writer{}, nil) - - qSvcOpts = qOpts.BuildQueryServiceOptionsV2(comboFactory, zap.NewNop()) - assert.NotNil(t, qSvcOpts) - assert.NotNil(t, qSvcOpts.Adjuster) - assert.NotNil(t, qSvcOpts.ArchiveTraceReader) - assert.NotNil(t, qSvcOpts.ArchiveTraceWriter) } func TestBuildQueryServiceOptionsV2_NoArchiveStorage(t *testing.T) { @@ -152,8 +133,11 @@ func TestBuildQueryServiceOptionsV2_NoArchiveStorage(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) + f, err := storage.NewFactory(defaultFactoryCfg()) + require.NoError(t, err) + logger, logBuf := testutils.NewLogger() - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(&mocks.Factory{}, logger) + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(f, logger) assert.Nil(t, qSvcOpts.ArchiveTraceReader) assert.Nil(t, qSvcOpts.ArchiveTraceWriter) From 382b3afeb3e1f43050c729f147f2a0782e9f4cba Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 12:20:34 -0500 Subject: [PATCH 33/74] Fix Server Tests With Some Commented Out Signed-off-by: Mahad Zaryab --- cmd/remote-storage/app/server_test.go | 303 +++++++++++++------------- 1 file changed, 152 insertions(+), 151 deletions(-) diff --git a/cmd/remote-storage/app/server_test.go b/cmd/remote-storage/app/server_test.go index e9c245c4cc4..04bf3c42501 100644 --- a/cmd/remote-storage/app/server_test.go +++ b/cmd/remote-storage/app/server_test.go @@ -4,13 +4,9 @@ package app import ( - "context" - "errors" "testing" - "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/config/configgrpc" "go.opentelemetry.io/collector/config/confignet" @@ -26,51 +22,77 @@ import ( "github.com/jaegertracing/jaeger/pkg/healthcheck" "github.com/jaegertracing/jaeger/pkg/telemetry" "github.com/jaegertracing/jaeger/pkg/tenancy" + "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" "github.com/jaegertracing/jaeger/proto-gen/storage_v1" - depStoreMocks "github.com/jaegertracing/jaeger/storage/dependencystore/mocks" - factoryMocks "github.com/jaegertracing/jaeger/storage/mocks" - spanStoreMocks "github.com/jaegertracing/jaeger/storage/spanstore/mocks" ) var testCertKeyLocation = "../../../pkg/config/tlscfg/testdata" +func defaultFactoryCfg() storage.FactoryConfig { + return storage.FactoryConfig{ + SpanWriterTypes: []string{"blackhole"}, + SpanReaderType: "blackhole", + DependenciesStorageType: "blackhole", + DownsamplingRatio: 1.0, + DownsamplingHashSalt: "", + } +} + func TestNewServer_CreateStorageErrors(t *testing.T) { - factory := new(factoryMocks.Factory) - factory.On("CreateSpanReader").Return(nil, errors.New("no reader")).Once() - factory.On("CreateSpanReader").Return(nil, nil) - factory.On("CreateSpanWriter").Return(nil, errors.New("no writer")).Once() - factory.On("CreateSpanWriter").Return(nil, nil) - factory.On("CreateDependencyReader").Return(nil, errors.New("no deps")).Once() - factory.On("CreateDependencyReader").Return(nil, nil) - f := func() (*Server, error) { - return NewServer( - &Options{ - ServerConfig: configgrpc.ServerConfig{ - NetAddr: confignet.AddrConfig{ - Endpoint: ":0", - }, - }, + tests := []struct { + name string + modifyFactory func(factory *storage.FactoryConfig) + expectedError string + }{ + { + name: "no span reader", + modifyFactory: func(factory *storage.FactoryConfig) { + factory.SpanReaderType = "a" }, - factory, - tenancy.NewManager(&tenancy.Options{}), - telemetry.NoopSettings(), - ) + expectedError: "no a backend registered", + }, + { + name: "no span writer", + modifyFactory: func(factory *storage.FactoryConfig) { + factory.SpanWriterTypes = []string{"b"} + }, + expectedError: "no b backend registered", + }, + { + name: "no dependency reader", + modifyFactory: func(factory *storage.FactoryConfig) { + factory.DependenciesStorageType = "c" + }, + expectedError: "no c backend registered", + }, } - _, err := f() - require.ErrorContains(t, err, "no reader") - _, err = f() - require.ErrorContains(t, err, "no writer") + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + factoryCfg := defaultFactoryCfg() - _, err = f() - require.ErrorContains(t, err, "no deps") + factory, err := storage.NewFactory(factoryCfg) + require.NoError(t, err) - s, err := f() - require.NoError(t, err) - require.NoError(t, s.Start()) - validateGRPCServer(t, s.grpcConn.Addr().String()) - require.NoError(t, s.grpcConn.Close()) + test.modifyFactory(&factory.FactoryConfig) + + _, err = NewServer( + &Options{ + ServerConfig: configgrpc.ServerConfig{ + NetAddr: confignet.AddrConfig{ + Endpoint: ":0", + }, + }, + }, + factory, + tenancy.NewManager(&tenancy.Options{}), + telemetry.NoopSettings(), + ) + + require.ErrorContains(t, err, test.expectedError) + }) + } } func TestServerStart_BadPortErrors(t *testing.T) { @@ -86,31 +108,6 @@ func TestServerStart_BadPortErrors(t *testing.T) { require.Error(t, srv.Start()) } -type storageMocks struct { - factory *factoryMocks.Factory - reader *spanStoreMocks.Reader - writer *spanStoreMocks.Writer - depReader *depStoreMocks.Reader -} - -func newStorageMocks() *storageMocks { - reader := new(spanStoreMocks.Reader) - writer := new(spanStoreMocks.Writer) - depReader := new(depStoreMocks.Reader) - - factory := new(factoryMocks.Factory) - factory.On("CreateSpanReader").Return(reader, nil) - factory.On("CreateSpanWriter").Return(writer, nil) - factory.On("CreateDependencyReader").Return(depReader, nil) - - return &storageMocks{ - factory: factory, - reader: reader, - writer: writer, - depReader: depReader, - } -} - func TestNewServer_TLSConfigError(t *testing.T) { tlsCfg := &configtls.ServerConfig{ ClientCAFile: "invalid/path", @@ -123,8 +120,11 @@ func TestNewServer_TLSConfigError(t *testing.T) { Logger: zap.NewNop(), ReportStatus: telemetry.HCAdapter(healthcheck.New()), } - storageMocks := newStorageMocks() - _, err := NewServer( + + f, err := storage.NewFactory(defaultFactoryCfg()) + require.NoError(t, err) + + _, err = NewServer( &Options{ ServerConfig: configgrpc.ServerConfig{ NetAddr: confignet.AddrConfig{ @@ -133,40 +133,40 @@ func TestNewServer_TLSConfigError(t *testing.T) { TLSSetting: tlsCfg, }, }, - storageMocks.factory, + f, tenancy.NewManager(&tenancy.Options{}), telset, ) assert.ErrorContains(t, err, "failed to load TLS config") } -func TestCreateGRPCHandler(t *testing.T) { - storageMocks := newStorageMocks() - h, err := createGRPCHandler(storageMocks.factory, zap.NewNop()) - require.NoError(t, err) +// func TestCreateGRPCHandler(t *testing.T) { +// storageMocks := newStorageMocks() +// h, err := createGRPCHandler(storageMocks.factory, zap.NewNop()) +// require.NoError(t, err) - storageMocks.writer.On("WriteSpan", mock.Anything, mock.Anything).Return(errors.New("writer error")) - _, err = h.WriteSpan(context.Background(), &storage_v1.WriteSpanRequest{}) - require.ErrorContains(t, err, "writer error") +// storageMocks.writer.On("WriteSpan", mock.Anything, mock.Anything).Return(errors.New("writer error")) +// _, err = h.WriteSpan(context.Background(), &storage_v1.WriteSpanRequest{}) +// require.ErrorContains(t, err, "writer error") - storageMocks.depReader.On( - "GetDependencies", - mock.Anything, // context - mock.Anything, // time - mock.Anything, // lookback - ).Return(nil, errors.New("deps error")) - _, err = h.GetDependencies(context.Background(), &storage_v1.GetDependenciesRequest{}) - require.ErrorContains(t, err, "deps error") +// storageMocks.depReader.On( +// "GetDependencies", +// mock.Anything, // context +// mock.Anything, // time +// mock.Anything, // lookback +// ).Return(nil, errors.New("deps error")) +// _, err = h.GetDependencies(context.Background(), &storage_v1.GetDependenciesRequest{}) +// require.ErrorContains(t, err, "deps error") - err = h.GetArchiveTrace(nil, nil) - require.ErrorContains(t, err, "not implemented") +// err = h.GetArchiveTrace(nil, nil) +// require.ErrorContains(t, err, "not implemented") - _, err = h.WriteArchiveSpan(context.Background(), nil) - require.ErrorContains(t, err, "not implemented") +// _, err = h.WriteArchiveSpan(context.Background(), nil) +// require.ErrorContains(t, err, "not implemented") - err = h.WriteSpanStream(nil) - assert.ErrorContains(t, err, "not implemented") -} +// err = h.WriteSpanStream(nil) +// assert.ErrorContains(t, err, "not implemented") +// } var testCases = []struct { name string @@ -324,74 +324,75 @@ func newGRPCClient(t *testing.T, addr string, creds credentials.TransportCredent } } -func TestServerGRPCTLS(t *testing.T) { - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - serverOptions := &Options{ - ServerConfig: configgrpc.ServerConfig{ - NetAddr: confignet.AddrConfig{ - Endpoint: ":0", - }, - TLSSetting: test.TLS, - }, - } - flagsSvc := flags.NewService(ports.QueryAdminHTTP) - flagsSvc.Logger = zap.NewNop() - - storageMocks := newStorageMocks() - expectedServices := []string{"test"} - storageMocks.reader.On("GetServices", mock.AnythingOfType("*context.valueCtx")).Return(expectedServices, nil) - - tm := tenancy.NewManager(&tenancy.Options{Enabled: true}) - telset := telemetry.Settings{ - Logger: flagsSvc.Logger, - ReportStatus: telemetry.HCAdapter(flagsSvc.HC()), - } - server, err := NewServer( - serverOptions, - storageMocks.factory, - tm, - telset, - ) - require.NoError(t, err) - require.NoError(t, server.Start()) - - var clientError error - var client *grpcClient - - if serverOptions.TLSSetting != nil { - clientTLSCfg, err0 := test.clientTLS.LoadTLSConfig(context.Background()) - require.NoError(t, err0) - creds := credentials.NewTLS(clientTLSCfg) - client = newGRPCClient(t, server.grpcConn.Addr().String(), creds, tm) - } else { - client = newGRPCClient(t, server.grpcConn.Addr().String(), nil, tm) - } - - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - - ctx = tenancy.WithTenant(ctx, "foo") - res, clientError := client.GetServices(ctx, &storage_v1.GetServicesRequest{}) - - if test.expectClientError { - require.Error(t, clientError) - } else { - require.NoError(t, clientError) - assert.Equal(t, expectedServices, res.Services) - } - require.NoError(t, client.conn.Close()) - server.Close() - assert.Equal(t, healthcheck.Unavailable, flagsSvc.HC().Get()) - }) - } -} +// func TestServerGRPCTLS(t *testing.T) { +// for _, test := range testCases { +// t.Run(test.name, func(t *testing.T) { +// serverOptions := &Options{ +// ServerConfig: configgrpc.ServerConfig{ +// NetAddr: confignet.AddrConfig{ +// Endpoint: ":0", +// }, +// TLSSetting: test.TLS, +// }, +// } +// flagsSvc := flags.NewService(ports.QueryAdminHTTP) +// flagsSvc.Logger = zap.NewNop() + +// storageMocks := newStorageMocks() +// expectedServices := []string{"test"} +// storageMocks.reader.On("GetServices", mock.AnythingOfType("*context.valueCtx")).Return(expectedServices, nil) + +// tm := tenancy.NewManager(&tenancy.Options{Enabled: true}) +// telset := telemetry.Settings{ +// Logger: flagsSvc.Logger, +// ReportStatus: telemetry.HCAdapter(flagsSvc.HC()), +// } +// server, err := NewServer( +// serverOptions, +// storageMocks.factory, +// tm, +// telset, +// ) +// require.NoError(t, err) +// require.NoError(t, server.Start()) + +// var clientError error +// var client *grpcClient + +// if serverOptions.TLSSetting != nil { +// clientTLSCfg, err0 := test.clientTLS.LoadTLSConfig(context.Background()) +// require.NoError(t, err0) +// creds := credentials.NewTLS(clientTLSCfg) +// client = newGRPCClient(t, server.grpcConn.Addr().String(), creds, tm) +// } else { +// client = newGRPCClient(t, server.grpcConn.Addr().String(), nil, tm) +// } + +// ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) +// defer cancel() + +// ctx = tenancy.WithTenant(ctx, "foo") +// res, clientError := client.GetServices(ctx, &storage_v1.GetServicesRequest{}) + +// if test.expectClientError { +// require.Error(t, clientError) +// } else { +// require.NoError(t, clientError) +// assert.Equal(t, expectedServices, res.Services) +// } +// require.NoError(t, client.conn.Close()) +// server.Close() +// assert.Equal(t, healthcheck.Unavailable, flagsSvc.HC().Get()) +// }) +// } +// } func TestServerHandlesPortZero(t *testing.T) { flagsSvc := flags.NewService(ports.QueryAdminHTTP) zapCore, logs := observer.New(zap.InfoLevel) flagsSvc.Logger = zap.New(zapCore) - storageMocks := newStorageMocks() + f, err := storage.NewFactory(defaultFactoryCfg()) + require.NoError(t, err) telset := telemetry.Settings{ Logger: flagsSvc.Logger, ReportStatus: telemetry.HCAdapter(flagsSvc.HC()), @@ -400,7 +401,7 @@ func TestServerHandlesPortZero(t *testing.T) { &Options{ServerConfig: configgrpc.ServerConfig{ NetAddr: confignet.AddrConfig{Endpoint: ":0"}, }}, - storageMocks.factory, + f, tenancy.NewManager(&tenancy.Options{}), telset, ) From 677405d3db496e4aa6a28914bd2e1f7125c7ac08 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 12:47:43 -0500 Subject: [PATCH 34/74] Fix ES Unit Tests Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory_test.go | 12 ++---------- plugin/storage/es/options_test.go | 5 ----- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/plugin/storage/es/factory_test.go b/plugin/storage/es/factory_test.go index 8ce8bdc3313..392491823e3 100644 --- a/plugin/storage/es/factory_test.go +++ b/plugin/storage/es/factory_test.go @@ -67,15 +67,7 @@ func TestElasticsearchFactory(t *testing.T) { f.InitFromViper(v, zap.NewNop()) f.newClientFn = (&mockClientBuilder{err: errors.New("made-up error")}).NewClient - require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "failed to create primary Elasticsearch client: made-up error") - - f.newClientFn = func(c *escfg.Configuration, logger *zap.Logger, metricsFactory metrics.Factory) (es.Client, error) { - // to test archive storage error, pretend that primary client creation is successful - // but override newClientFn so it fails for the next invocation - f.newClientFn = (&mockClientBuilder{err: errors.New("made-up error2")}).NewClient - return (&mockClientBuilder{}).NewClient(c, logger, metricsFactory) - } - require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "failed to create archive Elasticsearch client: made-up error2") + require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "failed to create Elasticsearch client: made-up error") f.newClientFn = (&mockClientBuilder{}).NewClient require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) @@ -276,7 +268,7 @@ func TestESStorageFactoryWithConfigError(t *testing.T) { LogLevel: "error", } _, err := NewFactoryWithConfig(cfg, metrics.NullFactory, zap.NewNop()) - require.ErrorContains(t, err, "failed to create primary Elasticsearch client") + require.ErrorContains(t, err, "failed to create Elasticsearch client") } func TestPasswordFromFile(t *testing.T) { diff --git a/plugin/storage/es/options_test.go b/plugin/storage/es/options_test.go index f013319cf08..cb3b05af479 100644 --- a/plugin/storage/es/options_test.go +++ b/plugin/storage/es/options_test.go @@ -55,11 +55,6 @@ func TestOptionsWithFlags(t *testing.T) { "--es.index-rollover-frequency-services=day", // a couple overrides "--es.remote-read-clusters=cluster_one,cluster_two", - "--es.aux.server-urls=3.3.3.3, 4.4.4.4", - "--es.aux.max-span-age=24h", - "--es.aux.num-replicas=10", - "--es.aux.index-date-separator=.", - "--es.aux.index-rollover-frequency-spans=hour", "--es.tls.enabled=true", "--es.tls.skip-host-verify=true", "--es.tags-as-fields.all=true", From ae8d2fd965f1b72ab0c98ac784182c69548be5ef Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 13:01:33 -0500 Subject: [PATCH 35/74] Fix GRPC Handler Tests Signed-off-by: Mahad Zaryab --- plugin/storage/grpc/shared/grpc_handler.go | 5 ++ .../storage/grpc/shared/grpc_handler_test.go | 48 +++++++------------ 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/plugin/storage/grpc/shared/grpc_handler.go b/plugin/storage/grpc/shared/grpc_handler.go index 197a4cd0d0e..0d8beadbcad 100644 --- a/plugin/storage/grpc/shared/grpc_handler.go +++ b/plugin/storage/grpc/shared/grpc_handler.go @@ -52,6 +52,7 @@ func NewGRPCHandler(impl *GRPCHandlerStorageImpl) *GRPCHandler { // NewGRPCHandler creates a handler given implementations grouped by plugin services. func NewGRPCHandlerWithPlugins( mainImpl StoragePlugin, + archiveImpl StoragePlugin, streamImpl StreamingSpanWriterPlugin, ) *GRPCHandler { impl := &GRPCHandlerStorageImpl{ @@ -63,6 +64,10 @@ func NewGRPCHandlerWithPlugins( ArchiveSpanWriter: func() spanstore.Writer { return nil }, StreamingSpanWriter: func() spanstore.Writer { return nil }, } + if archiveImpl != nil { + impl.ArchiveSpanReader = archiveImpl.SpanReader + impl.ArchiveSpanWriter = archiveImpl.SpanWriter + } if streamImpl != nil { impl.StreamingSpanWriter = streamImpl.StreamingSpanWriter } diff --git a/plugin/storage/grpc/shared/grpc_handler_test.go b/plugin/storage/grpc/shared/grpc_handler_test.go index 5bce060ad3f..08b5aaad25e 100644 --- a/plugin/storage/grpc/shared/grpc_handler_test.go +++ b/plugin/storage/grpc/shared/grpc_handler_test.go @@ -26,20 +26,10 @@ import ( ) type mockStoragePlugin struct { - spanReader *spanStoreMocks.Reader - spanWriter *spanStoreMocks.Writer - archiveReader *spanStoreMocks.Reader - archiveWriter *spanStoreMocks.Writer - depsReader *dependencyStoreMocks.Reader - streamWriter *spanStoreMocks.Writer -} - -func (plugin *mockStoragePlugin) ArchiveSpanReader() spanstore.Reader { - return plugin.archiveReader -} - -func (plugin *mockStoragePlugin) ArchiveSpanWriter() spanstore.Writer { - return plugin.archiveWriter + spanReader *spanStoreMocks.Reader + spanWriter *spanStoreMocks.Writer + depsReader *dependencyStoreMocks.Reader + streamWriter *spanStoreMocks.Writer } func (plugin *mockStoragePlugin) SpanReader() spanstore.Reader { @@ -66,21 +56,17 @@ type grpcServerTest struct { func withGRPCServer(fn func(r *grpcServerTest)) { spanReader := new(spanStoreMocks.Reader) spanWriter := new(spanStoreMocks.Writer) - archiveReader := new(spanStoreMocks.Reader) - archiveWriter := new(spanStoreMocks.Writer) depReader := new(dependencyStoreMocks.Reader) streamWriter := new(spanStoreMocks.Writer) impl := &mockStoragePlugin{ - spanReader: spanReader, - spanWriter: spanWriter, - archiveReader: archiveReader, - archiveWriter: archiveWriter, - depsReader: depReader, - streamWriter: streamWriter, + spanReader: spanReader, + spanWriter: spanWriter, + depsReader: depReader, + streamWriter: streamWriter, } - handler := NewGRPCHandlerWithPlugins(impl, impl) + handler := NewGRPCHandlerWithPlugins(impl, impl, impl) defer handler.Close(context.Background(), &storage_v1.CloseWriterRequest{}) r := &grpcServerTest{ server: handler, @@ -284,7 +270,7 @@ func TestGRPCServerGetArchiveTrace(t *testing.T) { for i := range mockTraceSpans { traceSpans = append(traceSpans, &mockTraceSpans[i]) } - r.impl.archiveReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). + r.impl.spanReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). Return(&model.Trace{Spans: traceSpans}, nil) err := r.server.GetArchiveTrace(&storage_v1.GetTraceRequest{ @@ -299,7 +285,7 @@ func TestGRPCServerGetArchiveTrace_NotFound(t *testing.T) { traceSteam := new(grpcMocks.SpanReaderPlugin_GetTraceServer) traceSteam.On("Context").Return(context.Background()) - r.impl.archiveReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). + r.impl.spanReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). Return(nil, spanstore.ErrTraceNotFound) err := r.server.GetArchiveTrace(&storage_v1.GetTraceRequest{ @@ -314,7 +300,7 @@ func TestGRPCServerGetArchiveTrace_Error(t *testing.T) { traceSteam := new(grpcMocks.SpanReaderPlugin_GetTraceServer) traceSteam.On("Context").Return(context.Background()) - r.impl.archiveReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). + r.impl.spanReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). Return(nil, errors.New("some error")) err := r.server.GetArchiveTrace(&storage_v1.GetTraceRequest{ @@ -329,7 +315,7 @@ func TestGRPCServerGetArchiveTrace_NoImpl(t *testing.T) { r.server.impl.ArchiveSpanReader = func() spanstore.Reader { return nil } traceSteam := new(grpcMocks.SpanReaderPlugin_GetTraceServer) - r.impl.archiveReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). + r.impl.spanReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). Return(nil, errors.New("some error")) err := r.server.GetArchiveTrace(&storage_v1.GetTraceRequest{ @@ -350,7 +336,7 @@ func TestGRPCServerGetArchiveTrace_StreamError(t *testing.T) { for i := range mockTraceSpans { traceSpans = append(traceSpans, &mockTraceSpans[i]) } - r.impl.archiveReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). + r.impl.spanReader.On("GetTrace", mock.Anything, spanstore.GetTraceParameters{TraceID: mockTraceID}). Return(&model.Trace{Spans: traceSpans}, nil) err := r.server.GetArchiveTrace(&storage_v1.GetTraceRequest{ @@ -373,7 +359,7 @@ func TestGRPCServerWriteArchiveSpan_NoImpl(t *testing.T) { func TestGRPCServerWriteArchiveSpan(t *testing.T) { withGRPCServer(func(r *grpcServerTest) { - r.impl.archiveWriter.On("WriteSpan", mock.Anything, &mockTraceSpans[0]). + r.impl.spanWriter.On("WriteSpan", mock.Anything, &mockTraceSpans[0]). Return(nil) s, err := r.server.WriteArchiveSpan(context.Background(), &storage_v1.WriteSpanRequest{ @@ -386,7 +372,7 @@ func TestGRPCServerWriteArchiveSpan(t *testing.T) { func TestGRPCServerWriteArchiveSpan_Error(t *testing.T) { withGRPCServer(func(r *grpcServerTest) { - r.impl.archiveWriter.On("WriteSpan", mock.Anything, &mockTraceSpans[0]). + r.impl.spanWriter.On("WriteSpan", mock.Anything, &mockTraceSpans[0]). Return(errors.New("some error")) _, err := r.server.WriteArchiveSpan(context.Background(), &storage_v1.WriteSpanRequest{ @@ -445,7 +431,7 @@ func TestNewGRPCHandlerWithPlugins_Nils(t *testing.T) { depsReader: depReader, } - handler := NewGRPCHandlerWithPlugins(impl, nil) + handler := NewGRPCHandlerWithPlugins(impl, nil, nil) assert.Nil(t, handler.impl.ArchiveSpanReader()) assert.Nil(t, handler.impl.ArchiveSpanWriter()) assert.Nil(t, handler.impl.StreamingSpanWriter()) From ac4ceab2968fc0dd8845e37c05387ab18caba878 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 13:13:30 -0500 Subject: [PATCH 36/74] Fix Cassandra Tests Signed-off-by: Mahad Zaryab --- plugin/storage/cassandra/factory_test.go | 5 ---- plugin/storage/factory.go | 37 ++++++++++++++++-------- plugin/storage/factory_test.go | 1 + 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/plugin/storage/cassandra/factory_test.go b/plugin/storage/cassandra/factory_test.go index a0864631f75..d0b3c425d83 100644 --- a/plugin/storage/cassandra/factory_test.go +++ b/plugin/storage/cassandra/factory_test.go @@ -62,10 +62,6 @@ func TestCassandraFactory(t *testing.T) { session.On("Query", mock.AnythingOfType("string"), mock.Anything).Return(query) session.On("Close").Return() query.On("Exec").Return(nil) - f.sessionBuilderFn = new(mockSessionBuilder). - add(session, nil). - add(nil, errors.New("made-up archive error")).build - require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "made-up archive error") f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).build require.NoError(t, f.Initialize(metrics.NullFactory, logger)) @@ -113,7 +109,6 @@ func TestExclusiveWhitelistBlacklist(t *testing.T) { f := NewFactory() v, command := viperize.Viperize(f.AddFlags) command.ParseFlags([]string{ - "--cassandra-archive.enabled=true", "--cassandra.index.tag-whitelist=a,b,c", "--cassandra.index.tag-blacklist=a,b,c", }) diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index 07c0eb7e93c..7c494ce5564 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -259,11 +259,15 @@ func (f *Factory) CreateDependencyReader() (dependencystore.Reader, error) { // AddFlags implements plugin.Configurable func (f *Factory) AddFlags(flagSet *flag.FlagSet) { - for _, factory := range f.factories { - if conf, ok := factory.(plugin.Configurable); ok { - conf.AddFlags(flagSet) + addFlags := func(factories map[string]storage.Factory) { + for _, factory := range factories { + if conf, ok := factory.(plugin.Configurable); ok { + conf.AddFlags(flagSet) + } } } + addFlags(f.factories) + addFlags(f.archiveFactories) } // AddPipelineFlags adds all the standard flags as well as the downsampling @@ -291,11 +295,15 @@ func (f *Factory) addDownsamplingFlags(flagSet *flag.FlagSet) { // InitFromViper implements plugin.Configurable func (f *Factory) InitFromViper(v *viper.Viper, logger *zap.Logger) { - for _, factory := range f.factories { - if conf, ok := factory.(plugin.Configurable); ok { - conf.InitFromViper(v, logger) + initFromViper := func(factories map[string]storage.Factory) { + for _, factory := range factories { + if conf, ok := factory.(plugin.Configurable); ok { + conf.InitFromViper(v, logger) + } } } + initFromViper(f.factories) + initFromViper(f.archiveFactories) f.initDownsamplingFromViper(v) } @@ -354,14 +362,19 @@ var _ io.Closer = (*Factory)(nil) // Close closes the resources held by the factory func (f *Factory) Close() error { var errs []error + closeFactory := func(factory storage.Factory) { + if closer, ok := factory.(io.Closer); ok { + if err := closer.Close(); err != nil { + errs = append(errs, err) + } + } + } for _, storageType := range f.SpanWriterTypes { if factory, ok := f.factories[storageType]; ok { - if closer, ok := factory.(io.Closer); ok { - err := closer.Close() - if err != nil { - errs = append(errs, err) - } - } + closeFactory(factory) + } + if factory, ok := f.archiveFactories[storageType]; ok { + closeFactory(factory) } } return errors.Join(errs...) diff --git a/plugin/storage/factory_test.go b/plugin/storage/factory_test.go index c0fa148ad48..89f435f7698 100644 --- a/plugin/storage/factory_test.go +++ b/plugin/storage/factory_test.go @@ -91,6 +91,7 @@ func TestInitialize(t *testing.T) { mock := new(mocks.Factory) f.factories[cassandraStorageType] = mock + f.archiveFactories[cassandraStorageType] = mock m := metrics.NullFactory l := zap.NewNop() From 7654aa7cfe06800deacb3bc50fa54c26c63dc1cf Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 15:18:09 -0500 Subject: [PATCH 37/74] Change Default to blackhole Signed-off-by: Mahad Zaryab --- cmd/query/app/flags_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/query/app/flags_test.go b/cmd/query/app/flags_test.go index 4cd4b1a9b17..82fcb2310ac 100644 --- a/cmd/query/app/flags_test.go +++ b/cmd/query/app/flags_test.go @@ -22,9 +22,9 @@ import ( func defaultFactoryCfg() storage.FactoryConfig { return storage.FactoryConfig{ - SpanWriterTypes: []string{"memory"}, - SpanReaderType: "memory", - DependenciesStorageType: "memory", + SpanWriterTypes: []string{"blackhole"}, + SpanReaderType: "blackhole", + DependenciesStorageType: "blackhole", DownsamplingRatio: 1.0, DownsamplingHashSalt: "", } From 5f524103e9966e5504ac4c44d7186a49cd002518 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 15:58:05 -0500 Subject: [PATCH 38/74] Fix Test Signed-off-by: Mahad Zaryab --- cmd/remote-storage/app/server_test.go | 125 +++++++++++++------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/cmd/remote-storage/app/server_test.go b/cmd/remote-storage/app/server_test.go index 04bf3c42501..e8c3e626b8f 100644 --- a/cmd/remote-storage/app/server_test.go +++ b/cmd/remote-storage/app/server_test.go @@ -4,7 +4,9 @@ package app import ( + "context" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -324,68 +326,67 @@ func newGRPCClient(t *testing.T, addr string, creds credentials.TransportCredent } } -// func TestServerGRPCTLS(t *testing.T) { -// for _, test := range testCases { -// t.Run(test.name, func(t *testing.T) { -// serverOptions := &Options{ -// ServerConfig: configgrpc.ServerConfig{ -// NetAddr: confignet.AddrConfig{ -// Endpoint: ":0", -// }, -// TLSSetting: test.TLS, -// }, -// } -// flagsSvc := flags.NewService(ports.QueryAdminHTTP) -// flagsSvc.Logger = zap.NewNop() - -// storageMocks := newStorageMocks() -// expectedServices := []string{"test"} -// storageMocks.reader.On("GetServices", mock.AnythingOfType("*context.valueCtx")).Return(expectedServices, nil) - -// tm := tenancy.NewManager(&tenancy.Options{Enabled: true}) -// telset := telemetry.Settings{ -// Logger: flagsSvc.Logger, -// ReportStatus: telemetry.HCAdapter(flagsSvc.HC()), -// } -// server, err := NewServer( -// serverOptions, -// storageMocks.factory, -// tm, -// telset, -// ) -// require.NoError(t, err) -// require.NoError(t, server.Start()) - -// var clientError error -// var client *grpcClient - -// if serverOptions.TLSSetting != nil { -// clientTLSCfg, err0 := test.clientTLS.LoadTLSConfig(context.Background()) -// require.NoError(t, err0) -// creds := credentials.NewTLS(clientTLSCfg) -// client = newGRPCClient(t, server.grpcConn.Addr().String(), creds, tm) -// } else { -// client = newGRPCClient(t, server.grpcConn.Addr().String(), nil, tm) -// } - -// ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) -// defer cancel() - -// ctx = tenancy.WithTenant(ctx, "foo") -// res, clientError := client.GetServices(ctx, &storage_v1.GetServicesRequest{}) - -// if test.expectClientError { -// require.Error(t, clientError) -// } else { -// require.NoError(t, clientError) -// assert.Equal(t, expectedServices, res.Services) -// } -// require.NoError(t, client.conn.Close()) -// server.Close() -// assert.Equal(t, healthcheck.Unavailable, flagsSvc.HC().Get()) -// }) -// } -// } +func TestServerGRPCTLS(t *testing.T) { + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + serverOptions := &Options{ + ServerConfig: configgrpc.ServerConfig{ + NetAddr: confignet.AddrConfig{ + Endpoint: ":0", + }, + TLSSetting: test.TLS, + }, + } + flagsSvc := flags.NewService(ports.QueryAdminHTTP) + flagsSvc.Logger = zap.NewNop() + + factory, err := storage.NewFactory(defaultFactoryCfg()) + require.NoError(t, err) + + tm := tenancy.NewManager(&tenancy.Options{Enabled: true}) + telset := telemetry.Settings{ + Logger: flagsSvc.Logger, + ReportStatus: telemetry.HCAdapter(flagsSvc.HC()), + } + server, err := NewServer( + serverOptions, + factory, + tm, + telset, + ) + require.NoError(t, err) + require.NoError(t, server.Start()) + + var clientError error + var client *grpcClient + + if serverOptions.TLSSetting != nil { + clientTLSCfg, err0 := test.clientTLS.LoadTLSConfig(context.Background()) + require.NoError(t, err0) + creds := credentials.NewTLS(clientTLSCfg) + client = newGRPCClient(t, server.grpcConn.Addr().String(), creds, tm) + } else { + client = newGRPCClient(t, server.grpcConn.Addr().String(), nil, tm) + } + + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + ctx = tenancy.WithTenant(ctx, "foo") + res, clientError := client.GetServices(ctx, &storage_v1.GetServicesRequest{}) + + if test.expectClientError { + require.Error(t, clientError) + } else { + require.NoError(t, clientError) + assert.Empty(t, res.Services) + } + require.NoError(t, client.conn.Close()) + server.Close() + assert.Equal(t, healthcheck.Unavailable, flagsSvc.HC().Get()) + }) + } +} func TestServerHandlesPortZero(t *testing.T) { flagsSvc := flags.NewService(ports.QueryAdminHTTP) From e8f61f9b39f95726f46646b82b08ea5677da91e6 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 18:29:09 -0500 Subject: [PATCH 39/74] Fix Remote Storage App Tests By Introducing Interface Signed-off-by: Mahad Zaryab --- cmd/remote-storage/app/server.go | 12 +++- cmd/remote-storage/app/server_test.go | 93 +++++++++++++++++++-------- 2 files changed, 76 insertions(+), 29 deletions(-) diff --git a/cmd/remote-storage/app/server.go b/cmd/remote-storage/app/server.go index dcd4a4aa7dd..577df153f20 100644 --- a/cmd/remote-storage/app/server.go +++ b/cmd/remote-storage/app/server.go @@ -20,7 +20,6 @@ import ( "github.com/jaegertracing/jaeger/pkg/bearertoken" "github.com/jaegertracing/jaeger/pkg/telemetry" "github.com/jaegertracing/jaeger/pkg/tenancy" - "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/plugin/storage/grpc/shared" "github.com/jaegertracing/jaeger/storage/dependencystore" "github.com/jaegertracing/jaeger/storage/spanstore" @@ -35,8 +34,15 @@ type Server struct { telset telemetry.Settings } +type storageFactory interface { + CreateSpanReader() (spanstore.Reader, error) + CreateSpanWriter() (spanstore.Writer, error) + CreateDependencyReader() (dependencystore.Reader, error) + InitArchiveStorage(logger *zap.Logger) (spanstore.Reader, spanstore.Writer) +} + // NewServer creates and initializes Server. -func NewServer(options *Options, storageFactory *storage.Factory, tm *tenancy.Manager, telset telemetry.Settings) (*Server, error) { +func NewServer(options *Options, storageFactory storageFactory, tm *tenancy.Manager, telset telemetry.Settings) (*Server, error) { handler, err := createGRPCHandler(storageFactory, telset.Logger) if err != nil { return nil, err @@ -54,7 +60,7 @@ func NewServer(options *Options, storageFactory *storage.Factory, tm *tenancy.Ma }, nil } -func createGRPCHandler(f *storage.Factory, logger *zap.Logger) (*shared.GRPCHandler, error) { +func createGRPCHandler(f storageFactory, logger *zap.Logger) (*shared.GRPCHandler, error) { reader, err := f.CreateSpanReader() if err != nil { return nil, err diff --git a/cmd/remote-storage/app/server_test.go b/cmd/remote-storage/app/server_test.go index e8c3e626b8f..2cffc755ef7 100644 --- a/cmd/remote-storage/app/server_test.go +++ b/cmd/remote-storage/app/server_test.go @@ -5,10 +5,12 @@ package app import ( "context" + "errors" "testing" "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/config/configgrpc" "go.opentelemetry.io/collector/config/confignet" @@ -27,6 +29,10 @@ import ( "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" "github.com/jaegertracing/jaeger/proto-gen/storage_v1" + "github.com/jaegertracing/jaeger/storage/dependencystore" + depStoreMocks "github.com/jaegertracing/jaeger/storage/dependencystore/mocks" + "github.com/jaegertracing/jaeger/storage/spanstore" + spanStoreMocks "github.com/jaegertracing/jaeger/storage/spanstore/mocks" ) var testCertKeyLocation = "../../../pkg/config/tlscfg/testdata" @@ -110,6 +116,28 @@ func TestServerStart_BadPortErrors(t *testing.T) { require.Error(t, srv.Start()) } +type fakeFactory struct { + reader *spanStoreMocks.Reader + writer *spanStoreMocks.Writer + depReader *depStoreMocks.Reader +} + +func (f *fakeFactory) CreateSpanReader() (spanstore.Reader, error) { + return f.reader, nil +} + +func (f *fakeFactory) CreateSpanWriter() (spanstore.Writer, error) { + return f.writer, nil +} + +func (f *fakeFactory) CreateDependencyReader() (dependencystore.Reader, error) { + return f.depReader, nil +} + +func (*fakeFactory) InitArchiveStorage(*zap.Logger) (spanstore.Reader, spanstore.Writer) { + return nil, nil +} + func TestNewServer_TLSConfigError(t *testing.T) { tlsCfg := &configtls.ServerConfig{ ClientCAFile: "invalid/path", @@ -142,33 +170,42 @@ func TestNewServer_TLSConfigError(t *testing.T) { assert.ErrorContains(t, err, "failed to load TLS config") } -// func TestCreateGRPCHandler(t *testing.T) { -// storageMocks := newStorageMocks() -// h, err := createGRPCHandler(storageMocks.factory, zap.NewNop()) -// require.NoError(t, err) +func TestCreateGRPCHandler(t *testing.T) { + reader := new(spanStoreMocks.Reader) + writer := new(spanStoreMocks.Writer) + depReader := new(depStoreMocks.Reader) -// storageMocks.writer.On("WriteSpan", mock.Anything, mock.Anything).Return(errors.New("writer error")) -// _, err = h.WriteSpan(context.Background(), &storage_v1.WriteSpanRequest{}) -// require.ErrorContains(t, err, "writer error") + f := &fakeFactory{ + reader: reader, + writer: writer, + depReader: depReader, + } -// storageMocks.depReader.On( -// "GetDependencies", -// mock.Anything, // context -// mock.Anything, // time -// mock.Anything, // lookback -// ).Return(nil, errors.New("deps error")) -// _, err = h.GetDependencies(context.Background(), &storage_v1.GetDependenciesRequest{}) -// require.ErrorContains(t, err, "deps error") + h, err := createGRPCHandler(f, zap.NewNop()) + require.NoError(t, err) -// err = h.GetArchiveTrace(nil, nil) -// require.ErrorContains(t, err, "not implemented") + writer.On("WriteSpan", mock.Anything, mock.Anything).Return(errors.New("writer error")) + _, err = h.WriteSpan(context.Background(), &storage_v1.WriteSpanRequest{}) + require.ErrorContains(t, err, "writer error") -// _, err = h.WriteArchiveSpan(context.Background(), nil) -// require.ErrorContains(t, err, "not implemented") + depReader.On( + "GetDependencies", + mock.Anything, // context + mock.Anything, // time + mock.Anything, // lookback + ).Return(nil, errors.New("deps error")) + _, err = h.GetDependencies(context.Background(), &storage_v1.GetDependenciesRequest{}) + require.ErrorContains(t, err, "deps error") -// err = h.WriteSpanStream(nil) -// assert.ErrorContains(t, err, "not implemented") -// } + err = h.GetArchiveTrace(nil, nil) + require.ErrorContains(t, err, "not implemented") + + _, err = h.WriteArchiveSpan(context.Background(), nil) + require.ErrorContains(t, err, "not implemented") + + err = h.WriteSpanStream(nil) + assert.ErrorContains(t, err, "not implemented") +} var testCases = []struct { name string @@ -340,8 +377,12 @@ func TestServerGRPCTLS(t *testing.T) { flagsSvc := flags.NewService(ports.QueryAdminHTTP) flagsSvc.Logger = zap.NewNop() - factory, err := storage.NewFactory(defaultFactoryCfg()) - require.NoError(t, err) + reader := new(spanStoreMocks.Reader) + f := &fakeFactory{ + reader: reader, + } + expectedServices := []string{"test"} + reader.On("GetServices", mock.AnythingOfType("*context.valueCtx")).Return(expectedServices, nil) tm := tenancy.NewManager(&tenancy.Options{Enabled: true}) telset := telemetry.Settings{ @@ -350,7 +391,7 @@ func TestServerGRPCTLS(t *testing.T) { } server, err := NewServer( serverOptions, - factory, + f, tm, telset, ) @@ -379,7 +420,7 @@ func TestServerGRPCTLS(t *testing.T) { require.Error(t, clientError) } else { require.NoError(t, clientError) - assert.Empty(t, res.Services) + assert.Equal(t, expectedServices, res.Services) } require.NoError(t, client.conn.Close()) server.Close() From 2fe8982b8f403ffb5a648a0589601de86960bd5e Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 22:19:10 -0500 Subject: [PATCH 40/74] Use FakeFactory For Storage Errors Test Signed-off-by: Mahad Zaryab --- cmd/remote-storage/app/server_test.go | 115 +++++++++++--------------- 1 file changed, 46 insertions(+), 69 deletions(-) diff --git a/cmd/remote-storage/app/server_test.go b/cmd/remote-storage/app/server_test.go index 2cffc755ef7..25603dc701d 100644 --- a/cmd/remote-storage/app/server_test.go +++ b/cmd/remote-storage/app/server_test.go @@ -26,7 +26,6 @@ import ( "github.com/jaegertracing/jaeger/pkg/healthcheck" "github.com/jaegertracing/jaeger/pkg/telemetry" "github.com/jaegertracing/jaeger/pkg/tenancy" - "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" "github.com/jaegertracing/jaeger/proto-gen/storage_v1" "github.com/jaegertracing/jaeger/storage/dependencystore" @@ -37,70 +36,40 @@ import ( var testCertKeyLocation = "../../../pkg/config/tlscfg/testdata" -func defaultFactoryCfg() storage.FactoryConfig { - return storage.FactoryConfig{ - SpanWriterTypes: []string{"blackhole"}, - SpanReaderType: "blackhole", - DependenciesStorageType: "blackhole", - DownsamplingRatio: 1.0, - DownsamplingHashSalt: "", - } -} - func TestNewServer_CreateStorageErrors(t *testing.T) { - tests := []struct { - name string - modifyFactory func(factory *storage.FactoryConfig) - expectedError string - }{ - { - name: "no span reader", - modifyFactory: func(factory *storage.FactoryConfig) { - factory.SpanReaderType = "a" - }, - expectedError: "no a backend registered", - }, - { - name: "no span writer", - modifyFactory: func(factory *storage.FactoryConfig) { - factory.SpanWriterTypes = []string{"b"} - }, - expectedError: "no b backend registered", - }, - { - name: "no dependency reader", - modifyFactory: func(factory *storage.FactoryConfig) { - factory.DependenciesStorageType = "c" + createServer := func(factory *fakeFactory) (*Server, error) { + return NewServer( + &Options{ + ServerConfig: configgrpc.ServerConfig{ + NetAddr: confignet.AddrConfig{ + Endpoint: ":0", + }, + }, }, - expectedError: "no c backend registered", - }, + factory, + tenancy.NewManager(&tenancy.Options{}), + telemetry.NoopSettings(), + ) } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - factoryCfg := defaultFactoryCfg() + factory := &fakeFactory{readerErr: errors.New("no reader")} + _, err := createServer(factory) + require.ErrorContains(t, err, "no reader") - factory, err := storage.NewFactory(factoryCfg) - require.NoError(t, err) + factory = &fakeFactory{writerErr: errors.New("no writer")} + _, err = createServer(factory) + require.ErrorContains(t, err, "no writer") - test.modifyFactory(&factory.FactoryConfig) + factory = &fakeFactory{depReaderErr: errors.New("no deps")} + _, err = createServer(factory) + require.ErrorContains(t, err, "no deps") - _, err = NewServer( - &Options{ - ServerConfig: configgrpc.ServerConfig{ - NetAddr: confignet.AddrConfig{ - Endpoint: ":0", - }, - }, - }, - factory, - tenancy.NewManager(&tenancy.Options{}), - telemetry.NoopSettings(), - ) - - require.ErrorContains(t, err, test.expectedError) - }) - } + factory = &fakeFactory{} + s, err := createServer(factory) + require.NoError(t, err) + require.NoError(t, s.Start()) + validateGRPCServer(t, s.grpcConn.Addr().String()) + require.NoError(t, s.grpcConn.Close()) } func TestServerStart_BadPortErrors(t *testing.T) { @@ -117,20 +86,33 @@ func TestServerStart_BadPortErrors(t *testing.T) { } type fakeFactory struct { - reader *spanStoreMocks.Reader - writer *spanStoreMocks.Writer - depReader *depStoreMocks.Reader + reader spanstore.Reader + writer spanstore.Writer + depReader dependencystore.Reader + + readerErr error + writerErr error + depReaderErr error } func (f *fakeFactory) CreateSpanReader() (spanstore.Reader, error) { + if f.readerErr != nil { + return nil, f.readerErr + } return f.reader, nil } func (f *fakeFactory) CreateSpanWriter() (spanstore.Writer, error) { + if f.writerErr != nil { + return nil, f.writerErr + } return f.writer, nil } func (f *fakeFactory) CreateDependencyReader() (dependencystore.Reader, error) { + if f.depReaderErr != nil { + return nil, f.depReaderErr + } return f.depReader, nil } @@ -151,10 +133,7 @@ func TestNewServer_TLSConfigError(t *testing.T) { ReportStatus: telemetry.HCAdapter(healthcheck.New()), } - f, err := storage.NewFactory(defaultFactoryCfg()) - require.NoError(t, err) - - _, err = NewServer( + _, err := NewServer( &Options{ ServerConfig: configgrpc.ServerConfig{ NetAddr: confignet.AddrConfig{ @@ -163,7 +142,7 @@ func TestNewServer_TLSConfigError(t *testing.T) { TLSSetting: tlsCfg, }, }, - f, + &fakeFactory{}, tenancy.NewManager(&tenancy.Options{}), telset, ) @@ -433,8 +412,6 @@ func TestServerHandlesPortZero(t *testing.T) { flagsSvc := flags.NewService(ports.QueryAdminHTTP) zapCore, logs := observer.New(zap.InfoLevel) flagsSvc.Logger = zap.New(zapCore) - f, err := storage.NewFactory(defaultFactoryCfg()) - require.NoError(t, err) telset := telemetry.Settings{ Logger: flagsSvc.Logger, ReportStatus: telemetry.HCAdapter(flagsSvc.HC()), @@ -443,7 +420,7 @@ func TestServerHandlesPortZero(t *testing.T) { &Options{ServerConfig: configgrpc.ServerConfig{ NetAddr: confignet.AddrConfig{Endpoint: ":0"}, }}, - f, + &fakeFactory{}, tenancy.NewManager(&tenancy.Options{}), telset, ) From c75bcaf90e0d6b3fef47d82c65e19eebc615d63d Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sun, 19 Jan 2025 22:36:58 -0500 Subject: [PATCH 41/74] Add Tests For Missing Code Paths Signed-off-by: Mahad Zaryab --- cmd/query/app/flags.go | 14 +++++---- cmd/query/app/flags_test.go | 58 +++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/cmd/query/app/flags.go b/cmd/query/app/flags.go index fc3b3ceb9eb..2f74022325f 100644 --- a/cmd/query/app/flags.go +++ b/cmd/query/app/flags.go @@ -29,8 +29,8 @@ import ( "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/config/tlscfg" "github.com/jaegertracing/jaeger/pkg/tenancy" - "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" + "github.com/jaegertracing/jaeger/storage/spanstore" "github.com/jaegertracing/jaeger/storage_v2/v1adapter" ) @@ -138,10 +138,14 @@ func (qOpts *QueryOptions) InitFromViper(v *viper.Viper, logger *zap.Logger) (*Q return qOpts, nil } +type archiveInitializer interface { + InitArchiveStorage(logger *zap.Logger) (spanstore.Reader, spanstore.Writer) +} + // BuildQueryServiceOptions creates a QueryServiceOptions struct with appropriate adjusters and archive config -func (qOpts *QueryOptions) BuildQueryServiceOptions(storageFactory *storage.Factory, logger *zap.Logger) *querysvc.QueryServiceOptions { +func (qOpts *QueryOptions) BuildQueryServiceOptions(archiveInitializer archiveInitializer, logger *zap.Logger) *querysvc.QueryServiceOptions { opts := &querysvc.QueryServiceOptions{} - ar, aw := storageFactory.InitArchiveStorage(logger) + ar, aw := archiveInitializer.InitArchiveStorage(logger) if ar != nil && aw != nil { opts.ArchiveSpanReader = ar opts.ArchiveSpanWriter = aw @@ -154,10 +158,10 @@ func (qOpts *QueryOptions) BuildQueryServiceOptions(storageFactory *storage.Fact return opts } -func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(storageFactory *storage.Factory, logger *zap.Logger) *v2querysvc.QueryServiceOptions { +func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(archiveInitializer archiveInitializer, logger *zap.Logger) *v2querysvc.QueryServiceOptions { opts := &v2querysvc.QueryServiceOptions{} - ar, aw := storageFactory.InitArchiveStorage(logger) + ar, aw := archiveInitializer.InitArchiveStorage(logger) if ar != nil && aw != nil { opts.ArchiveTraceReader = v1adapter.NewTraceReader(ar) opts.ArchiveTraceWriter = v1adapter.NewTraceWriter(aw) diff --git a/cmd/query/app/flags_test.go b/cmd/query/app/flags_test.go index 82fcb2310ac..994e20bdb67 100644 --- a/cmd/query/app/flags_test.go +++ b/cmd/query/app/flags_test.go @@ -16,20 +16,11 @@ import ( "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/testutils" - "github.com/jaegertracing/jaeger/plugin/storage" "github.com/jaegertracing/jaeger/ports" + "github.com/jaegertracing/jaeger/storage/spanstore" + spanstoremocks "github.com/jaegertracing/jaeger/storage/spanstore/mocks" ) -func defaultFactoryCfg() storage.FactoryConfig { - return storage.FactoryConfig{ - SpanWriterTypes: []string{"blackhole"}, - SpanReaderType: "blackhole", - DependenciesStorageType: "blackhole", - DownsamplingRatio: 1.0, - DownsamplingHashSalt: "", - } -} - func TestQueryBuilderFlags(t *testing.T) { v, command := config.Viperize(AddFlags) command.ParseFlags([]string{ @@ -95,20 +86,45 @@ func TestStringSliceAsHeader(t *testing.T) { require.NoError(t, err) } +type fakeArchiveInitializer struct { + archiveReader spanstore.Reader + archiveWriter spanstore.Writer +} + +func (f *fakeArchiveInitializer) InitArchiveStorage(*zap.Logger) (spanstore.Reader, spanstore.Writer) { + return f.archiveReader, f.archiveWriter +} + func TestBuildQueryServiceOptions(t *testing.T) { v, _ := config.Viperize(AddFlags) qOpts, err := new(QueryOptions).InitFromViper(v, zap.NewNop()) require.NoError(t, err) assert.NotNil(t, qOpts) - f, err := storage.NewFactory(defaultFactoryCfg()) + qSvcOpts := qOpts.BuildQueryServiceOptions(&fakeArchiveInitializer{ + archiveReader: &spanstoremocks.Reader{}, + archiveWriter: &spanstoremocks.Writer{}, + }, zap.NewNop()) + assert.NotNil(t, qSvcOpts) + assert.NotNil(t, qSvcOpts.Adjuster) + assert.NotNil(t, qSvcOpts.ArchiveSpanReader) + assert.NotNil(t, qSvcOpts.ArchiveSpanWriter) +} + +func TestBuildQueryServiceOptions_NoArchiveStorage(t *testing.T) { + v, _ := config.Viperize(AddFlags) + qOpts, err := new(QueryOptions).InitFromViper(v, zap.NewNop()) require.NoError(t, err) + assert.NotNil(t, qOpts) - qSvcOpts := qOpts.BuildQueryServiceOptions(f, zap.NewNop()) + logger, logBuf := testutils.NewLogger() + qSvcOpts := qOpts.BuildQueryServiceOptions(&fakeArchiveInitializer{}, logger) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) assert.Nil(t, qSvcOpts.ArchiveSpanReader) assert.Nil(t, qSvcOpts.ArchiveSpanWriter) + + require.Contains(t, logBuf.String(), "Archive storage not initialized") } func TestBuildQueryServiceOptionsV2(t *testing.T) { @@ -117,14 +133,15 @@ func TestBuildQueryServiceOptionsV2(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) - f, err := storage.NewFactory(defaultFactoryCfg()) - require.NoError(t, err) + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(&fakeArchiveInitializer{ + archiveReader: &spanstoremocks.Reader{}, + archiveWriter: &spanstoremocks.Writer{}, + }, zap.NewNop()) - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(f, zap.NewNop()) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) - assert.Nil(t, qSvcOpts.ArchiveTraceReader) - assert.Nil(t, qSvcOpts.ArchiveTraceWriter) + assert.NotNil(t, qSvcOpts.ArchiveTraceReader) + assert.NotNil(t, qSvcOpts.ArchiveTraceWriter) } func TestBuildQueryServiceOptionsV2_NoArchiveStorage(t *testing.T) { @@ -133,11 +150,8 @@ func TestBuildQueryServiceOptionsV2_NoArchiveStorage(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) - f, err := storage.NewFactory(defaultFactoryCfg()) - require.NoError(t, err) - logger, logBuf := testutils.NewLogger() - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(f, logger) + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(&fakeArchiveInitializer{}, logger) assert.Nil(t, qSvcOpts.ArchiveTraceReader) assert.Nil(t, qSvcOpts.ArchiveTraceWriter) From 9656083c5c2ba71c18ef8f7fe44e71889bc16bbc Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 11:25:47 -0500 Subject: [PATCH 42/74] Move Logic To Initialization Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index 1c3ea30ade9..c67a9602cb6 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -75,21 +75,8 @@ func NewFactory() *Factory { } func NewArchiveFactory() *Factory { - opts := NewOptions(archiveNamespace) - - aliasSuffix := "archive" - if opts.Config.UseReadWriteAliases { - opts.Config.ReadAliasSuffix = aliasSuffix + "-read" - opts.Config.WriteAliasSuffix = aliasSuffix + "-write" - } else { - opts.Config.ReadAliasSuffix = aliasSuffix - opts.Config.WriteAliasSuffix = aliasSuffix - } - - opts.Config.UseReadWriteAliases = true - return &Factory{ - Options: opts, + Options: NewOptions(archiveNamespace), newClientFn: config.NewClient, tracer: otel.GetTracerProvider(), } @@ -155,6 +142,19 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) f.watchers = append(f.watchers, watcher) } + if f.Options.Config.namespace == archiveNamespace { + aliasSuffix := "archive" + if f.config.UseReadWriteAliases { + f.config.ReadAliasSuffix = aliasSuffix + "-read" + f.config.WriteAliasSuffix = aliasSuffix + "-write" + } else { + f.config.ReadAliasSuffix = aliasSuffix + f.config.WriteAliasSuffix = aliasSuffix + } + + f.config.UseReadWriteAliases = true + } + return nil } From f4afdf134026960993eb8be702eccfbafa208da9 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 11:32:59 -0500 Subject: [PATCH 43/74] Add Unit Test For Archive Factory Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory_test.go | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/plugin/storage/es/factory_test.go b/plugin/storage/es/factory_test.go index 392491823e3..fd6fa76ac23 100644 --- a/plugin/storage/es/factory_test.go +++ b/plugin/storage/es/factory_test.go @@ -87,6 +87,44 @@ func TestElasticsearchFactory(t *testing.T) { require.NoError(t, f.Close()) } +func TestArchiveFactory(t *testing.T) { + tests := []struct { + name string + args []string + expectedReadAlias string + expectedWriteAlias string + }{ + { + name: "default settings", + args: []string{}, + expectedReadAlias: "archive", + expectedWriteAlias: "archive", + }, + { + name: "use read write aliases", + args: []string{"--es-archive.use-aliases=true"}, + expectedReadAlias: "archive-read", + expectedWriteAlias: "archive-write", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + f := NewArchiveFactory() + v, command := config.Viperize(f.AddFlags) + command.ParseFlags(test.args) + f.InitFromViper(v, zap.NewNop()) + + f.newClientFn = (&mockClientBuilder{}).NewClient + require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) + + require.Equal(t, test.expectedReadAlias, f.config.ReadAliasSuffix) + require.Equal(t, test.expectedWriteAlias, f.config.WriteAliasSuffix) + require.True(t, f.config.UseReadWriteAliases) + }) + } +} + func TestElasticsearchTagsFileDoNotExist(t *testing.T) { f := NewFactory() f.config = &escfg.Configuration{ From 1ae9be2d1a5cbbf6926f942aecb4a99f499a4b8a Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 11:35:54 -0500 Subject: [PATCH 44/74] Add Test For Cassandra Factory Signed-off-by: Mahad Zaryab --- plugin/storage/cassandra/factory_test.go | 79 +++++++++++++++--------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/plugin/storage/cassandra/factory_test.go b/plugin/storage/cassandra/factory_test.go index d0b3c425d83..b59cff0dab2 100644 --- a/plugin/storage/cassandra/factory_test.go +++ b/plugin/storage/cassandra/factory_test.go @@ -47,44 +47,67 @@ func (m *mockSessionBuilder) build(*config.Configuration) (cassandra.Session, er func TestCassandraFactory(t *testing.T) { logger, _ := testutils.NewLogger() - f := NewFactory() - v, command := viperize.Viperize(f.AddFlags) - command.ParseFlags([]string{"--cassandra-archive.enabled=true"}) - f.InitFromViper(v, zap.NewNop()) - f.sessionBuilderFn = new(mockSessionBuilder).add(nil, errors.New("made-up primary error")).build - require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "made-up primary error") + tests := []struct { + name string + factoryFn func() *Factory + namespace string + }{ + { + name: "CassandraFactory", + factoryFn: NewFactory, + namespace: primaryStorageNamespace, + }, + { + name: "CassandraArchiveFactory", + factoryFn: NewArchiveFactory, + namespace: archiveStorageNamespace, + }, + } - var ( - session = &mocks.Session{} - query = &mocks.Query{} - ) - session.On("Query", mock.AnythingOfType("string"), mock.Anything).Return(query) - session.On("Close").Return() - query.On("Exec").Return(nil) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + f := test.factoryFn() + require.Equal(t, test.namespace, f.Options.namespace) + v, command := viperize.Viperize(f.AddFlags) + command.ParseFlags([]string{}) + f.InitFromViper(v, zap.NewNop()) - f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).build - require.NoError(t, f.Initialize(metrics.NullFactory, logger)) + f.sessionBuilderFn = new(mockSessionBuilder).add(nil, errors.New("made-up primary error")).build + require.EqualError(t, f.Initialize(metrics.NullFactory, zap.NewNop()), "made-up primary error") - _, err := f.CreateSpanReader() - require.NoError(t, err) + var ( + session = &mocks.Session{} + query = &mocks.Query{} + ) + session.On("Query", mock.AnythingOfType("string"), mock.Anything).Return(query) + session.On("Close").Return() + query.On("Exec").Return(nil) - _, err = f.CreateSpanWriter() - require.NoError(t, err) + f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).build + require.NoError(t, f.Initialize(metrics.NullFactory, logger)) - _, err = f.CreateDependencyReader() - require.NoError(t, err) + _, err := f.CreateSpanReader() + require.NoError(t, err) - f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).add(session, nil).build - require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) + _, err = f.CreateSpanWriter() + require.NoError(t, err) - _, err = f.CreateLock() - require.NoError(t, err) + _, err = f.CreateDependencyReader() + require.NoError(t, err) - _, err = f.CreateSamplingStore(0) - require.NoError(t, err) + f.sessionBuilderFn = new(mockSessionBuilder).add(session, nil).add(session, nil).build + require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) + + _, err = f.CreateLock() + require.NoError(t, err) - require.NoError(t, f.Close()) + _, err = f.CreateSamplingStore(0) + require.NoError(t, err) + + require.NoError(t, f.Close()) + }) + } } func TestCreateSpanReaderError(t *testing.T) { From 11ec9fe8c344c77edb65877dc09940fe74d1fff9 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 11:55:43 -0500 Subject: [PATCH 45/74] Allow Inheriting of Default Settings Signed-off-by: Mahad Zaryab --- plugin/configurable.go | 6 ++++++ plugin/storage/cassandra/factory.go | 6 ++++++ plugin/storage/es/factory.go | 18 ++++++++++++------ plugin/storage/factory.go | 8 +++++++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/plugin/configurable.go b/plugin/configurable.go index 07a479cf4ce..edc32ef92ab 100644 --- a/plugin/configurable.go +++ b/plugin/configurable.go @@ -9,6 +9,8 @@ import ( "github.com/spf13/viper" "go.uber.org/zap" + + "github.com/jaegertracing/jaeger/storage" ) // Configurable interface can be implemented by plugins that require external configuration, @@ -20,3 +22,7 @@ type Configurable interface { // InitFromViper initializes this component with properties from spf13/viper. InitFromViper(v *viper.Viper, logger *zap.Logger) } + +type DefaultConfigurable interface { + InheritSettingsFrom(other storage.Factory) +} diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 15eef48f7a5..9848e629c45 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -282,3 +282,9 @@ func (f *Factory) Close() error { func (f *Factory) Purge(_ context.Context) error { return f.session.Query("TRUNCATE traces").Exec() } + +func (f *Factory) InheritDefaultSettingsFrom(other storage.Factory) { + if otherFactory, ok := other.(*Factory); ok { + f.config.ApplyDefaults(&otherFactory.config) + } +} diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index c67a9602cb6..876951d322e 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -42,10 +42,11 @@ const ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) - _ storage.Purger = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ plugin.DefaultConfigurable = (*Factory)(nil) + _ storage.Purger = (*Factory)(nil) ) // Factory implements storage.Factory for Elasticsearch backend. @@ -142,7 +143,7 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) f.watchers = append(f.watchers, watcher) } - if f.Options.Config.namespace == archiveNamespace { + if f.Options != nil && f.Options.Config.namespace == archiveNamespace { aliasSuffix := "archive" if f.config.UseReadWriteAliases { f.config.ReadAliasSuffix = aliasSuffix + "-read" @@ -151,7 +152,6 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) f.config.ReadAliasSuffix = aliasSuffix f.config.WriteAliasSuffix = aliasSuffix } - f.config.UseReadWriteAliases = true } @@ -363,3 +363,9 @@ func loadTokenFromFile(path string) (string, error) { } return strings.TrimRight(string(b), "\r\n"), nil } + +func (f *Factory) InheritSettingsFrom(other storage.Factory) { + if otherFactory, ok := other.(*Factory); ok { + f.config.ApplyDefaults(otherFactory.config) + } +} diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index 7c494ce5564..eff328c0128 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -166,6 +166,13 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) if err := factory.Initialize(mf, logger); err != nil { return err } + if role == "archive" { + if primaryFactory, ok := f.factories[kind]; ok { + if dc, ok := factory.(plugin.DefaultConfigurable); ok { + dc.InheritSettingsFrom(primaryFactory) + } + } + } } return nil } @@ -176,7 +183,6 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) return err } f.publishOpts() - return nil } From 782e3ea9651d61314d6c1e060f3267d620c4cbec Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 12:05:08 -0500 Subject: [PATCH 46/74] Add Unit Test To Cassandra Factory Signed-off-by: Mahad Zaryab --- plugin/configurable.go | 2 ++ plugin/storage/cassandra/factory.go | 2 +- plugin/storage/cassandra/factory_test.go | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/plugin/configurable.go b/plugin/configurable.go index edc32ef92ab..b55ead9943f 100644 --- a/plugin/configurable.go +++ b/plugin/configurable.go @@ -23,6 +23,8 @@ type Configurable interface { InitFromViper(v *viper.Viper, logger *zap.Logger) } +// DefaultConfigurable is an interface that can be implement by some storage implementations +// to provide a way to inherit configuration settings from another factory. type DefaultConfigurable interface { InheritSettingsFrom(other storage.Factory) } diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 9848e629c45..5d8e9ddf557 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -283,7 +283,7 @@ func (f *Factory) Purge(_ context.Context) error { return f.session.Query("TRUNCATE traces").Exec() } -func (f *Factory) InheritDefaultSettingsFrom(other storage.Factory) { +func (f *Factory) InheritSettingsFrom(other storage.Factory) { if otherFactory, ok := other.(*Factory); ok { f.config.ApplyDefaults(&otherFactory.config) } diff --git a/plugin/storage/cassandra/factory_test.go b/plugin/storage/cassandra/factory_test.go index b59cff0dab2..e068b0a7f3c 100644 --- a/plugin/storage/cassandra/factory_test.go +++ b/plugin/storage/cassandra/factory_test.go @@ -291,3 +291,17 @@ func TestNewSessionErrors(t *testing.T) { require.ErrorContains(t, err, "no hosts provided") }) } + +func TestInheritSettingsFrom(t *testing.T) { + primaryFactory := NewFactory() + primaryFactory.config.Schema.Keyspace = "foo" + primaryFactory.config.Query.MaxRetryAttempts = 99 + + archiveFactory := NewArchiveFactory() + archiveFactory.config.Schema.Keyspace = "bar" + + archiveFactory.InheritSettingsFrom(primaryFactory) + + require.Equal(t, "bar", archiveFactory.config.Schema.Keyspace) + require.Equal(t, 99, archiveFactory.config.Query.MaxRetryAttempts) +} From 263315bdd3a0f0341ca732723331b60ccadc0dd6 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 12:12:24 -0500 Subject: [PATCH 47/74] Add Unit Test To ES Factory Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plugin/storage/es/factory_test.go b/plugin/storage/es/factory_test.go index fd6fa76ac23..0cf8ffa52ab 100644 --- a/plugin/storage/es/factory_test.go +++ b/plugin/storage/es/factory_test.go @@ -447,3 +447,20 @@ func TestPasswordFromFileErrors(t *testing.T) { require.NoError(t, os.Remove(pwdFile)) f.onPasswordChange() } + +func TestInheritSettingsFrom(t *testing.T) { + primaryFactory := NewFactory() + primaryFactory.config = &escfg.Configuration{ + MaxDocCount: 99, + } + + archiveFactory := NewArchiveFactory() + archiveFactory.config = &escfg.Configuration{ + SendGetBodyAs: "PUT", + } + + archiveFactory.InheritSettingsFrom(primaryFactory) + + require.Equal(t, "PUT", archiveFactory.config.SendGetBodyAs) + require.Equal(t, 99, primaryFactory.config.MaxDocCount) +} From 304504928aac0996353c73d885a704f63b628625 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 20:24:57 -0500 Subject: [PATCH 48/74] Change Input To Be Func Type Signed-off-by: Mahad Zaryab --- cmd/all-in-one/main.go | 4 ++-- cmd/query/app/flags.go | 15 ++++++++------- cmd/query/app/flags_test.go | 23 ++++++----------------- cmd/query/main.go | 10 ++++++++-- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/cmd/all-in-one/main.go b/cmd/all-in-one/main.go index b393a6c962d..502efe2c895 100644 --- a/cmd/all-in-one/main.go +++ b/cmd/all-in-one/main.go @@ -171,8 +171,8 @@ by default uses only in-memory database.`, queryTelset := baseTelset // copy queryTelset.Metrics = queryMetricsFactory querySrv := startQuery( - svc, qOpts, qOpts.BuildQueryServiceOptions(storageFactory, logger), - qOpts.BuildQueryServiceOptionsV2(storageFactory, logger), + svc, qOpts, qOpts.BuildQueryServiceOptions(storageFactory.InitArchiveStorage, logger), + qOpts.BuildQueryServiceOptionsV2(storageFactory.InitArchiveStorage, logger), traceReader, dependencyReader, metricsQueryService, tm, queryTelset, ) diff --git a/cmd/query/app/flags.go b/cmd/query/app/flags.go index 2f74022325f..2110c9f2a70 100644 --- a/cmd/query/app/flags.go +++ b/cmd/query/app/flags.go @@ -138,14 +138,15 @@ func (qOpts *QueryOptions) InitFromViper(v *viper.Viper, logger *zap.Logger) (*Q return qOpts, nil } -type archiveInitializer interface { - InitArchiveStorage(logger *zap.Logger) (spanstore.Reader, spanstore.Writer) -} +type InitArchiveStorageFn func(logger *zap.Logger) (spanstore.Reader, spanstore.Writer) // BuildQueryServiceOptions creates a QueryServiceOptions struct with appropriate adjusters and archive config -func (qOpts *QueryOptions) BuildQueryServiceOptions(archiveInitializer archiveInitializer, logger *zap.Logger) *querysvc.QueryServiceOptions { +func (qOpts *QueryOptions) BuildQueryServiceOptions( + initArchiveStorageFn InitArchiveStorageFn, + logger *zap.Logger, +) *querysvc.QueryServiceOptions { opts := &querysvc.QueryServiceOptions{} - ar, aw := archiveInitializer.InitArchiveStorage(logger) + ar, aw := initArchiveStorageFn(logger) if ar != nil && aw != nil { opts.ArchiveSpanReader = ar opts.ArchiveSpanWriter = aw @@ -158,10 +159,10 @@ func (qOpts *QueryOptions) BuildQueryServiceOptions(archiveInitializer archiveIn return opts } -func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(archiveInitializer archiveInitializer, logger *zap.Logger) *v2querysvc.QueryServiceOptions { +func (qOpts *QueryOptions) BuildQueryServiceOptionsV2(initArchiveStorageFn InitArchiveStorageFn, logger *zap.Logger) *v2querysvc.QueryServiceOptions { opts := &v2querysvc.QueryServiceOptions{} - ar, aw := archiveInitializer.InitArchiveStorage(logger) + ar, aw := initArchiveStorageFn(logger) if ar != nil && aw != nil { opts.ArchiveTraceReader = v1adapter.NewTraceReader(ar) opts.ArchiveTraceWriter = v1adapter.NewTraceWriter(aw) diff --git a/cmd/query/app/flags_test.go b/cmd/query/app/flags_test.go index 994e20bdb67..e54259c1262 100644 --- a/cmd/query/app/flags_test.go +++ b/cmd/query/app/flags_test.go @@ -86,13 +86,8 @@ func TestStringSliceAsHeader(t *testing.T) { require.NoError(t, err) } -type fakeArchiveInitializer struct { - archiveReader spanstore.Reader - archiveWriter spanstore.Writer -} - -func (f *fakeArchiveInitializer) InitArchiveStorage(*zap.Logger) (spanstore.Reader, spanstore.Writer) { - return f.archiveReader, f.archiveWriter +func fakeInitializerFn(*zap.Logger) (spanstore.Reader, spanstore.Writer) { + return &spanstoremocks.Reader{}, &spanstoremocks.Writer{} } func TestBuildQueryServiceOptions(t *testing.T) { @@ -101,10 +96,7 @@ func TestBuildQueryServiceOptions(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) - qSvcOpts := qOpts.BuildQueryServiceOptions(&fakeArchiveInitializer{ - archiveReader: &spanstoremocks.Reader{}, - archiveWriter: &spanstoremocks.Writer{}, - }, zap.NewNop()) + qSvcOpts := qOpts.BuildQueryServiceOptions(fakeInitializerFn, zap.NewNop()) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) assert.NotNil(t, qSvcOpts.ArchiveSpanReader) @@ -118,7 +110,7 @@ func TestBuildQueryServiceOptions_NoArchiveStorage(t *testing.T) { assert.NotNil(t, qOpts) logger, logBuf := testutils.NewLogger() - qSvcOpts := qOpts.BuildQueryServiceOptions(&fakeArchiveInitializer{}, logger) + qSvcOpts := qOpts.BuildQueryServiceOptions(fakeInitializerFn, logger) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) assert.Nil(t, qSvcOpts.ArchiveSpanReader) @@ -133,10 +125,7 @@ func TestBuildQueryServiceOptionsV2(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(&fakeArchiveInitializer{ - archiveReader: &spanstoremocks.Reader{}, - archiveWriter: &spanstoremocks.Writer{}, - }, zap.NewNop()) + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(fakeInitializerFn, zap.NewNop()) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) @@ -151,7 +140,7 @@ func TestBuildQueryServiceOptionsV2_NoArchiveStorage(t *testing.T) { assert.NotNil(t, qOpts) logger, logBuf := testutils.NewLogger() - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(&fakeArchiveInitializer{}, logger) + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(fakeInitializerFn, logger) assert.Nil(t, qSvcOpts.ArchiveTraceReader) assert.Nil(t, qSvcOpts.ArchiveTraceWriter) diff --git a/cmd/query/main.go b/cmd/query/main.go index 2cced74fb30..8ee34ae6188 100644 --- a/cmd/query/main.go +++ b/cmd/query/main.go @@ -107,13 +107,19 @@ func main() { if err != nil { logger.Fatal("Failed to create metrics query service", zap.Error(err)) } - queryServiceOptions := queryOpts.BuildQueryServiceOptions(storageFactory, logger) + queryServiceOptions := queryOpts.BuildQueryServiceOptions( + storageFactory.InitArchiveStorage, + logger, + ) queryService := querysvc.NewQueryService( traceReader, dependencyReader, *queryServiceOptions) - queryServiceOptionsV2 := queryOpts.BuildQueryServiceOptionsV2(storageFactory, logger) + queryServiceOptionsV2 := queryOpts.BuildQueryServiceOptionsV2( + storageFactory.InitArchiveStorage, + logger, + ) queryServiceV2 := querysvcv2.NewQueryService( traceReader, dependencyReader, From 944d425e5fbbc3cbc8d1ac0fd4998d2869c72a74 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 20:27:38 -0500 Subject: [PATCH 49/74] Add Documentation For New Configuration Fields Signed-off-by: Mahad Zaryab --- pkg/es/config/config.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/es/config/config.go b/pkg/es/config/config.go index 6a40a016223..a1916e95d48 100644 --- a/pkg/es/config/config.go +++ b/pkg/es/config/config.go @@ -114,9 +114,15 @@ type Configuration struct { // UseReadWriteAliases, if set to true, will use read and write aliases for indices. // Use this option with Elasticsearch rollover API. It requires an external component // to create aliases before startup and then performing its management. - UseReadWriteAliases bool `mapstructure:"use_aliases"` - ReadAliasSuffix string `mapstructure:"-"` - WriteAliasSuffix string `mapstructure:"-"` + UseReadWriteAliases bool `mapstructure:"use_aliases"` + // ReadAliasSuffix is the suffix to append to the index name used for reading. + // This configuration only exists to provide backwards compatibility for jaeger-v1 + // which is why it is not exposed as a configuration option for jaeger-v2 + ReadAliasSuffix string `mapstructure:"-"` + // WriteAliasSuffix is the suffix to append to the write index name. + // This configuration only exists to provide backwards compatibility for jaeger-v1 + // which is why it is not exposed as a configuration option for jaeger-v2 + WriteAliasSuffix string `mapstructure:"-"` // CreateIndexTemplates, if set to true, creates index templates at application startup. // This configuration should be set to false when templates are installed manually. CreateIndexTemplates bool `mapstructure:"create_mappings"` From a3440be5514a5a4cf1f5993557d580476cbe0e5d Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 20:29:09 -0500 Subject: [PATCH 50/74] Change Name of Interface Signed-off-by: Mahad Zaryab --- plugin/configurable.go | 4 ++-- plugin/storage/cassandra/factory.go | 1 + plugin/storage/es/factory.go | 10 +++++----- plugin/storage/factory.go | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/plugin/configurable.go b/plugin/configurable.go index b55ead9943f..a1e011d855b 100644 --- a/plugin/configurable.go +++ b/plugin/configurable.go @@ -23,8 +23,8 @@ type Configurable interface { InitFromViper(v *viper.Viper, logger *zap.Logger) } -// DefaultConfigurable is an interface that can be implement by some storage implementations +// Inheritable is an interface that can be implement by some storage implementations // to provide a way to inherit configuration settings from another factory. -type DefaultConfigurable interface { +type Inheritable interface { InheritSettingsFrom(other storage.Factory) } diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 5d8e9ddf557..2a8fc48b310 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -46,6 +46,7 @@ var ( // interface comformance checks _ storage.SamplingStoreFactory = (*Factory)(nil) _ io.Closer = (*Factory)(nil) _ plugin.Configurable = (*Factory)(nil) + _ plugin.Inheritable = (*Factory)(nil) ) // Factory implements storage.Factory for Cassandra backend. diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index 876951d322e..74d3a18d568 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -42,11 +42,11 @@ const ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) - _ plugin.DefaultConfigurable = (*Factory)(nil) - _ storage.Purger = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ plugin.Inheritable = (*Factory)(nil) + _ storage.Purger = (*Factory)(nil) ) // Factory implements storage.Factory for Elasticsearch backend. diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index eff328c0128..466bb7dadd9 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -168,7 +168,7 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) } if role == "archive" { if primaryFactory, ok := f.factories[kind]; ok { - if dc, ok := factory.(plugin.DefaultConfigurable); ok { + if dc, ok := factory.(plugin.Inheritable); ok { dc.InheritSettingsFrom(primaryFactory) } } From d1674a4cc9d9be006bda252c42a488ff90ff684d Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 20:42:10 -0500 Subject: [PATCH 51/74] Fix Unit Tests Signed-off-by: Mahad Zaryab --- cmd/query/app/flags_test.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cmd/query/app/flags_test.go b/cmd/query/app/flags_test.go index e54259c1262..86f07f367fd 100644 --- a/cmd/query/app/flags_test.go +++ b/cmd/query/app/flags_test.go @@ -86,17 +86,21 @@ func TestStringSliceAsHeader(t *testing.T) { require.NoError(t, err) } -func fakeInitializerFn(*zap.Logger) (spanstore.Reader, spanstore.Writer) { +func initializedFn(*zap.Logger) (spanstore.Reader, spanstore.Writer) { return &spanstoremocks.Reader{}, &spanstoremocks.Writer{} } +func uninitializedFn(*zap.Logger) (spanstore.Reader, spanstore.Writer) { + return nil, nil +} + func TestBuildQueryServiceOptions(t *testing.T) { v, _ := config.Viperize(AddFlags) qOpts, err := new(QueryOptions).InitFromViper(v, zap.NewNop()) require.NoError(t, err) assert.NotNil(t, qOpts) - qSvcOpts := qOpts.BuildQueryServiceOptions(fakeInitializerFn, zap.NewNop()) + qSvcOpts := qOpts.BuildQueryServiceOptions(initializedFn, zap.NewNop()) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) assert.NotNil(t, qSvcOpts.ArchiveSpanReader) @@ -110,7 +114,7 @@ func TestBuildQueryServiceOptions_NoArchiveStorage(t *testing.T) { assert.NotNil(t, qOpts) logger, logBuf := testutils.NewLogger() - qSvcOpts := qOpts.BuildQueryServiceOptions(fakeInitializerFn, logger) + qSvcOpts := qOpts.BuildQueryServiceOptions(uninitializedFn, logger) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) assert.Nil(t, qSvcOpts.ArchiveSpanReader) @@ -125,7 +129,7 @@ func TestBuildQueryServiceOptionsV2(t *testing.T) { require.NoError(t, err) assert.NotNil(t, qOpts) - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(fakeInitializerFn, zap.NewNop()) + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(initializedFn, zap.NewNop()) assert.NotNil(t, qSvcOpts) assert.NotNil(t, qSvcOpts.Adjuster) @@ -140,7 +144,7 @@ func TestBuildQueryServiceOptionsV2_NoArchiveStorage(t *testing.T) { assert.NotNil(t, qOpts) logger, logBuf := testutils.NewLogger() - qSvcOpts := qOpts.BuildQueryServiceOptionsV2(fakeInitializerFn, logger) + qSvcOpts := qOpts.BuildQueryServiceOptionsV2(uninitializedFn, logger) assert.Nil(t, qSvcOpts.ArchiveTraceReader) assert.Nil(t, qSvcOpts.ArchiveTraceWriter) From 8b90aebe4b1d2c91c5f65a10cf33b17404ed33d7 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 20:42:20 -0500 Subject: [PATCH 52/74] Remove Unused Types Signed-off-by: Mahad Zaryab --- plugin/storage/grpc/shared/archive.go | 81 ---------------- plugin/storage/grpc/shared/archive_test.go | 106 --------------------- 2 files changed, 187 deletions(-) delete mode 100644 plugin/storage/grpc/shared/archive.go delete mode 100644 plugin/storage/grpc/shared/archive_test.go diff --git a/plugin/storage/grpc/shared/archive.go b/plugin/storage/grpc/shared/archive.go deleted file mode 100644 index 8eeb3b609b2..00000000000 --- a/plugin/storage/grpc/shared/archive.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2020 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package shared - -import ( - "context" - "errors" - "fmt" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/jaegertracing/jaeger/model" - "github.com/jaegertracing/jaeger/proto-gen/storage_v1" - "github.com/jaegertracing/jaeger/storage/spanstore" -) - -var ( - _ spanstore.Reader = (*archiveReader)(nil) - _ spanstore.Writer = (*archiveWriter)(nil) -) - -// archiveReader wraps storage_v1.ArchiveSpanReaderPluginClient into spanstore.Reader -type archiveReader struct { - client storage_v1.ArchiveSpanReaderPluginClient -} - -// ArchiveWriter wraps storage_v1.ArchiveSpanWriterPluginClient into spanstore.Writer -type archiveWriter struct { - client storage_v1.ArchiveSpanWriterPluginClient -} - -// GetTrace takes a traceID and returns a Trace associated with that traceID from Archive Storage -func (r *archiveReader) GetTrace(ctx context.Context, q spanstore.GetTraceParameters) (*model.Trace, error) { - stream, err := r.client.GetArchiveTrace(ctx, &storage_v1.GetTraceRequest{ - TraceID: q.TraceID, - StartTime: q.StartTime, - EndTime: q.EndTime, - }) - if status.Code(err) == codes.NotFound { - return nil, spanstore.ErrTraceNotFound - } - if err != nil { - return nil, fmt.Errorf("plugin error: %w", err) - } - - return readTrace(stream) -} - -// GetServices not used in archiveReader -func (*archiveReader) GetServices(context.Context) ([]string, error) { - return nil, errors.New("GetServices not implemented") -} - -// GetOperations not used in archiveReader -func (*archiveReader) GetOperations(context.Context, spanstore.OperationQueryParameters) ([]spanstore.Operation, error) { - return nil, errors.New("GetOperations not implemented") -} - -// FindTraces not used in archiveReader -func (*archiveReader) FindTraces(context.Context, *spanstore.TraceQueryParameters) ([]*model.Trace, error) { - return nil, errors.New("FindTraces not implemented") -} - -// FindTraceIDs not used in archiveReader -func (*archiveReader) FindTraceIDs(context.Context, *spanstore.TraceQueryParameters) ([]model.TraceID, error) { - return nil, errors.New("FindTraceIDs not implemented") -} - -// WriteSpan saves the span into Archive Storage -func (w *archiveWriter) WriteSpan(ctx context.Context, span *model.Span) error { - _, err := w.client.WriteArchiveSpan(ctx, &storage_v1.WriteSpanRequest{ - Span: span, - }) - if err != nil { - return fmt.Errorf("plugin error: %w", err) - } - - return nil -} diff --git a/plugin/storage/grpc/shared/archive_test.go b/plugin/storage/grpc/shared/archive_test.go deleted file mode 100644 index 3f5128ff590..00000000000 --- a/plugin/storage/grpc/shared/archive_test.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2020 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package shared - -import ( - "context" - "io" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/jaegertracing/jaeger/model" - "github.com/jaegertracing/jaeger/proto-gen/storage_v1" - "github.com/jaegertracing/jaeger/proto-gen/storage_v1/mocks" - "github.com/jaegertracing/jaeger/storage/spanstore" -) - -func TestArchiveWriter_WriteSpan(t *testing.T) { - mockSpan := &model.Span{ - TraceID: mockTraceID, - SpanID: model.NewSpanID(1), - Process: &model.Process{}, - } - - archiveSpanWriter := new(mocks.ArchiveSpanWriterPluginClient) - archiveSpanWriter.On("WriteArchiveSpan", mock.Anything, &storage_v1.WriteSpanRequest{Span: mockSpan}). - Return(&storage_v1.WriteSpanResponse{}, nil) - writer := &archiveWriter{client: archiveSpanWriter} - - err := writer.WriteSpan(context.Background(), mockSpan) - require.NoError(t, err) -} - -func TestArchiveReader_GetTrace(t *testing.T) { - mockTraceID := model.NewTraceID(0, 123456) - mockSpan := model.Span{ - TraceID: mockTraceID, - SpanID: model.NewSpanID(1), - Process: &model.Process{}, - } - expected := &model.Trace{ - Spans: []*model.Span{&mockSpan}, - } - - traceClient := new(mocks.ArchiveSpanReaderPlugin_GetArchiveTraceClient) - traceClient.On("Recv").Return(&storage_v1.SpansResponseChunk{ - Spans: []model.Span{mockSpan}, - }, nil).Once() - traceClient.On("Recv").Return(nil, io.EOF) - - archiveSpanReader := new(mocks.ArchiveSpanReaderPluginClient) - archiveSpanReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - }).Return(traceClient, nil) - reader := &archiveReader{client: archiveSpanReader} - - trace, err := reader.GetTrace(context.Background(), spanstore.GetTraceParameters{ - TraceID: mockTraceID, - }) - require.NoError(t, err) - assert.Equal(t, expected, trace) -} - -func TestArchiveReaderGetTrace_NoTrace(t *testing.T) { - mockTraceID := model.NewTraceID(0, 123456) - - archiveSpanReader := new(mocks.ArchiveSpanReaderPluginClient) - archiveSpanReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - }).Return(nil, status.Errorf(codes.NotFound, "")) - reader := &archiveReader{client: archiveSpanReader} - - _, err := reader.GetTrace(context.Background(), spanstore.GetTraceParameters{ - TraceID: mockTraceID, - }) - assert.Equal(t, spanstore.ErrTraceNotFound, err) -} - -func TestArchiveReader_FindTraceIDs(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.FindTraceIDs(context.Background(), nil) - require.Error(t, err) -} - -func TestArchiveReader_FindTraces(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.FindTraces(context.Background(), nil) - require.Error(t, err) -} - -func TestArchiveReader_GetOperations(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.GetOperations(context.Background(), spanstore.OperationQueryParameters{}) - require.Error(t, err) -} - -func TestArchiveReader_GetServices(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.GetServices(context.Background()) - require.Error(t, err) -} From 510fc6647026d38bf67e0f3414ee695e109823c9 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 20:44:05 -0500 Subject: [PATCH 53/74] Fix nit in Test Signed-off-by: Mahad Zaryab --- plugin/storage/integration/grpc_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugin/storage/integration/grpc_test.go b/plugin/storage/integration/grpc_test.go index 52bd78b83e4..5e30e14c96c 100644 --- a/plugin/storage/integration/grpc_test.go +++ b/plugin/storage/integration/grpc_test.go @@ -33,8 +33,7 @@ func (s *GRPCStorageIntegrationTestSuite) initialize(t *testing.T) { initFactory := func() *grpc.Factory { f := grpc.NewFactory() v, command := config.Viperize(f.AddFlags) - err := command.ParseFlags(s.flags) - require.NoError(t, err) + require.NoError(t, command.ParseFlags(s.flags)) f.InitFromViper(v, logger) require.NoError(t, f.Initialize(metrics.NullFactory, logger)) return f From 6761944918331f9435fa561798250b30f6dd5b5e Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 20:56:48 -0500 Subject: [PATCH 54/74] Move Inheritance To InitFromViper Signed-off-by: Mahad Zaryab --- plugin/storage/factory.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index 466bb7dadd9..aaae0c5aa39 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -301,15 +301,23 @@ func (f *Factory) addDownsamplingFlags(flagSet *flag.FlagSet) { // InitFromViper implements plugin.Configurable func (f *Factory) InitFromViper(v *viper.Viper, logger *zap.Logger) { - initFromViper := func(factories map[string]storage.Factory) { - for _, factory := range factories { - if conf, ok := factory.(plugin.Configurable); ok { - conf.InitFromViper(v, logger) + initializeConfigurable := func(factory storage.Factory) { + if conf, ok := factory.(plugin.Configurable); ok { + conf.InitFromViper(v, logger) + } + } + for _, factory := range f.factories { + initializeConfigurable(factory) + } + for kind, factory := range f.archiveFactories { + initializeConfigurable(factory) + + if primaryFactory, ok := f.factories[kind]; ok { + if inheritable, ok := factory.(plugin.Inheritable); ok { + inheritable.InheritSettingsFrom(primaryFactory) } } } - initFromViper(f.factories) - initFromViper(f.archiveFactories) f.initDownsamplingFromViper(v) } From b7698b843f3c0156d03545c8bd2b8a67091b2dfd Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Mon, 20 Jan 2025 21:15:26 -0500 Subject: [PATCH 55/74] Change File Watcher To Be Singular Signed-off-by: Mahad Zaryab --- plugin/storage/es/factory.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index 74d3a18d568..74de8b18792 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -63,7 +63,7 @@ type Factory struct { client atomic.Pointer[es.Client] - watchers []*fswatcher.FSWatcher + pwdFileWatcher *fswatcher.FSWatcher } // NewFactory creates a new Factory. @@ -140,7 +140,7 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) if err != nil { return fmt.Errorf("failed to create watcher for ES client's password: %w", err) } - f.watchers = append(f.watchers, watcher) + f.pwdFileWatcher = watcher } if f.Options != nil && f.Options.Config.namespace == archiveNamespace { @@ -315,8 +315,8 @@ var _ io.Closer = (*Factory)(nil) func (f *Factory) Close() error { var errs []error - for _, w := range f.watchers { - errs = append(errs, w.Close()) + if f.pwdFileWatcher != nil { + errs = append(errs, f.pwdFileWatcher.Close()) } errs = append(errs, f.getClient().Close()) From 66436be863d775f356d502c147d9e55318d578bc Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Tue, 21 Jan 2025 19:55:00 -0500 Subject: [PATCH 56/74] Fix Test Signed-off-by: Mahad Zaryab --- plugin/storage/grpc/shared/grpc_handler_test.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/plugin/storage/grpc/shared/grpc_handler_test.go b/plugin/storage/grpc/shared/grpc_handler_test.go index 313c9f2f3bd..dd4f8d401bc 100644 --- a/plugin/storage/grpc/shared/grpc_handler_test.go +++ b/plugin/storage/grpc/shared/grpc_handler_test.go @@ -59,16 +59,11 @@ func withGRPCServer(fn func(r *grpcServerTest)) { depReader := new(dependencyStoreMocks.Reader) streamWriter := new(spanStoreMocks.Writer) - impl := &mockStoragePlugin{ + mockPlugin := &mockStoragePlugin{ spanReader: spanReader, spanWriter: spanWriter, depsReader: depReader, streamWriter: streamWriter, - mockPlugin := &mockStoragePlugin{ - spanReader: spanReader, - spanWriter: spanWriter, - depsReader: depReader, - streamWriter: streamWriter, } impl := &GRPCHandlerStorageImpl{ @@ -82,10 +77,10 @@ func withGRPCServer(fn func(r *grpcServerTest)) { return mockPlugin.depsReader }, ArchiveSpanReader: func() spanstore.Reader { - return mockPlugin.archiveReader + return mockPlugin.spanReader }, ArchiveSpanWriter: func() spanstore.Writer { - return mockPlugin.archiveWriter + return mockPlugin.spanWriter }, StreamingSpanWriter: func() spanstore.Writer { return mockPlugin.streamWriter From a278cadca37dc647840756acea5d2e4257f6f5fb Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Tue, 21 Jan 2025 20:05:35 -0500 Subject: [PATCH 57/74] Remove Redundant Check Signed-off-by: Mahad Zaryab --- plugin/storage/factory.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index aaae0c5aa39..6bad9a8a981 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -166,13 +166,6 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) if err := factory.Initialize(mf, logger); err != nil { return err } - if role == "archive" { - if primaryFactory, ok := f.factories[kind]; ok { - if dc, ok := factory.(plugin.Inheritable); ok { - dc.InheritSettingsFrom(primaryFactory) - } - } - } } return nil } From 2ec0c9ae1fe17638942a27978d00da94b6ed42c2 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Tue, 21 Jan 2025 20:24:37 -0500 Subject: [PATCH 58/74] Fix Flaky Unit Test Signed-off-by: Mahad Zaryab --- plugin/storage/factory_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/storage/factory_test.go b/plugin/storage/factory_test.go index 89f435f7698..5d8f3988275 100644 --- a/plugin/storage/factory_test.go +++ b/plugin/storage/factory_test.go @@ -186,7 +186,9 @@ func TestCreateMulti(t *testing.T) { mock := new(mocks.Factory) mock2 := new(mocks.Factory) f.factories[cassandraStorageType] = mock + f.archiveFactories[cassandraStorageType] = mock f.factories[elasticsearchStorageType] = mock2 + f.archiveFactories[elasticsearchStorageType] = mock2 spanWriter := new(spanStoreMocks.Writer) spanWriter2 := new(spanStoreMocks.Writer) From 0675e7a2adc9f09b8a52cfc1c08ef2c254e36c25 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Tue, 21 Jan 2025 20:39:04 -0500 Subject: [PATCH 59/74] Add Test For Inheritable Signed-off-by: Mahad Zaryab --- plugin/storage/factory_test.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/plugin/storage/factory_test.go b/plugin/storage/factory_test.go index 5d8f3988275..59aea4c3738 100644 --- a/plugin/storage/factory_test.go +++ b/plugin/storage/factory_test.go @@ -8,6 +8,7 @@ import ( "errors" "expvar" "flag" + "fmt" "io" "reflect" "strings" @@ -315,6 +316,36 @@ func TestConfigurable(t *testing.T) { assert.Equal(t, v, mock.viper) } +type inheritable struct { + mocks.Factory + calledWith storage.Factory +} + +func (i *inheritable) InheritSettingsFrom(other storage.Factory) { + fmt.Println("here") + i.calledWith = other +} + +func TestInheritable(t *testing.T) { + f, err := NewFactory(defaultCfg()) + require.NoError(t, err) + assert.NotEmpty(t, f.factories) + assert.NotEmpty(t, f.factories[cassandraStorageType]) + assert.NotEmpty(t, f.archiveFactories[cassandraStorageType]) + + mockInheritable := new(inheritable) + f.factories[cassandraStorageType] = &mocks.Factory{} + f.archiveFactories[cassandraStorageType] = mockInheritable + + fs := new(flag.FlagSet) + v := viper.New() + + f.AddFlags(fs) + f.InitFromViper(v, zap.NewNop()) + + assert.Equal(t, f.factories[cassandraStorageType], mockInheritable.calledWith) +} + func TestParsingDownsamplingRatio(t *testing.T) { f := Factory{} v, command := config.Viperize(f.AddPipelineFlags) From c4a67a0e55ba33501726c2ec1e247503d3c9bfca Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Wed, 22 Jan 2025 22:06:24 -0500 Subject: [PATCH 60/74] Separate Primary And Archive For GRPC Remote Storage Signed-off-by: Mahad Zaryab --- cmd/jaeger/config-remote-storage.yaml | 6 +++ cmd/jaeger/internal/integration/grpc_test.go | 8 +++- plugin/storage/factory.go | 2 + plugin/storage/grpc/factory.go | 26 ++++++++----- plugin/storage/grpc/factory_test.go | 6 +-- plugin/storage/grpc/options.go | 38 +++++++++++++------ plugin/storage/grpc/options_test.go | 18 +++++---- plugin/storage/integration/grpc_test.go | 31 +++++++++------ .../integration/remote_memory_storage.go | 4 +- 9 files changed, 93 insertions(+), 46 deletions(-) diff --git a/cmd/jaeger/config-remote-storage.yaml b/cmd/jaeger/config-remote-storage.yaml index 655703b2034..966812aaffb 100644 --- a/cmd/jaeger/config-remote-storage.yaml +++ b/cmd/jaeger/config-remote-storage.yaml @@ -24,6 +24,7 @@ extensions: jaeger_query: storage: traces: some-storage + traces_archive: another-storage ui: config_file: ./cmd/jaeger/config-ui.json @@ -34,6 +35,11 @@ extensions: endpoint: localhost:17271 tls: insecure: true + another-storage: + grpc: + endpoint: localhost:17272 + tls: + insecure: true receivers: otlp: diff --git a/cmd/jaeger/internal/integration/grpc_test.go b/cmd/jaeger/internal/integration/grpc_test.go index cd12984bc62..ad56dc08745 100644 --- a/cmd/jaeger/internal/integration/grpc_test.go +++ b/cmd/jaeger/internal/integration/grpc_test.go @@ -7,20 +7,24 @@ import ( "testing" "github.com/jaegertracing/jaeger/plugin/storage/integration" + "github.com/jaegertracing/jaeger/ports" ) type GRPCStorageIntegration struct { E2EStorageIntegration - remoteStorage *integration.RemoteMemoryStorage + remoteStorage *integration.RemoteMemoryStorage + archiveRemoteStorage *integration.RemoteMemoryStorage } func (s *GRPCStorageIntegration) initialize(t *testing.T) { - s.remoteStorage = integration.StartNewRemoteMemoryStorage(t) + s.remoteStorage = integration.StartNewRemoteMemoryStorage(t, ports.RemoteStorageGRPC) + s.remoteStorage = integration.StartNewRemoteMemoryStorage(t, ports.RemoteStorageGRPC+1) } func (s *GRPCStorageIntegration) cleanUp(t *testing.T) { s.remoteStorage.Close(t) + s.archiveRemoteStorage.Close(t) s.initialize(t) } diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index 6bad9a8a981..901d3263449 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -146,6 +146,8 @@ func (*Factory) getArchiveFactoryOfType(factoryType string) (storage.Factory, er return cassandra.NewArchiveFactory(), nil case elasticsearchStorageType, opensearchStorageType: return es.NewArchiveFactory(), nil + case grpcStorageType: + return grpc.NewArchiveFactory(), nil default: return nil, fmt.Errorf("archive storage factory not available for %s", factoryType) } diff --git a/plugin/storage/grpc/factory.go b/plugin/storage/grpc/factory.go index 7e4fb5bf6b1..3af5d452f83 100644 --- a/plugin/storage/grpc/factory.go +++ b/plugin/storage/grpc/factory.go @@ -41,7 +41,7 @@ var ( // interface comformance checks // Factory implements storage.Factory and creates storage components backed by a storage plugin. type Factory struct { - config Config + options *options telset telemetry.Settings services *ClientPluginServices tracedRemoteConn *grpc.ClientConn @@ -51,7 +51,15 @@ type Factory struct { // NewFactory creates a new Factory. func NewFactory() *Factory { return &Factory{ - telset: telemetry.NoopSettings(), + options: newOptions(remotePrefix), + telset: telemetry.NoopSettings(), + } +} + +func NewArchiveFactory() *Factory { + return &Factory{ + options: newOptions(archiveRemotePrefix), + telset: telemetry.NoopSettings(), } } @@ -61,7 +69,7 @@ func NewFactoryWithConfig( telset telemetry.Settings, ) (*Factory, error) { f := NewFactory() - f.config = cfg + f.options.Config = cfg f.telset = telset if err := f.Initialize(telset.Metrics, telset.Logger); err != nil { return nil, err @@ -70,13 +78,13 @@ func NewFactoryWithConfig( } // AddFlags implements plugin.Configurable -func (*Factory) AddFlags(flagSet *flag.FlagSet) { - addFlags(flagSet) +func (f *Factory) AddFlags(flagSet *flag.FlagSet) { + f.options.addFlags(flagSet) } // InitFromViper implements plugin.Configurable func (f *Factory) InitFromViper(v *viper.Viper, logger *zap.Logger) { - if err := initFromViper(&f.config, v); err != nil { + if err := f.options.initFromViper(&f.options.Config, v); err != nil { logger.Fatal("unable to initialize gRPC storage factory", zap.Error(err)) } } @@ -94,7 +102,7 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) for _, opt := range opts { clientOpts = append(clientOpts, configgrpc.WithGrpcDialOption(opt)) } - return f.config.ToClientConn(context.Background(), f.telset.Host, telset, clientOpts...) + return f.options.Config.ToClientConn(context.Background(), f.telset.Host, telset, clientOpts...) } var err error @@ -102,7 +110,7 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) if err != nil { return fmt.Errorf("grpc storage builder failed to create a store: %w", err) } - logger.Info("Remote storage configuration", zap.Any("configuration", f.config)) + logger.Info("Remote storage configuration", zap.Any("configuration", f.options.Config)) return nil } @@ -113,7 +121,7 @@ func (f *Factory) newRemoteStorage( untracedTelset component.TelemetrySettings, newClient newClientFn, ) (*ClientPluginServices, error) { - c := f.config + c := f.options.Config if c.Auth != nil { return nil, errors.New("authenticator is not supported") } diff --git a/plugin/storage/grpc/factory_test.go b/plugin/storage/grpc/factory_test.go index 4f24d5dcde1..1578fddf3c7 100644 --- a/plugin/storage/grpc/factory_test.go +++ b/plugin/storage/grpc/factory_test.go @@ -83,7 +83,7 @@ func makeMockServices() *ClientPluginServices { func makeFactory(t *testing.T) *Factory { f := NewFactory() f.InitFromViper(viper.New(), zap.NewNop()) - f.config.ClientConfig.Endpoint = ":0" + f.options.ClientConfig.Endpoint = ":0" require.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) t.Cleanup(func() { @@ -110,7 +110,7 @@ func TestNewFactoryError(t *testing.T) { t.Run("viper", func(t *testing.T) { f := NewFactory() f.InitFromViper(viper.New(), zap.NewNop()) - f.config = *cfg + f.options.Config = *cfg err := f.Initialize(metrics.NullFactory, zap.NewNop()) assert.ErrorContains(t, err, "authenticator") }) @@ -235,7 +235,7 @@ func TestWithCLIFlags(t *testing.T) { }) require.NoError(t, err) f.InitFromViper(v, zap.NewNop()) - assert.Equal(t, "foo:1234", f.config.ClientConfig.Endpoint) + assert.Equal(t, "foo:1234", f.options.Config.ClientConfig.Endpoint) require.NoError(t, f.Close()) } diff --git a/plugin/storage/grpc/options.go b/plugin/storage/grpc/options.go index 3461cfc28a4..eb8d7ccd03d 100644 --- a/plugin/storage/grpc/options.go +++ b/plugin/storage/grpc/options.go @@ -16,33 +16,47 @@ import ( const ( remotePrefix = "grpc-storage" - remoteServer = remotePrefix + ".server" - remoteConnectionTimeout = remotePrefix + ".connection-timeout" + archiveRemotePrefix = "grpc-storage-archive" + remoteServer = ".server" + remoteConnectionTimeout = ".connection-timeout" defaultConnectionTimeout = time.Duration(5 * time.Second) ) -func tlsFlagsConfig() tlscfg.ClientFlagsConfig { +type options struct { + Config + namespace string +} + +func newOptions(namespace string) *options { + options := &options{ + Config: DefaultConfig(), + namespace: namespace, + } + return options +} + +func (opts *options) tlsFlagsConfig() tlscfg.ClientFlagsConfig { return tlscfg.ClientFlagsConfig{ - Prefix: remotePrefix, + Prefix: opts.namespace, } } // addFlags adds flags for Options -func addFlags(flagSet *flag.FlagSet) { - tlsFlagsConfig().AddFlags(flagSet) +func (opts *options) addFlags(flagSet *flag.FlagSet) { + opts.tlsFlagsConfig().AddFlags(flagSet) - flagSet.String(remoteServer, "", "The remote storage gRPC server address as host:port") - flagSet.Duration(remoteConnectionTimeout, defaultConnectionTimeout, "The remote storage gRPC server connection timeout") + flagSet.String(opts.namespace+remoteServer, "", "The remote storage gRPC server address as host:port") + flagSet.Duration(opts.namespace+remoteConnectionTimeout, defaultConnectionTimeout, "The remote storage gRPC server connection timeout") } -func initFromViper(cfg *Config, v *viper.Viper) error { - cfg.ClientConfig.Endpoint = v.GetString(remoteServer) - remoteTLSCfg, err := tlsFlagsConfig().InitFromViper(v) +func (opts *options) initFromViper(cfg *Config, v *viper.Viper) error { + cfg.ClientConfig.Endpoint = v.GetString(opts.namespace + remoteServer) + remoteTLSCfg, err := opts.tlsFlagsConfig().InitFromViper(v) if err != nil { return fmt.Errorf("failed to parse gRPC storage TLS options: %w", err) } cfg.ClientConfig.TLSSetting = remoteTLSCfg - cfg.TimeoutConfig.Timeout = v.GetDuration(remoteConnectionTimeout) + cfg.TimeoutConfig.Timeout = v.GetDuration(opts.namespace + remoteConnectionTimeout) cfg.Tenancy = tenancy.InitFromViper(v) return nil } diff --git a/plugin/storage/grpc/options_test.go b/plugin/storage/grpc/options_test.go index a3e8953f098..dc715e4119f 100644 --- a/plugin/storage/grpc/options_test.go +++ b/plugin/storage/grpc/options_test.go @@ -18,14 +18,15 @@ import ( ) func TestOptionsWithFlags(t *testing.T) { - v, command := config.Viperize(addFlags, tenancy.AddFlags) + opts := newOptions("grpc-storage") + v, command := config.Viperize(opts.addFlags, tenancy.AddFlags) err := command.ParseFlags([]string{ "--grpc-storage.server=foo:12345", "--multi-tenancy.header=x-scope-orgid", }) require.NoError(t, err) var cfg Config - require.NoError(t, initFromViper(&cfg, v)) + require.NoError(t, opts.initFromViper(&cfg, v)) assert.Equal(t, "foo:12345", cfg.ClientConfig.Endpoint) assert.False(t, cfg.Tenancy.Enabled) @@ -33,7 +34,8 @@ func TestOptionsWithFlags(t *testing.T) { } func TestRemoteOptionsWithFlags(t *testing.T) { - v, command := config.Viperize(addFlags) + opts := newOptions("grpc-storage") + v, command := config.Viperize(opts.addFlags) err := command.ParseFlags([]string{ "--grpc-storage.server=localhost:2001", "--grpc-storage.tls.enabled=true", @@ -41,7 +43,7 @@ func TestRemoteOptionsWithFlags(t *testing.T) { }) require.NoError(t, err) var cfg Config - require.NoError(t, initFromViper(&cfg, v)) + require.NoError(t, opts.initFromViper(&cfg, v)) assert.Equal(t, "localhost:2001", cfg.ClientConfig.Endpoint) assert.False(t, cfg.ClientConfig.TLSSetting.Insecure) @@ -49,7 +51,8 @@ func TestRemoteOptionsWithFlags(t *testing.T) { } func TestRemoteOptionsNoTLSWithFlags(t *testing.T) { - v, command := config.Viperize(addFlags) + opts := newOptions("grpc-storage") + v, command := config.Viperize(opts.addFlags) err := command.ParseFlags([]string{ "--grpc-storage.server=localhost:2001", "--grpc-storage.tls.enabled=false", @@ -57,7 +60,7 @@ func TestRemoteOptionsNoTLSWithFlags(t *testing.T) { }) require.NoError(t, err) var cfg Config - require.NoError(t, initFromViper(&cfg, v)) + require.NoError(t, opts.initFromViper(&cfg, v)) assert.Equal(t, "localhost:2001", cfg.ClientConfig.Endpoint) assert.True(t, cfg.ClientConfig.TLSSetting.Insecure) @@ -65,7 +68,8 @@ func TestRemoteOptionsNoTLSWithFlags(t *testing.T) { } func TestFailedTLSFlags(t *testing.T) { - v, command := config.Viperize(addFlags) + opts := newOptions("grpc-storage") + v, command := config.Viperize(opts.addFlags) err := command.ParseFlags([]string{ "--grpc-storage.tls.enabled=false", "--grpc-storage.tls.cert=blah", // invalid unless tls.enabled=true diff --git a/plugin/storage/integration/grpc_test.go b/plugin/storage/integration/grpc_test.go index 5e30e14c96c..cf46a5371c8 100644 --- a/plugin/storage/integration/grpc_test.go +++ b/plugin/storage/integration/grpc_test.go @@ -15,31 +15,35 @@ import ( "github.com/jaegertracing/jaeger/pkg/metrics" "github.com/jaegertracing/jaeger/pkg/testutils" "github.com/jaegertracing/jaeger/plugin/storage/grpc" + "github.com/jaegertracing/jaeger/ports" "github.com/jaegertracing/jaeger/storage_v2/v1adapter" ) type GRPCStorageIntegrationTestSuite struct { StorageIntegration - flags []string - factory *grpc.Factory - archiveFactory *grpc.Factory - remoteStorage *RemoteMemoryStorage + flags []string + archiveFlags []string + factory *grpc.Factory + archiveFactory *grpc.Factory + remoteStorage *RemoteMemoryStorage + archiveRemoteStorage *RemoteMemoryStorage } func (s *GRPCStorageIntegrationTestSuite) initialize(t *testing.T) { logger := zaptest.NewLogger(t, zaptest.WrapOptions(zap.AddCaller())) - s.remoteStorage = StartNewRemoteMemoryStorage(t) + s.remoteStorage = StartNewRemoteMemoryStorage(t, ports.RemoteStorageGRPC) + s.archiveRemoteStorage = StartNewRemoteMemoryStorage(t, ports.RemoteStorageGRPC+1) - initFactory := func() *grpc.Factory { - f := grpc.NewFactory() + initFactory := func(f *grpc.Factory, flags []string) { v, command := config.Viperize(f.AddFlags) - require.NoError(t, command.ParseFlags(s.flags)) + require.NoError(t, command.ParseFlags(flags)) f.InitFromViper(v, logger) require.NoError(t, f.Initialize(metrics.NullFactory, logger)) - return f } - f := initFactory() - af := initFactory() + f := grpc.NewFactory() + af := grpc.NewArchiveFactory() + initFactory(f, s.flags) + initFactory(af, s.archiveFlags) s.factory = f s.archiveFactory = af @@ -63,6 +67,7 @@ func (s *GRPCStorageIntegrationTestSuite) close(t *testing.T) { require.NoError(t, s.factory.Close()) require.NoError(t, s.archiveFactory.Close()) s.remoteStorage.Close(t) + s.archiveRemoteStorage.Close(t) } func (s *GRPCStorageIntegrationTestSuite) cleanUp(t *testing.T) { @@ -80,6 +85,10 @@ func TestGRPCRemoteStorage(t *testing.T) { "--grpc-storage.server=localhost:17271", "--grpc-storage.tls.enabled=false", }, + archiveFlags: []string{ + "--grpc-storage-archive.server=localhost:17272", + "--grpc-storage-archive.tls.enabled=false", + }, } s.initialize(t) defer s.close(t) diff --git a/plugin/storage/integration/remote_memory_storage.go b/plugin/storage/integration/remote_memory_storage.go index 8e72fadf47c..d569abbc65f 100644 --- a/plugin/storage/integration/remote_memory_storage.go +++ b/plugin/storage/integration/remote_memory_storage.go @@ -33,12 +33,12 @@ type RemoteMemoryStorage struct { storageFactory *storage.Factory } -func StartNewRemoteMemoryStorage(t *testing.T) *RemoteMemoryStorage { +func StartNewRemoteMemoryStorage(t *testing.T, port int) *RemoteMemoryStorage { logger := zaptest.NewLogger(t, zaptest.WrapOptions(zap.AddCaller())) opts := &app.Options{ ServerConfig: configgrpc.ServerConfig{ NetAddr: confignet.AddrConfig{ - Endpoint: ports.PortToHostPort(ports.RemoteStorageGRPC), + Endpoint: ports.PortToHostPort(port), }, }, Tenancy: tenancy.Options{ From 3afcdb5478ea05327bdffdd7b3c95d98c431cb02 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Wed, 22 Jan 2025 22:15:16 -0500 Subject: [PATCH 61/74] Fix Typo Signed-off-by: Mahad Zaryab --- cmd/jaeger/internal/integration/grpc_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/jaeger/internal/integration/grpc_test.go b/cmd/jaeger/internal/integration/grpc_test.go index ad56dc08745..9f5990016da 100644 --- a/cmd/jaeger/internal/integration/grpc_test.go +++ b/cmd/jaeger/internal/integration/grpc_test.go @@ -19,7 +19,7 @@ type GRPCStorageIntegration struct { func (s *GRPCStorageIntegration) initialize(t *testing.T) { s.remoteStorage = integration.StartNewRemoteMemoryStorage(t, ports.RemoteStorageGRPC) - s.remoteStorage = integration.StartNewRemoteMemoryStorage(t, ports.RemoteStorageGRPC+1) + s.archiveRemoteStorage = integration.StartNewRemoteMemoryStorage(t, ports.RemoteStorageGRPC+1) } func (s *GRPCStorageIntegration) cleanUp(t *testing.T) { From 9c4c5736dd1990bcabbcff46633ee4e5af653b8d Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Wed, 22 Jan 2025 22:27:30 -0500 Subject: [PATCH 62/74] Add Missing Cleanup Call Signed-off-by: Mahad Zaryab --- cmd/jaeger/internal/integration/grpc_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/jaeger/internal/integration/grpc_test.go b/cmd/jaeger/internal/integration/grpc_test.go index 9f5990016da..a3579f350e6 100644 --- a/cmd/jaeger/internal/integration/grpc_test.go +++ b/cmd/jaeger/internal/integration/grpc_test.go @@ -41,6 +41,7 @@ func TestGRPCStorage(t *testing.T) { s.e2eInitialize(t, "grpc") t.Cleanup(func() { s.remoteStorage.Close(t) + s.archiveRemoteStorage.Close(t) }) s.RunSpanStoreTests(t) } From 89ba32d3c485076621739b3c62c5c2a077ef60c6 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Thu, 23 Jan 2025 18:33:38 -0500 Subject: [PATCH 63/74] Add ArchiveCapable Interface To Initialize Correctly Signed-off-by: Mahad Zaryab --- plugin/configurable.go | 4 +++ plugin/storage/cassandra/factory.go | 5 ++++ plugin/storage/es/factory.go | 15 ++++++---- plugin/storage/es/options.go | 2 +- plugin/storage/factory.go | 45 +++++++++++++++++------------ 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/plugin/configurable.go b/plugin/configurable.go index a1e011d855b..4be32bf76da 100644 --- a/plugin/configurable.go +++ b/plugin/configurable.go @@ -28,3 +28,7 @@ type Configurable interface { type Inheritable interface { InheritSettingsFrom(other storage.Factory) } + +type ArchiveCapable interface { + IsArchiveCapable() bool +} diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 2a8fc48b310..8abf5604894 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -47,6 +47,7 @@ var ( // interface comformance checks _ io.Closer = (*Factory)(nil) _ plugin.Configurable = (*Factory)(nil) _ plugin.Inheritable = (*Factory)(nil) + _ plugin.ArchiveCapable = (*Factory)(nil) ) // Factory implements storage.Factory for Cassandra backend. @@ -289,3 +290,7 @@ func (f *Factory) InheritSettingsFrom(other storage.Factory) { f.config.ApplyDefaults(&otherFactory.config) } } + +func (f *Factory) IsArchiveCapable() bool { + return f.Options.NamespaceConfig.namespace == archiveStorageNamespace && f.Options.Enabled +} diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index 74de8b18792..b83146c474a 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -42,11 +42,12 @@ const ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) - _ plugin.Inheritable = (*Factory)(nil) - _ storage.Purger = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ plugin.Inheritable = (*Factory)(nil) + _ storage.Purger = (*Factory)(nil) + _ plugin.ArchiveCapable = (*Factory)(nil) ) // Factory implements storage.Factory for Elasticsearch backend. @@ -369,3 +370,7 @@ func (f *Factory) InheritSettingsFrom(other storage.Factory) { f.config.ApplyDefaults(otherFactory.config) } } + +func (f *Factory) IsArchiveCapable() bool { + return f.Options.Config.namespace == archiveNamespace && f.config.Enabled +} diff --git a/plugin/storage/es/options.go b/plugin/storage/es/options.go index 8c604863372..264bf3393fa 100644 --- a/plugin/storage/es/options.go +++ b/plugin/storage/es/options.go @@ -275,7 +275,7 @@ func addFlags(flagSet *flag.FlagSet, nsConfig *namespaceConfig) { if nsConfig.namespace == archiveNamespace { flagSet.Bool( nsConfig.namespace+suffixEnabled, - nsConfig.Enabled, + false, "Enable extra storage") } else { // MaxSpanAge is only relevant when searching for unarchived traces. diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index 901d3263449..d3ec46e44d5 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -153,30 +153,39 @@ func (*Factory) getArchiveFactoryOfType(factoryType string) (storage.Factory, er } } -// Initialize implements storage.Factory. func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) error { f.metricsFactory = metricsFactory - initializeFactories := func(factories map[string]storage.Factory, role string) error { - for kind, factory := range factories { - mf := metricsFactory.Namespace(metrics.NSOptions{ - Name: "storage", - Tags: map[string]string{ - "kind": kind, - "role": role, - }, - }) - if err := factory.Initialize(mf, logger); err != nil { - return err - } + + initializeFactory := func(kind string, factory storage.Factory, role string) error { + mf := metricsFactory.Namespace(metrics.NSOptions{ + Name: "storage", + Tags: map[string]string{ + "kind": kind, + "role": role, + }, + }) + return factory.Initialize(mf, logger) + } + + for kind, factory := range f.factories { + if err := initializeFactory(kind, factory, "primary"); err != nil { + return err } - return nil } - if err := initializeFactories(f.factories, "primary"); err != nil { - return err + + uninitializedArchiveFactories := make(map[string]struct{}) + for kind, factory := range f.archiveFactories { + if archivable, ok := factory.(plugin.ArchiveCapable); ok && archivable.IsArchiveCapable() { + if err := initializeFactory(kind, factory, "primary"); err != nil { + uninitializedArchiveFactories[kind] = struct{}{} + } + } } - if err := initializeFactories(f.archiveFactories, "archive"); err != nil { - return err + + for kind := range uninitializedArchiveFactories { + delete(f.archiveFactories, kind) } + f.publishOpts() return nil } From ba068b1fbd91336349e12d718b0caed6442827f1 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Thu, 23 Jan 2025 21:21:53 -0500 Subject: [PATCH 64/74] Add Enabled Flag For GRPC Archive Signed-off-by: Mahad Zaryab --- plugin/storage/grpc/config.go | 1 + plugin/storage/grpc/factory.go | 11 ++++++++--- plugin/storage/grpc/options.go | 10 ++++++++++ plugin/storage/integration/grpc_test.go | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/plugin/storage/grpc/config.go b/plugin/storage/grpc/config.go index 37a5d293fa2..d9150bcba33 100644 --- a/plugin/storage/grpc/config.go +++ b/plugin/storage/grpc/config.go @@ -16,6 +16,7 @@ type Config struct { Tenancy tenancy.Options `mapstructure:"multi_tenancy"` configgrpc.ClientConfig `mapstructure:",squash"` exporterhelper.TimeoutConfig `mapstructure:",squash"` + enabled bool } func DefaultConfig() Config { diff --git a/plugin/storage/grpc/factory.go b/plugin/storage/grpc/factory.go index 3af5d452f83..e24aec335d9 100644 --- a/plugin/storage/grpc/factory.go +++ b/plugin/storage/grpc/factory.go @@ -34,9 +34,10 @@ import ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ plugin.ArchiveCapable = (*Factory)(nil) ) // Factory implements storage.Factory and creates storage components backed by a storage plugin. @@ -210,3 +211,7 @@ func getTelset(logger *zap.Logger, tracerProvider trace.TracerProvider, meterPro MeterProvider: meterProvider, } } + +func (f *Factory) IsArchiveCapable() bool { + return f.options.namespace == archiveRemotePrefix && f.options.enabled +} diff --git a/plugin/storage/grpc/options.go b/plugin/storage/grpc/options.go index eb8d7ccd03d..747e4a924ea 100644 --- a/plugin/storage/grpc/options.go +++ b/plugin/storage/grpc/options.go @@ -19,6 +19,7 @@ const ( archiveRemotePrefix = "grpc-storage-archive" remoteServer = ".server" remoteConnectionTimeout = ".connection-timeout" + enabled = ".enabled" defaultConnectionTimeout = time.Duration(5 * time.Second) ) @@ -47,6 +48,12 @@ func (opts *options) addFlags(flagSet *flag.FlagSet) { flagSet.String(opts.namespace+remoteServer, "", "The remote storage gRPC server address as host:port") flagSet.Duration(opts.namespace+remoteConnectionTimeout, defaultConnectionTimeout, "The remote storage gRPC server connection timeout") + if opts.namespace == archiveRemotePrefix { + flagSet.Bool( + opts.namespace+enabled, + false, + "Enable extra storage") + } } func (opts *options) initFromViper(cfg *Config, v *viper.Viper) error { @@ -58,5 +65,8 @@ func (opts *options) initFromViper(cfg *Config, v *viper.Viper) error { cfg.ClientConfig.TLSSetting = remoteTLSCfg cfg.TimeoutConfig.Timeout = v.GetDuration(opts.namespace + remoteConnectionTimeout) cfg.Tenancy = tenancy.InitFromViper(v) + if opts.namespace == archiveRemotePrefix { + cfg.enabled = v.GetBool(opts.namespace + enabled) + } return nil } diff --git a/plugin/storage/integration/grpc_test.go b/plugin/storage/integration/grpc_test.go index cf46a5371c8..76e089b1e16 100644 --- a/plugin/storage/integration/grpc_test.go +++ b/plugin/storage/integration/grpc_test.go @@ -86,6 +86,7 @@ func TestGRPCRemoteStorage(t *testing.T) { "--grpc-storage.tls.enabled=false", }, archiveFlags: []string{ + "--grpc-storage-archive.enabled=true", "--grpc-storage-archive.server=localhost:17272", "--grpc-storage-archive.tls.enabled=false", }, From aea0e8bdd1c68202626806d846dac502bae9aa35 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Thu, 23 Jan 2025 21:34:57 -0500 Subject: [PATCH 65/74] Fix Logic Signed-off-by: Mahad Zaryab --- plugin/storage/factory.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index d3ec46e44d5..de1ed381215 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -173,19 +173,16 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) } } - uninitializedArchiveFactories := make(map[string]struct{}) for kind, factory := range f.archiveFactories { if archivable, ok := factory.(plugin.ArchiveCapable); ok && archivable.IsArchiveCapable() { - if err := initializeFactory(kind, factory, "primary"); err != nil { - uninitializedArchiveFactories[kind] = struct{}{} + if err := initializeFactory(kind, factory, "archive"); err != nil { + return err } + } else { + delete(f.archiveFactories, kind) } } - for kind := range uninitializedArchiveFactories { - delete(f.archiveFactories, kind) - } - f.publishOpts() return nil } From e73ec5ccb3e91fd45dd529aab0236fe40df91aab Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Thu, 23 Jan 2025 21:36:50 -0500 Subject: [PATCH 66/74] Remove Print Signed-off-by: Mahad Zaryab --- plugin/storage/factory_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugin/storage/factory_test.go b/plugin/storage/factory_test.go index 59aea4c3738..84fd173d0c1 100644 --- a/plugin/storage/factory_test.go +++ b/plugin/storage/factory_test.go @@ -8,7 +8,6 @@ import ( "errors" "expvar" "flag" - "fmt" "io" "reflect" "strings" @@ -322,7 +321,6 @@ type inheritable struct { } func (i *inheritable) InheritSettingsFrom(other storage.Factory) { - fmt.Println("here") i.calledWith = other } From 44d8b7855cb384b8233c45d9324f14d84a4e196c Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Thu, 23 Jan 2025 21:58:25 -0500 Subject: [PATCH 67/74] Add Test For Archive Configurable Signed-off-by: Mahad Zaryab --- plugin/storage/factory_test.go | 72 ++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/plugin/storage/factory_test.go b/plugin/storage/factory_test.go index 84fd173d0c1..a9aaa4490d3 100644 --- a/plugin/storage/factory_test.go +++ b/plugin/storage/factory_test.go @@ -344,6 +344,78 @@ func TestInheritable(t *testing.T) { assert.Equal(t, f.factories[cassandraStorageType], mockInheritable.calledWith) } +type archiveConfigurable struct { + isConfigurable bool + *mocks.Factory +} + +func (ac *archiveConfigurable) IsArchiveCapable() bool { + return ac.isConfigurable +} + +func TestArchiveConfigurable(t *testing.T) { + tests := []struct { + name string + isArchiveCapable bool + archiveInitError error + expectedError error + expectedArchiveSize int + }{ + { + name: "Archive factory initializes successfully", + isArchiveCapable: true, + archiveInitError: nil, + expectedError: nil, + expectedArchiveSize: 1, + }, + { + name: "Archive factory initialization fails", + isArchiveCapable: true, + archiveInitError: assert.AnError, + expectedError: assert.AnError, + expectedArchiveSize: 1, + }, + { + name: "Archive factory is not archive-capable", + isArchiveCapable: false, + archiveInitError: nil, + expectedError: nil, + expectedArchiveSize: 0, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + f, err := NewFactory(defaultCfg()) + require.NoError(t, err) + + primaryFactory := &mocks.Factory{} + archiveFactory := &mocks.Factory{} + archiveConfigurable := &archiveConfigurable{ + isConfigurable: test.isArchiveCapable, + Factory: archiveFactory, + } + + f.factories[cassandraStorageType] = primaryFactory + f.archiveFactories[cassandraStorageType] = archiveConfigurable + + m := metrics.NullFactory + l := zap.NewNop() + primaryFactory.On("Initialize", m, l).Return(nil).Once() + archiveFactory.On("Initialize", m, l).Return(test.archiveInitError).Once() + + err = f.Initialize(m, l) + if test.expectedError != nil { + require.ErrorIs(t, err, test.expectedError) + } else { + require.NoError(t, err) + } + + assert.Len(t, f.archiveFactories, test.expectedArchiveSize) + }) + } +} + func TestParsingDownsamplingRatio(t *testing.T) { f := Factory{} v, command := config.Viperize(f.AddPipelineFlags) From 3d0f3d35446554669049cd95887037ed9270c662 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Thu, 23 Jan 2025 22:08:19 -0500 Subject: [PATCH 68/74] Add Unit Tests For IsArchiveCapable Function Signed-off-by: Mahad Zaryab --- plugin/storage/cassandra/factory.go | 3 +- plugin/storage/cassandra/factory_test.go | 43 ++++++++++++++++++++++ plugin/storage/es/factory.go | 2 +- plugin/storage/es/factory_test.go | 45 ++++++++++++++++++++++++ plugin/storage/grpc/factory_test.go | 43 ++++++++++++++++++++++ 5 files changed, 134 insertions(+), 2 deletions(-) diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 8abf5604894..5fb990d1181 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -292,5 +292,6 @@ func (f *Factory) InheritSettingsFrom(other storage.Factory) { } func (f *Factory) IsArchiveCapable() bool { - return f.Options.NamespaceConfig.namespace == archiveStorageNamespace && f.Options.Enabled + return f.Options.NamespaceConfig.namespace == archiveStorageNamespace && + f.Options.NamespaceConfig.Enabled } diff --git a/plugin/storage/cassandra/factory_test.go b/plugin/storage/cassandra/factory_test.go index e068b0a7f3c..bc0af147e1c 100644 --- a/plugin/storage/cassandra/factory_test.go +++ b/plugin/storage/cassandra/factory_test.go @@ -305,3 +305,46 @@ func TestInheritSettingsFrom(t *testing.T) { require.Equal(t, "bar", archiveFactory.config.Schema.Keyspace) require.Equal(t, 99, archiveFactory.config.Query.MaxRetryAttempts) } + +func TestIsArchiveCapable(t *testing.T) { + tests := []struct { + name string + namespace string + enabled bool + expected bool + }{ + { + name: "archive capable", + namespace: "cassandra-archive", + enabled: true, + expected: true, + }, + { + name: "not capable", + namespace: "cassandra-archive", + enabled: false, + expected: false, + }, + { + name: "capable + wrong namespace", + namespace: "cassandra", + enabled: true, + expected: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + factory := &Factory{ + Options: &Options{ + NamespaceConfig: NamespaceConfig{ + namespace: test.namespace, + Enabled: test.enabled, + }, + }, + } + result := factory.IsArchiveCapable() + require.Equal(t, test.expected, result) + }) + } +} diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index b83146c474a..a565ff4737c 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -372,5 +372,5 @@ func (f *Factory) InheritSettingsFrom(other storage.Factory) { } func (f *Factory) IsArchiveCapable() bool { - return f.Options.Config.namespace == archiveNamespace && f.config.Enabled + return f.Options.Config.namespace == archiveNamespace && f.Options.Config.Enabled } diff --git a/plugin/storage/es/factory_test.go b/plugin/storage/es/factory_test.go index 0cf8ffa52ab..bf9f2fde3cd 100644 --- a/plugin/storage/es/factory_test.go +++ b/plugin/storage/es/factory_test.go @@ -464,3 +464,48 @@ func TestInheritSettingsFrom(t *testing.T) { require.Equal(t, "PUT", archiveFactory.config.SendGetBodyAs) require.Equal(t, 99, primaryFactory.config.MaxDocCount) } + +func TestIsArchiveCapable(t *testing.T) { + tests := []struct { + name string + namespace string + enabled bool + expected bool + }{ + { + name: "archive capable", + namespace: "es-archive", + enabled: true, + expected: true, + }, + { + name: "not capable", + namespace: "es-archive", + enabled: false, + expected: false, + }, + { + name: "capable + wrong namespace", + namespace: "es", + enabled: true, + expected: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + factory := &Factory{ + Options: &Options{ + Config: namespaceConfig{ + namespace: test.namespace, + Configuration: escfg.Configuration{ + Enabled: test.enabled, + }, + }, + }, + } + result := factory.IsArchiveCapable() + require.Equal(t, test.expected, result) + }) + } +} diff --git a/plugin/storage/grpc/factory_test.go b/plugin/storage/grpc/factory_test.go index 1578fddf3c7..89d30731e00 100644 --- a/plugin/storage/grpc/factory_test.go +++ b/plugin/storage/grpc/factory_test.go @@ -287,3 +287,46 @@ func TestStreamingSpanWriterFactory_Capabilities(t *testing.T) { err = writer.WriteSpan(context.Background(), nil) assert.ErrorContains(t, err, "I am streaming writer", "streaming writer when Capabilities return true") } + +func TestIsArchiveCapable(t *testing.T) { + tests := []struct { + name string + namespace string + enabled bool + expected bool + }{ + { + name: "archive capable", + namespace: "grpc-storage-archive", + enabled: true, + expected: true, + }, + { + name: "not capable", + namespace: "grpc-storage-archive", + enabled: false, + expected: false, + }, + { + name: "capable + wrong namespace", + namespace: "grpc-storage", + enabled: true, + expected: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + factory := &Factory{ + options: &options{ + namespace: test.namespace, + Config: Config{ + enabled: test.enabled, + }, + }, + } + result := factory.IsArchiveCapable() + require.Equal(t, test.expected, result) + }) + } +} From 48ff461df45a24d36febfabbb993c615912ce8ee Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 25 Jan 2025 11:19:40 -0500 Subject: [PATCH 69/74] Restore For Merge Conflicts Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/query_service.go | 35 ++++++- plugin/storage/grpc/shared/archive.go | 81 ++++++++++++++++ plugin/storage/grpc/shared/archive_test.go | 106 +++++++++++++++++++++ 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 plugin/storage/grpc/shared/archive.go create mode 100644 plugin/storage/grpc/shared/archive_test.go diff --git a/cmd/query/app/querysvc/query_service.go b/cmd/query/app/querysvc/query_service.go index 86731c5abc7..9492ab13f61 100644 --- a/cmd/query/app/querysvc/query_service.go +++ b/cmd/query/app/querysvc/query_service.go @@ -8,8 +8,11 @@ import ( "errors" "time" - "github.com/jaegertracing/jaeger/model" + "go.uber.org/zap" + + "github.com/jaegertracing/jaeger-idl/model/v1" "github.com/jaegertracing/jaeger/model/adjuster" + "github.com/jaegertracing/jaeger/storage" "github.com/jaegertracing/jaeger/storage/spanstore" "github.com/jaegertracing/jaeger/storage_v2/depstore" "github.com/jaegertracing/jaeger/storage_v2/tracestore" @@ -161,6 +164,36 @@ func (qs QueryService) GetCapabilities() StorageCapabilities { } } +// InitArchiveStorage tries to initialize archive storage reader/writer if storage factory supports them. +func (opts *QueryServiceOptions) InitArchiveStorage(storageFactory storage.BaseFactory, logger *zap.Logger) bool { + archiveFactory, ok := storageFactory.(storage.ArchiveFactory) + if !ok { + logger.Info("Archive storage not supported by the factory") + return false + } + reader, err := archiveFactory.CreateArchiveSpanReader() + if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { + logger.Info("Archive storage not created", zap.String("reason", err.Error())) + return false + } + if err != nil { + logger.Error("Cannot init archive storage reader", zap.Error(err)) + return false + } + writer, err := archiveFactory.CreateArchiveSpanWriter() + if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { + logger.Info("Archive storage not created", zap.String("reason", err.Error())) + return false + } + if err != nil { + logger.Error("Cannot init archive storage writer", zap.Error(err)) + return false + } + opts.ArchiveSpanReader = reader + opts.ArchiveSpanWriter = writer + return true +} + // hasArchiveStorage returns true if archive storage reader/writer are initialized. func (opts *QueryServiceOptions) hasArchiveStorage() bool { return opts.ArchiveSpanReader != nil && opts.ArchiveSpanWriter != nil diff --git a/plugin/storage/grpc/shared/archive.go b/plugin/storage/grpc/shared/archive.go new file mode 100644 index 00000000000..8776f7542b6 --- /dev/null +++ b/plugin/storage/grpc/shared/archive.go @@ -0,0 +1,81 @@ +// Copyright (c) 2020 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package shared + +import ( + "context" + "errors" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/jaegertracing/jaeger-idl/model/v1" + "github.com/jaegertracing/jaeger/proto-gen/storage_v1" + "github.com/jaegertracing/jaeger/storage/spanstore" +) + +var ( + _ spanstore.Reader = (*archiveReader)(nil) + _ spanstore.Writer = (*archiveWriter)(nil) +) + +// archiveReader wraps storage_v1.ArchiveSpanReaderPluginClient into spanstore.Reader +type archiveReader struct { + client storage_v1.ArchiveSpanReaderPluginClient +} + +// ArchiveWriter wraps storage_v1.ArchiveSpanWriterPluginClient into spanstore.Writer +type archiveWriter struct { + client storage_v1.ArchiveSpanWriterPluginClient +} + +// GetTrace takes a traceID and returns a Trace associated with that traceID from Archive Storage +func (r *archiveReader) GetTrace(ctx context.Context, q spanstore.GetTraceParameters) (*model.Trace, error) { + stream, err := r.client.GetArchiveTrace(ctx, &storage_v1.GetTraceRequest{ + TraceID: q.TraceID, + StartTime: q.StartTime, + EndTime: q.EndTime, + }) + if status.Code(err) == codes.NotFound { + return nil, spanstore.ErrTraceNotFound + } + if err != nil { + return nil, fmt.Errorf("plugin error: %w", err) + } + + return readTrace(stream) +} + +// GetServices not used in archiveReader +func (*archiveReader) GetServices(context.Context) ([]string, error) { + return nil, errors.New("GetServices not implemented") +} + +// GetOperations not used in archiveReader +func (*archiveReader) GetOperations(context.Context, spanstore.OperationQueryParameters) ([]spanstore.Operation, error) { + return nil, errors.New("GetOperations not implemented") +} + +// FindTraces not used in archiveReader +func (*archiveReader) FindTraces(context.Context, *spanstore.TraceQueryParameters) ([]*model.Trace, error) { + return nil, errors.New("FindTraces not implemented") +} + +// FindTraceIDs not used in archiveReader +func (*archiveReader) FindTraceIDs(context.Context, *spanstore.TraceQueryParameters) ([]model.TraceID, error) { + return nil, errors.New("FindTraceIDs not implemented") +} + +// WriteSpan saves the span into Archive Storage +func (w *archiveWriter) WriteSpan(ctx context.Context, span *model.Span) error { + _, err := w.client.WriteArchiveSpan(ctx, &storage_v1.WriteSpanRequest{ + Span: span, + }) + if err != nil { + return fmt.Errorf("plugin error: %w", err) + } + + return nil +} diff --git a/plugin/storage/grpc/shared/archive_test.go b/plugin/storage/grpc/shared/archive_test.go new file mode 100644 index 00000000000..100d4b9ba26 --- /dev/null +++ b/plugin/storage/grpc/shared/archive_test.go @@ -0,0 +1,106 @@ +// Copyright (c) 2020 The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 + +package shared + +import ( + "context" + "io" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/jaegertracing/jaeger-idl/model/v1" + "github.com/jaegertracing/jaeger/proto-gen/storage_v1" + "github.com/jaegertracing/jaeger/proto-gen/storage_v1/mocks" + "github.com/jaegertracing/jaeger/storage/spanstore" +) + +func TestArchiveWriter_WriteSpan(t *testing.T) { + mockSpan := &model.Span{ + TraceID: mockTraceID, + SpanID: model.NewSpanID(1), + Process: &model.Process{}, + } + + archiveSpanWriter := new(mocks.ArchiveSpanWriterPluginClient) + archiveSpanWriter.On("WriteArchiveSpan", mock.Anything, &storage_v1.WriteSpanRequest{Span: mockSpan}). + Return(&storage_v1.WriteSpanResponse{}, nil) + writer := &archiveWriter{client: archiveSpanWriter} + + err := writer.WriteSpan(context.Background(), mockSpan) + require.NoError(t, err) +} + +func TestArchiveReader_GetTrace(t *testing.T) { + mockTraceID := model.NewTraceID(0, 123456) + mockSpan := model.Span{ + TraceID: mockTraceID, + SpanID: model.NewSpanID(1), + Process: &model.Process{}, + } + expected := &model.Trace{ + Spans: []*model.Span{&mockSpan}, + } + + traceClient := new(mocks.ArchiveSpanReaderPlugin_GetArchiveTraceClient) + traceClient.On("Recv").Return(&storage_v1.SpansResponseChunk{ + Spans: []model.Span{mockSpan}, + }, nil).Once() + traceClient.On("Recv").Return(nil, io.EOF) + + archiveSpanReader := new(mocks.ArchiveSpanReaderPluginClient) + archiveSpanReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ + TraceID: mockTraceID, + }).Return(traceClient, nil) + reader := &archiveReader{client: archiveSpanReader} + + trace, err := reader.GetTrace(context.Background(), spanstore.GetTraceParameters{ + TraceID: mockTraceID, + }) + require.NoError(t, err) + assert.Equal(t, expected, trace) +} + +func TestArchiveReaderGetTrace_NoTrace(t *testing.T) { + mockTraceID := model.NewTraceID(0, 123456) + + archiveSpanReader := new(mocks.ArchiveSpanReaderPluginClient) + archiveSpanReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ + TraceID: mockTraceID, + }).Return(nil, status.Errorf(codes.NotFound, "")) + reader := &archiveReader{client: archiveSpanReader} + + _, err := reader.GetTrace(context.Background(), spanstore.GetTraceParameters{ + TraceID: mockTraceID, + }) + assert.Equal(t, spanstore.ErrTraceNotFound, err) +} + +func TestArchiveReader_FindTraceIDs(t *testing.T) { + reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} + _, err := reader.FindTraceIDs(context.Background(), nil) + require.Error(t, err) +} + +func TestArchiveReader_FindTraces(t *testing.T) { + reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} + _, err := reader.FindTraces(context.Background(), nil) + require.Error(t, err) +} + +func TestArchiveReader_GetOperations(t *testing.T) { + reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} + _, err := reader.GetOperations(context.Background(), spanstore.OperationQueryParameters{}) + require.Error(t, err) +} + +func TestArchiveReader_GetServices(t *testing.T) { + reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} + _, err := reader.GetServices(context.Background()) + require.Error(t, err) +} From 21ecf5b70a885b7f005211ce7a807b7afb6bcb5a Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 25 Jan 2025 11:21:11 -0500 Subject: [PATCH 70/74] Restore Back Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/query_service.go | 35 +------ plugin/storage/grpc/shared/archive.go | 81 ---------------- plugin/storage/grpc/shared/archive_test.go | 106 --------------------- 3 files changed, 1 insertion(+), 221 deletions(-) delete mode 100644 plugin/storage/grpc/shared/archive.go delete mode 100644 plugin/storage/grpc/shared/archive_test.go diff --git a/cmd/query/app/querysvc/query_service.go b/cmd/query/app/querysvc/query_service.go index 9492ab13f61..86731c5abc7 100644 --- a/cmd/query/app/querysvc/query_service.go +++ b/cmd/query/app/querysvc/query_service.go @@ -8,11 +8,8 @@ import ( "errors" "time" - "go.uber.org/zap" - - "github.com/jaegertracing/jaeger-idl/model/v1" + "github.com/jaegertracing/jaeger/model" "github.com/jaegertracing/jaeger/model/adjuster" - "github.com/jaegertracing/jaeger/storage" "github.com/jaegertracing/jaeger/storage/spanstore" "github.com/jaegertracing/jaeger/storage_v2/depstore" "github.com/jaegertracing/jaeger/storage_v2/tracestore" @@ -164,36 +161,6 @@ func (qs QueryService) GetCapabilities() StorageCapabilities { } } -// InitArchiveStorage tries to initialize archive storage reader/writer if storage factory supports them. -func (opts *QueryServiceOptions) InitArchiveStorage(storageFactory storage.BaseFactory, logger *zap.Logger) bool { - archiveFactory, ok := storageFactory.(storage.ArchiveFactory) - if !ok { - logger.Info("Archive storage not supported by the factory") - return false - } - reader, err := archiveFactory.CreateArchiveSpanReader() - if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { - logger.Info("Archive storage not created", zap.String("reason", err.Error())) - return false - } - if err != nil { - logger.Error("Cannot init archive storage reader", zap.Error(err)) - return false - } - writer, err := archiveFactory.CreateArchiveSpanWriter() - if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { - logger.Info("Archive storage not created", zap.String("reason", err.Error())) - return false - } - if err != nil { - logger.Error("Cannot init archive storage writer", zap.Error(err)) - return false - } - opts.ArchiveSpanReader = reader - opts.ArchiveSpanWriter = writer - return true -} - // hasArchiveStorage returns true if archive storage reader/writer are initialized. func (opts *QueryServiceOptions) hasArchiveStorage() bool { return opts.ArchiveSpanReader != nil && opts.ArchiveSpanWriter != nil diff --git a/plugin/storage/grpc/shared/archive.go b/plugin/storage/grpc/shared/archive.go deleted file mode 100644 index 8776f7542b6..00000000000 --- a/plugin/storage/grpc/shared/archive.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2020 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package shared - -import ( - "context" - "errors" - "fmt" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/jaegertracing/jaeger-idl/model/v1" - "github.com/jaegertracing/jaeger/proto-gen/storage_v1" - "github.com/jaegertracing/jaeger/storage/spanstore" -) - -var ( - _ spanstore.Reader = (*archiveReader)(nil) - _ spanstore.Writer = (*archiveWriter)(nil) -) - -// archiveReader wraps storage_v1.ArchiveSpanReaderPluginClient into spanstore.Reader -type archiveReader struct { - client storage_v1.ArchiveSpanReaderPluginClient -} - -// ArchiveWriter wraps storage_v1.ArchiveSpanWriterPluginClient into spanstore.Writer -type archiveWriter struct { - client storage_v1.ArchiveSpanWriterPluginClient -} - -// GetTrace takes a traceID and returns a Trace associated with that traceID from Archive Storage -func (r *archiveReader) GetTrace(ctx context.Context, q spanstore.GetTraceParameters) (*model.Trace, error) { - stream, err := r.client.GetArchiveTrace(ctx, &storage_v1.GetTraceRequest{ - TraceID: q.TraceID, - StartTime: q.StartTime, - EndTime: q.EndTime, - }) - if status.Code(err) == codes.NotFound { - return nil, spanstore.ErrTraceNotFound - } - if err != nil { - return nil, fmt.Errorf("plugin error: %w", err) - } - - return readTrace(stream) -} - -// GetServices not used in archiveReader -func (*archiveReader) GetServices(context.Context) ([]string, error) { - return nil, errors.New("GetServices not implemented") -} - -// GetOperations not used in archiveReader -func (*archiveReader) GetOperations(context.Context, spanstore.OperationQueryParameters) ([]spanstore.Operation, error) { - return nil, errors.New("GetOperations not implemented") -} - -// FindTraces not used in archiveReader -func (*archiveReader) FindTraces(context.Context, *spanstore.TraceQueryParameters) ([]*model.Trace, error) { - return nil, errors.New("FindTraces not implemented") -} - -// FindTraceIDs not used in archiveReader -func (*archiveReader) FindTraceIDs(context.Context, *spanstore.TraceQueryParameters) ([]model.TraceID, error) { - return nil, errors.New("FindTraceIDs not implemented") -} - -// WriteSpan saves the span into Archive Storage -func (w *archiveWriter) WriteSpan(ctx context.Context, span *model.Span) error { - _, err := w.client.WriteArchiveSpan(ctx, &storage_v1.WriteSpanRequest{ - Span: span, - }) - if err != nil { - return fmt.Errorf("plugin error: %w", err) - } - - return nil -} diff --git a/plugin/storage/grpc/shared/archive_test.go b/plugin/storage/grpc/shared/archive_test.go deleted file mode 100644 index 100d4b9ba26..00000000000 --- a/plugin/storage/grpc/shared/archive_test.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2020 The Jaeger Authors. -// SPDX-License-Identifier: Apache-2.0 - -package shared - -import ( - "context" - "io" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/jaegertracing/jaeger-idl/model/v1" - "github.com/jaegertracing/jaeger/proto-gen/storage_v1" - "github.com/jaegertracing/jaeger/proto-gen/storage_v1/mocks" - "github.com/jaegertracing/jaeger/storage/spanstore" -) - -func TestArchiveWriter_WriteSpan(t *testing.T) { - mockSpan := &model.Span{ - TraceID: mockTraceID, - SpanID: model.NewSpanID(1), - Process: &model.Process{}, - } - - archiveSpanWriter := new(mocks.ArchiveSpanWriterPluginClient) - archiveSpanWriter.On("WriteArchiveSpan", mock.Anything, &storage_v1.WriteSpanRequest{Span: mockSpan}). - Return(&storage_v1.WriteSpanResponse{}, nil) - writer := &archiveWriter{client: archiveSpanWriter} - - err := writer.WriteSpan(context.Background(), mockSpan) - require.NoError(t, err) -} - -func TestArchiveReader_GetTrace(t *testing.T) { - mockTraceID := model.NewTraceID(0, 123456) - mockSpan := model.Span{ - TraceID: mockTraceID, - SpanID: model.NewSpanID(1), - Process: &model.Process{}, - } - expected := &model.Trace{ - Spans: []*model.Span{&mockSpan}, - } - - traceClient := new(mocks.ArchiveSpanReaderPlugin_GetArchiveTraceClient) - traceClient.On("Recv").Return(&storage_v1.SpansResponseChunk{ - Spans: []model.Span{mockSpan}, - }, nil).Once() - traceClient.On("Recv").Return(nil, io.EOF) - - archiveSpanReader := new(mocks.ArchiveSpanReaderPluginClient) - archiveSpanReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - }).Return(traceClient, nil) - reader := &archiveReader{client: archiveSpanReader} - - trace, err := reader.GetTrace(context.Background(), spanstore.GetTraceParameters{ - TraceID: mockTraceID, - }) - require.NoError(t, err) - assert.Equal(t, expected, trace) -} - -func TestArchiveReaderGetTrace_NoTrace(t *testing.T) { - mockTraceID := model.NewTraceID(0, 123456) - - archiveSpanReader := new(mocks.ArchiveSpanReaderPluginClient) - archiveSpanReader.On("GetArchiveTrace", mock.Anything, &storage_v1.GetTraceRequest{ - TraceID: mockTraceID, - }).Return(nil, status.Errorf(codes.NotFound, "")) - reader := &archiveReader{client: archiveSpanReader} - - _, err := reader.GetTrace(context.Background(), spanstore.GetTraceParameters{ - TraceID: mockTraceID, - }) - assert.Equal(t, spanstore.ErrTraceNotFound, err) -} - -func TestArchiveReader_FindTraceIDs(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.FindTraceIDs(context.Background(), nil) - require.Error(t, err) -} - -func TestArchiveReader_FindTraces(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.FindTraces(context.Background(), nil) - require.Error(t, err) -} - -func TestArchiveReader_GetOperations(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.GetOperations(context.Background(), spanstore.OperationQueryParameters{}) - require.Error(t, err) -} - -func TestArchiveReader_GetServices(t *testing.T) { - reader := archiveReader{client: &mocks.ArchiveSpanReaderPluginClient{}} - _, err := reader.GetServices(context.Background()) - require.Error(t, err) -} From 9a42d6bac1413c573f1b65d382d081e6fcfc088f Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 25 Jan 2025 12:20:33 -0500 Subject: [PATCH 71/74] Move to idl Signed-off-by: Mahad Zaryab --- cmd/query/app/querysvc/query_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/query/app/querysvc/query_service.go b/cmd/query/app/querysvc/query_service.go index 86731c5abc7..914a302e30b 100644 --- a/cmd/query/app/querysvc/query_service.go +++ b/cmd/query/app/querysvc/query_service.go @@ -8,7 +8,7 @@ import ( "errors" "time" - "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger-idl/model/v1" "github.com/jaegertracing/jaeger/model/adjuster" "github.com/jaegertracing/jaeger/storage/spanstore" "github.com/jaegertracing/jaeger/storage_v2/depstore" From d2ef5b345b0655350895c66a27eea94f16656288 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 25 Jan 2025 13:37:51 -0500 Subject: [PATCH 72/74] Address Feedback Signed-off-by: Mahad Zaryab --- plugin/storage/factory.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index de1ed381215..f70470e2c55 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -111,8 +111,7 @@ func NewFactory(config FactoryConfig) (*Factory, error) { } f.factories[t] = ff - af, err := f.getArchiveFactoryOfType(t) - if err == nil { + if af, ok := f.getArchiveFactoryOfType(t); ok { f.archiveFactories[t] = af } } @@ -140,16 +139,16 @@ func (*Factory) getFactoryOfType(factoryType string) (storage.Factory, error) { } } -func (*Factory) getArchiveFactoryOfType(factoryType string) (storage.Factory, error) { +func (*Factory) getArchiveFactoryOfType(factoryType string) (storage.Factory, bool) { switch factoryType { case cassandraStorageType: - return cassandra.NewArchiveFactory(), nil + return cassandra.NewArchiveFactory(), true case elasticsearchStorageType, opensearchStorageType: - return es.NewArchiveFactory(), nil + return es.NewArchiveFactory(), true case grpcStorageType: - return grpc.NewArchiveFactory(), nil + return grpc.NewArchiveFactory(), true default: - return nil, fmt.Errorf("archive storage factory not available for %s", factoryType) + return nil, false } } From 859e4cebf6e160eac9a0307a45002fd48d92b7f3 Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 25 Jan 2025 13:42:27 -0500 Subject: [PATCH 73/74] Move Interfaces To Other Package Signed-off-by: Mahad Zaryab --- plugin/configurable.go | 12 ------------ plugin/storage/cassandra/factory.go | 4 ++-- plugin/storage/es/factory.go | 12 ++++++------ plugin/storage/factory.go | 4 ++-- plugin/storage/grpc/factory.go | 8 ++++---- storage/factory.go | 12 ++++++++++++ 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/plugin/configurable.go b/plugin/configurable.go index 4be32bf76da..07a479cf4ce 100644 --- a/plugin/configurable.go +++ b/plugin/configurable.go @@ -9,8 +9,6 @@ import ( "github.com/spf13/viper" "go.uber.org/zap" - - "github.com/jaegertracing/jaeger/storage" ) // Configurable interface can be implemented by plugins that require external configuration, @@ -22,13 +20,3 @@ type Configurable interface { // InitFromViper initializes this component with properties from spf13/viper. InitFromViper(v *viper.Viper, logger *zap.Logger) } - -// Inheritable is an interface that can be implement by some storage implementations -// to provide a way to inherit configuration settings from another factory. -type Inheritable interface { - InheritSettingsFrom(other storage.Factory) -} - -type ArchiveCapable interface { - IsArchiveCapable() bool -} diff --git a/plugin/storage/cassandra/factory.go b/plugin/storage/cassandra/factory.go index 5fb990d1181..5937f92d08a 100644 --- a/plugin/storage/cassandra/factory.go +++ b/plugin/storage/cassandra/factory.go @@ -46,8 +46,8 @@ var ( // interface comformance checks _ storage.SamplingStoreFactory = (*Factory)(nil) _ io.Closer = (*Factory)(nil) _ plugin.Configurable = (*Factory)(nil) - _ plugin.Inheritable = (*Factory)(nil) - _ plugin.ArchiveCapable = (*Factory)(nil) + _ storage.Inheritable = (*Factory)(nil) + _ storage.ArchiveCapable = (*Factory)(nil) ) // Factory implements storage.Factory for Cassandra backend. diff --git a/plugin/storage/es/factory.go b/plugin/storage/es/factory.go index a565ff4737c..595e81ffe29 100644 --- a/plugin/storage/es/factory.go +++ b/plugin/storage/es/factory.go @@ -42,12 +42,12 @@ const ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) - _ plugin.Inheritable = (*Factory)(nil) - _ storage.Purger = (*Factory)(nil) - _ plugin.ArchiveCapable = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ storage.Inheritable = (*Factory)(nil) + _ storage.Purger = (*Factory)(nil) + _ storage.ArchiveCapable = (*Factory)(nil) ) // Factory implements storage.Factory for Elasticsearch backend. diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index f70470e2c55..6142c299456 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -173,7 +173,7 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) } for kind, factory := range f.archiveFactories { - if archivable, ok := factory.(plugin.ArchiveCapable); ok && archivable.IsArchiveCapable() { + if archivable, ok := factory.(storage.ArchiveCapable); ok && archivable.IsArchiveCapable() { if err := initializeFactory(kind, factory, "archive"); err != nil { return err } @@ -313,7 +313,7 @@ func (f *Factory) InitFromViper(v *viper.Viper, logger *zap.Logger) { initializeConfigurable(factory) if primaryFactory, ok := f.factories[kind]; ok { - if inheritable, ok := factory.(plugin.Inheritable); ok { + if inheritable, ok := factory.(storage.Inheritable); ok { inheritable.InheritSettingsFrom(primaryFactory) } } diff --git a/plugin/storage/grpc/factory.go b/plugin/storage/grpc/factory.go index e24aec335d9..dd6c68a9a40 100644 --- a/plugin/storage/grpc/factory.go +++ b/plugin/storage/grpc/factory.go @@ -34,10 +34,10 @@ import ( ) var ( // interface comformance checks - _ storage.Factory = (*Factory)(nil) - _ io.Closer = (*Factory)(nil) - _ plugin.Configurable = (*Factory)(nil) - _ plugin.ArchiveCapable = (*Factory)(nil) + _ storage.Factory = (*Factory)(nil) + _ io.Closer = (*Factory)(nil) + _ plugin.Configurable = (*Factory)(nil) + _ storage.ArchiveCapable = (*Factory)(nil) ) // Factory implements storage.Factory and creates storage components backed by a storage plugin. diff --git a/storage/factory.go b/storage/factory.go index c677390c4d9..da07bcd4ca8 100644 --- a/storage/factory.go +++ b/storage/factory.go @@ -74,3 +74,15 @@ type MetricStoreFactory interface { // CreateMetricsReader creates a metricstore.Reader. CreateMetricsReader() (metricstore.Reader, error) } + +// Inheritable is an interface that can be implement by some storage implementations +// to provide a way to inherit configuration settings from another factory. +type Inheritable interface { + InheritSettingsFrom(other Factory) +} + +// ArchiveCapable is an interface that can be implemented by some storage implementations +// to indicate that they are capable of archiving data. +type ArchiveCapable interface { + IsArchiveCapable() bool +} From ba5fdd4bbaf74575eee7d8b7e294e61adf6c206e Mon Sep 17 00:00:00 2001 From: Mahad Zaryab Date: Sat, 25 Jan 2025 13:56:00 -0500 Subject: [PATCH 74/74] Add Mocks Signed-off-by: Mahad Zaryab --- storage/mocks/ArchiveCapable.go | 47 +++++++++++++++++++++++++++++++++ storage/mocks/Inheritable.go | 37 ++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 storage/mocks/ArchiveCapable.go create mode 100644 storage/mocks/Inheritable.go diff --git a/storage/mocks/ArchiveCapable.go b/storage/mocks/ArchiveCapable.go new file mode 100644 index 00000000000..aef23e66bf4 --- /dev/null +++ b/storage/mocks/ArchiveCapable.go @@ -0,0 +1,47 @@ +// Copyright (c) The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 +// +// Run 'make generate-mocks' to regenerate. + +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// ArchiveCapable is an autogenerated mock type for the ArchiveCapable type +type ArchiveCapable struct { + mock.Mock +} + +// IsArchiveCapable provides a mock function with no fields +func (_m *ArchiveCapable) IsArchiveCapable() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsArchiveCapable") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// NewArchiveCapable creates a new instance of ArchiveCapable. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewArchiveCapable(t interface { + mock.TestingT + Cleanup(func()) +}) *ArchiveCapable { + mock := &ArchiveCapable{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/storage/mocks/Inheritable.go b/storage/mocks/Inheritable.go new file mode 100644 index 00000000000..150bf34ab1e --- /dev/null +++ b/storage/mocks/Inheritable.go @@ -0,0 +1,37 @@ +// Copyright (c) The Jaeger Authors. +// SPDX-License-Identifier: Apache-2.0 +// +// Run 'make generate-mocks' to regenerate. + +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + storage "github.com/jaegertracing/jaeger/storage" + mock "github.com/stretchr/testify/mock" +) + +// Inheritable is an autogenerated mock type for the Inheritable type +type Inheritable struct { + mock.Mock +} + +// InheritSettingsFrom provides a mock function with given fields: other +func (_m *Inheritable) InheritSettingsFrom(other storage.Factory) { + _m.Called(other) +} + +// NewInheritable creates a new instance of Inheritable. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewInheritable(t interface { + mock.TestingT + Cleanup(func()) +}) *Inheritable { + mock := &Inheritable{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +}