Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gRPC Plugin framework #1461

Merged
merged 38 commits into from
May 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
2d32099
Add New Storage Plugin Framework
olivierboucher Nov 24, 2018
1a21e65
Remove old generated storage file
chvck Apr 5, 2019
70f43dc
Update plugin grpc interface/implementation
chvck Apr 5, 2019
482edd6
Fix gosec by adding an exclude comment
chvck Apr 8, 2019
be72ed7
Run make fmt
chvck Apr 8, 2019
9925b38
Remove unused plugin file
chvck Apr 9, 2019
74aaf5e
Add comments to uncommented functions
chvck Apr 9, 2019
a8a0114
Split grpc server and client into separate files
chvck Apr 9, 2019
ef0078f
Use errors.wrap rather than fmt for errors
chvck Apr 9, 2019
931dfa4
Add copyright header to grpc server file
chvck Apr 11, 2019
d5fe102
Update headers to updated license on uncommitted files
chvck Apr 11, 2019
f56cc80
Merge branch 'master' into chvck/plugin-framework
chvck Apr 15, 2019
7dc2b9a
Merge branch 'master' into chvck/plugin-framework
chvck Apr 24, 2019
f180890
Move grpc config to plugin/storage
chvck Apr 24, 2019
419f4ce
Add empty test files to fix build
Apr 23, 2019
9f482b4
Merge branch 'master' into chvck/plugin-framework
chvck Apr 26, 2019
3919ac6
Move grpc config empty_test file
chvck Apr 26, 2019
5e87836
Merge branch 'master' into plugin-framework
Apr 28, 2019
7e7b072
Merge pull request #2 from yurishkuro/plugin-framework-fix-gosec
chvck Apr 28, 2019
7ffb8b6
Change fmt for error to errors.Wrap
chvck Apr 30, 2019
c136b37
Use single-line for comprehensions where possible
chvck Apr 30, 2019
978eb07
Don't accumulate spans before sending
chvck Apr 30, 2019
0abb726
Add function to serve the plugin
chvck Apr 30, 2019
dd199ad
Merge branch 'master' into chvck/plugin-framework
chvck Apr 30, 2019
79e0849
Small grpc client refactor
chvck Apr 30, 2019
b747fb9
Update grpc interface and move noop plugin to examples
chvck Apr 30, 2019
03db22b
Add missed fix for factory
chvck Apr 30, 2019
ba8b35f
Rename memory-store example to memstore-plugin
chvck May 1, 2019
616f1b9
Refactor Serve to call ServeWithGRPCServer
chvck May 1, 2019
bf0e140
Refactor to make some structs private
chvck May 1, 2019
deba568
Change factory_test to use mocks
chvck May 1, 2019
763ec4c
Add storage grpc integration test
chvck May 1, 2019
3b5e9ea
Create mocks for storage_v1 and add grpc client tests
chvck May 3, 2019
6041195
Add grpc server tests
chvck May 3, 2019
86d8a1f
Run make fmt
chvck May 3, 2019
84a7a67
Merge branch 'master' into chvck/plugin-framework
chvck May 3, 2019
4a43047
Strip unnecessary code from test
chvck May 3, 2019
83f7edc
Merge branch 'master' into plugin-framework
yurishkuro May 5, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,11 @@ required = [
[[constraint]]
name = "github.com/rs/cors"
version = "1.3.0"

[[constraint]]
name = "github.com/hashicorp/go-plugin"
version = "1.0.0"

[[constraint]]
name = "github.com/hashicorp/go-hclog"
version = "0.8.0"
15 changes: 15 additions & 0 deletions examples/memstore-plugin/empty_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2018 The Jaeger Authors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file should be removed (packages with main() are excluded from coverage automatically)

//
// 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 main
65 changes: 65 additions & 0 deletions examples/memstore-plugin/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2018 The Jaeger Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"flag"
"path"
"strings"

"github.com/spf13/viper"

"github.com/jaegertracing/jaeger/plugin/storage/grpc"
"github.com/jaegertracing/jaeger/storage/dependencystore"
"github.com/jaegertracing/jaeger/plugin/storage/memory"
"github.com/jaegertracing/jaeger/storage/spanstore"
)

var configPath string

func main() {
flag.StringVar(&configPath, "config", "", "A path to the plugin's configuration file")
flag.Parse()

if configPath != "" {
viper.SetConfigFile(path.Base(configPath))
viper.AddConfigPath(path.Dir(configPath))
}

v := viper.New()
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_", ".", "_"))

opts := memory.Options{}
opts.InitFromViper(v)

grpc.Serve(&memoryStore{store: memory.NewStore()})
}

type memoryStore struct {
store *memory.Store
}

func (ns *memoryStore) DependencyReader() dependencystore.Reader {
return ns.store
}

func (ns *memoryStore) SpanReader() spanstore.Reader {
return ns.store
}

func (ns *memoryStore) SpanWriter() spanstore.Writer {
return ns.store
}
6 changes: 5 additions & 1 deletion plugin/storage/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/jaegertracing/jaeger/plugin/storage/badger"
"github.com/jaegertracing/jaeger/plugin/storage/cassandra"
"github.com/jaegertracing/jaeger/plugin/storage/es"
"github.com/jaegertracing/jaeger/plugin/storage/grpc"
"github.com/jaegertracing/jaeger/plugin/storage/kafka"
"github.com/jaegertracing/jaeger/plugin/storage/memory"
"github.com/jaegertracing/jaeger/storage"
Expand All @@ -38,6 +39,7 @@ const (
elasticsearchStorageType = "elasticsearch"
memoryStorageType = "memory"
kafkaStorageType = "kafka"
grpcPluginStorageType = "grpc-plugin"
badgerStorageType = "badger"
downsamplingRatio = "downsampling.ratio"
downsamplingHashSalt = "downsampling.hashsalt"
Expand All @@ -48,7 +50,7 @@ const (
defaultDownsamplingHashSalt = ""
)

var allStorageTypes = []string{cassandraStorageType, elasticsearchStorageType, memoryStorageType, kafkaStorageType, badgerStorageType}
var allStorageTypes = []string{cassandraStorageType, elasticsearchStorageType, memoryStorageType, kafkaStorageType, badgerStorageType, grpcPluginStorageType}

// Factory implements storage.Factory interface as a meta-factory for storage components.
type Factory struct {
Expand Down Expand Up @@ -90,6 +92,8 @@ func (f *Factory) getFactoryOfType(factoryType string) (storage.Factory, error)
return kafka.NewFactory(), nil
case badgerStorageType:
return badger.NewFactory(), nil
case grpcPluginStorageType:
return grpc.NewFactory(), nil
default:
return nil, fmt.Errorf("unknown storage type %s. Valid types are %v", factoryType, allStorageTypes)
}
Expand Down
76 changes: 76 additions & 0 deletions plugin/storage/grpc/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) 2019 The Jaeger Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package config

import (
"fmt"
"os/exec"
"runtime"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"

"github.com/jaegertracing/jaeger/plugin/storage/grpc/shared"
)

// Configuration describes the options to customize the storage behavior
type Configuration struct {
PluginBinary string `yaml:"binary"`
PluginConfigurationFile string `yaml:"configuration-file"`
}

// Build instantiates a StoragePlugin
func (c *Configuration) Build() (shared.StoragePlugin, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file comes up with large gap in coverage, but we can actually test it using examples/memstore-plugin/

// #nosec G204
cmd := exec.Command(c.PluginBinary, "--config", c.PluginConfigurationFile)

client := plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: shared.Handshake,
VersionedPlugins: map[int]plugin.PluginSet{
1: shared.PluginMap,
},
Cmd: cmd,
AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
Logger: hclog.New(&hclog.LoggerOptions{
Level: hclog.Warn,
}),
})

runtime.SetFinalizer(client, func(c *plugin.Client) {
c.Kill()
})

rpcClient, err := client.Client()
if err != nil {
return nil, fmt.Errorf("error attempting to connect to plugin rpc client: %s", err)
}

raw, err := rpcClient.Dispense(shared.StoragePluginIdentifier)
if err != nil {
return nil, fmt.Errorf("unable to retrieve storage plugin instance: %s", err)
}

storagePlugin, ok := raw.(shared.StoragePlugin)
if !ok {
return nil, fmt.Errorf("unexpected type for plugin \"%s\"", shared.StoragePluginIdentifier)
}

return storagePlugin, nil
}

// PluginBuilder is used to create storage plugins
type PluginBuilder interface {
Build() (shared.StoragePlugin, error)
}
15 changes: 15 additions & 0 deletions plugin/storage/grpc/config/empty_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2018 The Jaeger Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package config
Loading