diff --git a/plugin/storage/blackhole/blackhole.go b/plugin/storage/blackhole/blackhole.go new file mode 100644 index 00000000000..3118a2d84ef --- /dev/null +++ b/plugin/storage/blackhole/blackhole.go @@ -0,0 +1,75 @@ +// Copyright (c) 2019 The Jaeger Authors. +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package blackhole + +import ( + "context" + "time" + + "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger/storage/spanstore" +) + +// Store is a blackhole. It creates an artificial micro-singularity +// and forwards all writes to it. We do not know what happens to the +// data once it reaches the singulatiry, but we know that we cannot +// get it back. +type Store struct { + // nothing, just darkness +} + +// NewStore creates a blackhole store. +func NewStore() *Store { + return &Store{} +} + +// GetDependencies returns nothing. +func (st *Store) GetDependencies(ctx context.Context, endTs time.Time, lookback time.Duration) ([]model.DependencyLink, error) { + return []model.DependencyLink{}, nil +} + +// WriteSpan writes the given span to blackhole. +func (st *Store) WriteSpan(ctx context.Context, span *model.Span) error { + return nil +} + +// GetTrace gets nothing. +func (st *Store) GetTrace(ctx context.Context, traceID model.TraceID) (*model.Trace, error) { + return nil, spanstore.ErrTraceNotFound +} + +// GetServices returns nothing. +func (st *Store) GetServices(ctx context.Context) ([]string, error) { + return []string{}, nil +} + +// GetOperations returns nothing. +func (st *Store) GetOperations( + ctx context.Context, + query spanstore.OperationQueryParameters, +) ([]spanstore.Operation, error) { + return []spanstore.Operation{}, nil +} + +// FindTraces returns nothing. +func (st *Store) FindTraces(ctx context.Context, query *spanstore.TraceQueryParameters) ([]*model.Trace, error) { + return []*model.Trace{}, nil +} + +// FindTraceIDs returns nothing. +func (m *Store) FindTraceIDs(ctx context.Context, query *spanstore.TraceQueryParameters) ([]model.TraceID, error) { + return []model.TraceID{}, nil +} diff --git a/plugin/storage/blackhole/blackhole_test.go b/plugin/storage/blackhole/blackhole_test.go new file mode 100644 index 00000000000..b02b45fa7d6 --- /dev/null +++ b/plugin/storage/blackhole/blackhole_test.go @@ -0,0 +1,89 @@ +// Copyright (c) 2019 The Jaeger Authors. +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package blackhole + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/jaegertracing/jaeger/model" + "github.com/jaegertracing/jaeger/storage/spanstore" +) + +func withBlackhole(f func(store *Store)) { + f(NewStore()) +} + +func TestStoreGetDependencies(t *testing.T) { + withBlackhole(func(store *Store) { + links, err := store.GetDependencies(context.Background(), time.Now(), time.Hour) + assert.NoError(t, err) + assert.Empty(t, links) + }) +} + +func TestStoreWriteSpan(t *testing.T) { + withBlackhole(func(store *Store) { + err := store.WriteSpan(context.Background(), nil) + assert.NoError(t, err) + }) +} + +func TestStoreGetTrace(t *testing.T) { + withBlackhole(func(store *Store) { + trace, err := store.GetTrace(context.Background(), model.NewTraceID(1, 2)) + assert.Error(t, err) + assert.Nil(t, trace) + }) +} + +func TestStoreGetServices(t *testing.T) { + withBlackhole(func(store *Store) { + serviceNames, err := store.GetServices(context.Background()) + assert.NoError(t, err) + assert.Len(t, serviceNames, 0) + }) +} + +func TestStoreGetAllOperations(t *testing.T) { + withBlackhole(func(store *Store) { + operations, err := store.GetOperations( + context.Background(), + spanstore.OperationQueryParameters{}, + ) + assert.NoError(t, err) + assert.Len(t, operations, 0) + }) +} + +func TestStoreFindTraces(t *testing.T) { + withBlackhole(func(store *Store) { + traces, err := store.FindTraces(context.Background(), nil) + assert.NoError(t, err) + assert.Len(t, traces, 0) + }) +} + +func TestStoreFindTraceIDs(t *testing.T) { + withBlackhole(func(store *Store) { + traceIDs, err := store.FindTraceIDs(context.Background(), nil) + assert.NoError(t, err) + assert.Len(t, traceIDs, 0) + }) +} diff --git a/plugin/storage/blackhole/factory.go b/plugin/storage/blackhole/factory.go new file mode 100644 index 00000000000..3ddc2798faf --- /dev/null +++ b/plugin/storage/blackhole/factory.go @@ -0,0 +1,69 @@ +// Copyright (c) 2019 The Jaeger Authors. +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package blackhole + +import ( + "go.uber.org/zap" + + "github.com/jaegertracing/jaeger/pkg/metrics" + "github.com/jaegertracing/jaeger/storage/dependencystore" + "github.com/jaegertracing/jaeger/storage/spanstore" +) + +// Factory implements storage.Factory and creates blackhole storage components. +type Factory struct { + metricsFactory metrics.Factory + logger *zap.Logger + store *Store +} + +// NewFactory creates a new Factory. +func NewFactory() *Factory { + return &Factory{} +} + +// Initialize implements storage.Factory +func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger) error { + f.metricsFactory, f.logger = metricsFactory, logger + f.store = NewStore() + logger.Info("Blackhole storage initialized") + return nil +} + +// CreateSpanReader implements storage.Factory +func (f *Factory) CreateSpanReader() (spanstore.Reader, error) { + return f.store, nil +} + +// CreateSpanWriter implements storage.Factory +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 +} diff --git a/plugin/storage/blackhole/factory_test.go b/plugin/storage/blackhole/factory_test.go new file mode 100644 index 00000000000..3416a34af3b --- /dev/null +++ b/plugin/storage/blackhole/factory_test.go @@ -0,0 +1,49 @@ +// Copyright (c) 2019 The Jaeger Authors. +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package blackhole + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/zap" + + "github.com/jaegertracing/jaeger/pkg/metrics" + "github.com/jaegertracing/jaeger/storage" +) + +var _ storage.Factory = new(Factory) + +func TestStorageFactory(t *testing.T) { + f := NewFactory() + assert.NoError(t, f.Initialize(metrics.NullFactory, zap.NewNop())) + assert.NotNil(t, f.store) + reader, err := f.CreateSpanReader() + assert.NoError(t, err) + assert.Equal(t, f.store, reader) + writer, err := f.CreateSpanWriter() + assert.NoError(t, err) + assert.Equal(t, f.store, writer) + reader, err = f.CreateArchiveSpanReader() + assert.NoError(t, err) + assert.Equal(t, f.store, reader) + writer, err = f.CreateArchiveSpanWriter() + assert.NoError(t, err) + assert.Equal(t, f.store, writer) + depReader, err := f.CreateDependencyReader() + assert.NoError(t, err) + assert.Equal(t, f.store, depReader) +} diff --git a/plugin/storage/factory.go b/plugin/storage/factory.go index b2c6b7a9226..8b88032b0f6 100644 --- a/plugin/storage/factory.go +++ b/plugin/storage/factory.go @@ -27,6 +27,7 @@ import ( "github.com/jaegertracing/jaeger/pkg/metrics" "github.com/jaegertracing/jaeger/plugin" "github.com/jaegertracing/jaeger/plugin/storage/badger" + "github.com/jaegertracing/jaeger/plugin/storage/blackhole" "github.com/jaegertracing/jaeger/plugin/storage/cassandra" "github.com/jaegertracing/jaeger/plugin/storage/es" "github.com/jaegertracing/jaeger/plugin/storage/grpc" @@ -45,6 +46,7 @@ const ( kafkaStorageType = "kafka" grpcPluginStorageType = "grpc-plugin" badgerStorageType = "badger" + blackholeStorageType = "blackhole" downsamplingRatio = "downsampling.ratio" downsamplingHashSalt = "downsampling.hashsalt" @@ -64,6 +66,7 @@ var AllStorageTypes = []string{ memoryStorageType, kafkaStorageType, badgerStorageType, + blackholeStorageType, grpcPluginStorageType, } @@ -132,6 +135,8 @@ func (f *Factory) getFactoryOfType(factoryType string) (storage.Factory, error) return badger.NewFactory(), nil case grpcPluginStorageType: return grpc.NewFactory(), nil + case blackholeStorageType: + return blackhole.NewFactory(), nil default: return nil, fmt.Errorf("unknown storage type %s. Valid types are %v", factoryType, AllStorageTypes) } diff --git a/plugin/storage/factory_config.go b/plugin/storage/factory_config.go index 0fb576491c4..06b6833290b 100644 --- a/plugin/storage/factory_config.go +++ b/plugin/storage/factory_config.go @@ -52,6 +52,7 @@ type FactoryConfig struct { // * `elasticsearch` - built-in // * `memory` - built-in // * `kafka` - built-in +// * `blackhole` - built-in // * `plugin` - loads a dynamic plugin that implements storage.Factory interface (not supported at the moment) // // For backwards compatibility it also parses the args looking for deprecated --span-storage.type flag.