Moved to google.golang.org/genproto/googleapis/api/annotations

Fixes #52
This commit is contained in:
Valerio Gheri
2017-03-31 18:01:58 +02:00
parent 024c5a4e4e
commit c40779224f
2037 changed files with 831329 additions and 1854 deletions

39
vendor/github.com/go-kit/kit/sd/consul/client.go generated vendored Normal file
View File

@@ -0,0 +1,39 @@
package consul
import (
consul "github.com/hashicorp/consul/api"
)
// Client is a wrapper around the Consul API.
type Client interface {
// Register a service with the local agent.
Register(r *consul.AgentServiceRegistration) error
// Deregister a service with the local agent.
Deregister(r *consul.AgentServiceRegistration) error
// Service
Service(service, tag string, passingOnly bool, queryOpts *consul.QueryOptions) ([]*consul.ServiceEntry, *consul.QueryMeta, error)
}
type client struct {
consul *consul.Client
}
// NewClient returns an implementation of the Client interface, wrapping a
// concrete Consul client.
func NewClient(c *consul.Client) Client {
return &client{consul: c}
}
func (c *client) Register(r *consul.AgentServiceRegistration) error {
return c.consul.Agent().ServiceRegister(r)
}
func (c *client) Deregister(r *consul.AgentServiceRegistration) error {
return c.consul.Agent().ServiceDeregister(r.ID)
}
func (c *client) Service(service, tag string, passingOnly bool, queryOpts *consul.QueryOptions) ([]*consul.ServiceEntry, *consul.QueryMeta, error) {
return c.consul.Health().Service(service, tag, passingOnly, queryOpts)
}

156
vendor/github.com/go-kit/kit/sd/consul/client_test.go generated vendored Normal file
View File

@@ -0,0 +1,156 @@
package consul
import (
"context"
"errors"
"io"
"reflect"
"testing"
stdconsul "github.com/hashicorp/consul/api"
"github.com/go-kit/kit/endpoint"
)
func TestClientRegistration(t *testing.T) {
c := newTestClient(nil)
services, _, err := c.Service(testRegistration.Name, "", true, &stdconsul.QueryOptions{})
if err != nil {
t.Error(err)
}
if want, have := 0, len(services); want != have {
t.Errorf("want %d, have %d", want, have)
}
if err := c.Register(testRegistration); err != nil {
t.Error(err)
}
if err := c.Register(testRegistration); err == nil {
t.Errorf("want error, have %v", err)
}
services, _, err = c.Service(testRegistration.Name, "", true, &stdconsul.QueryOptions{})
if err != nil {
t.Error(err)
}
if want, have := 1, len(services); want != have {
t.Errorf("want %d, have %d", want, have)
}
if err := c.Deregister(testRegistration); err != nil {
t.Error(err)
}
if err := c.Deregister(testRegistration); err == nil {
t.Errorf("want error, have %v", err)
}
services, _, err = c.Service(testRegistration.Name, "", true, &stdconsul.QueryOptions{})
if err != nil {
t.Error(err)
}
if want, have := 0, len(services); want != have {
t.Errorf("want %d, have %d", want, have)
}
}
type testClient struct {
entries []*stdconsul.ServiceEntry
}
func newTestClient(entries []*stdconsul.ServiceEntry) *testClient {
return &testClient{
entries: entries,
}
}
var _ Client = &testClient{}
func (c *testClient) Service(service, tag string, _ bool, opts *stdconsul.QueryOptions) ([]*stdconsul.ServiceEntry, *stdconsul.QueryMeta, error) {
var results []*stdconsul.ServiceEntry
for _, entry := range c.entries {
if entry.Service.Service != service {
continue
}
if tag != "" {
tagMap := map[string]struct{}{}
for _, t := range entry.Service.Tags {
tagMap[t] = struct{}{}
}
if _, ok := tagMap[tag]; !ok {
continue
}
}
results = append(results, entry)
}
return results, &stdconsul.QueryMeta{}, nil
}
func (c *testClient) Register(r *stdconsul.AgentServiceRegistration) error {
toAdd := registration2entry(r)
for _, entry := range c.entries {
if reflect.DeepEqual(*entry, *toAdd) {
return errors.New("duplicate")
}
}
c.entries = append(c.entries, toAdd)
return nil
}
func (c *testClient) Deregister(r *stdconsul.AgentServiceRegistration) error {
toDelete := registration2entry(r)
var newEntries []*stdconsul.ServiceEntry
for _, entry := range c.entries {
if reflect.DeepEqual(*entry, *toDelete) {
continue
}
newEntries = append(newEntries, entry)
}
if len(newEntries) == len(c.entries) {
return errors.New("not found")
}
c.entries = newEntries
return nil
}
func registration2entry(r *stdconsul.AgentServiceRegistration) *stdconsul.ServiceEntry {
return &stdconsul.ServiceEntry{
Node: &stdconsul.Node{
Node: "some-node",
Address: r.Address,
},
Service: &stdconsul.AgentService{
ID: r.ID,
Service: r.Name,
Tags: r.Tags,
Port: r.Port,
Address: r.Address,
},
// Checks ignored
}
}
func testFactory(instance string) (endpoint.Endpoint, io.Closer, error) {
return func(context.Context, interface{}) (interface{}, error) {
return instance, nil
}, nil, nil
}
var testRegistration = &stdconsul.AgentServiceRegistration{
ID: "my-id",
Name: "my-name",
Tags: []string{"my-tag-1", "my-tag-2"},
Port: 12345,
Address: "my-address",
}

2
vendor/github.com/go-kit/kit/sd/consul/doc.go generated vendored Normal file
View File

@@ -0,0 +1,2 @@
// Package consul provides subscriber and registrar implementations for Consul.
package consul

View File

@@ -0,0 +1,81 @@
// +build integration
package consul
import (
"io"
"os"
"testing"
"time"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log"
stdconsul "github.com/hashicorp/consul/api"
)
func TestIntegration(t *testing.T) {
consulAddr := os.Getenv("CONSUL_ADDR")
if consulAddr == "" {
t.Fatal("CONSUL_ADDR is not set")
}
stdClient, err := stdconsul.NewClient(&stdconsul.Config{
Address: consulAddr,
})
if err != nil {
t.Fatal(err)
}
client := NewClient(stdClient)
logger := log.NewLogfmtLogger(os.Stderr)
// Produce a fake service registration.
r := &stdconsul.AgentServiceRegistration{
ID: "my-service-ID",
Name: "my-service-name",
Tags: []string{"alpha", "beta"},
Port: 12345,
Address: "my-address",
EnableTagOverride: false,
// skipping check(s)
}
// Build a subscriber on r.Name + r.Tags.
factory := func(instance string) (endpoint.Endpoint, io.Closer, error) {
t.Logf("factory invoked for %q", instance)
return endpoint.Nop, nil, nil
}
subscriber := NewSubscriber(
client,
factory,
log.With(logger, "component", "subscriber"),
r.Name,
r.Tags,
true,
)
time.Sleep(time.Second)
// Before we publish, we should have no endpoints.
endpoints, err := subscriber.Endpoints()
if err != nil {
t.Error(err)
}
if want, have := 0, len(endpoints); want != have {
t.Errorf("want %d, have %d", want, have)
}
// Build a registrar for r.
registrar := NewRegistrar(client, r, log.With(logger, "component", "registrar"))
registrar.Register()
defer registrar.Deregister()
time.Sleep(time.Second)
// Now we should have one active endpoints.
endpoints, err = subscriber.Endpoints()
if err != nil {
t.Error(err)
}
if want, have := 1, len(endpoints); want != have {
t.Errorf("want %d, have %d", want, have)
}
}

44
vendor/github.com/go-kit/kit/sd/consul/registrar.go generated vendored Normal file
View File

@@ -0,0 +1,44 @@
package consul
import (
"fmt"
stdconsul "github.com/hashicorp/consul/api"
"github.com/go-kit/kit/log"
)
// Registrar registers service instance liveness information to Consul.
type Registrar struct {
client Client
registration *stdconsul.AgentServiceRegistration
logger log.Logger
}
// NewRegistrar returns a Consul Registrar acting on the provided catalog
// registration.
func NewRegistrar(client Client, r *stdconsul.AgentServiceRegistration, logger log.Logger) *Registrar {
return &Registrar{
client: client,
registration: r,
logger: log.With(logger, "service", r.Name, "tags", fmt.Sprint(r.Tags), "address", r.Address),
}
}
// Register implements sd.Registrar interface.
func (p *Registrar) Register() {
if err := p.client.Register(p.registration); err != nil {
p.logger.Log("err", err)
} else {
p.logger.Log("action", "register")
}
}
// Deregister implements sd.Registrar interface.
func (p *Registrar) Deregister() {
if err := p.client.Deregister(p.registration); err != nil {
p.logger.Log("err", err)
} else {
p.logger.Log("action", "deregister")
}
}

View File

@@ -0,0 +1,27 @@
package consul
import (
"testing"
stdconsul "github.com/hashicorp/consul/api"
"github.com/go-kit/kit/log"
)
func TestRegistrar(t *testing.T) {
client := newTestClient([]*stdconsul.ServiceEntry{})
p := NewRegistrar(client, testRegistration, log.NewNopLogger())
if want, have := 0, len(client.entries); want != have {
t.Errorf("want %d, have %d", want, have)
}
p.Register()
if want, have := 1, len(client.entries); want != have {
t.Errorf("want %d, have %d", want, have)
}
p.Deregister()
if want, have := 0, len(client.entries); want != have {
t.Errorf("want %d, have %d", want, have)
}
}

166
vendor/github.com/go-kit/kit/sd/consul/subscriber.go generated vendored Normal file
View File

@@ -0,0 +1,166 @@
package consul
import (
"fmt"
"io"
consul "github.com/hashicorp/consul/api"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/sd"
"github.com/go-kit/kit/sd/cache"
)
const defaultIndex = 0
// Subscriber yields endpoints for a service in Consul. Updates to the service
// are watched and will update the Subscriber endpoints.
type Subscriber struct {
cache *cache.Cache
client Client
logger log.Logger
service string
tags []string
passingOnly bool
endpointsc chan []endpoint.Endpoint
quitc chan struct{}
}
var _ sd.Subscriber = &Subscriber{}
// NewSubscriber returns a Consul subscriber which returns endpoints for the
// requested service. It only returns instances for which all of the passed tags
// are present.
func NewSubscriber(client Client, factory sd.Factory, logger log.Logger, service string, tags []string, passingOnly bool) *Subscriber {
s := &Subscriber{
cache: cache.New(factory, logger),
client: client,
logger: log.With(logger, "service", service, "tags", fmt.Sprint(tags)),
service: service,
tags: tags,
passingOnly: passingOnly,
quitc: make(chan struct{}),
}
instances, index, err := s.getInstances(defaultIndex, nil)
if err == nil {
s.logger.Log("instances", len(instances))
} else {
s.logger.Log("err", err)
}
s.cache.Update(instances)
go s.loop(index)
return s
}
// Endpoints implements the Subscriber interface.
func (s *Subscriber) Endpoints() ([]endpoint.Endpoint, error) {
return s.cache.Endpoints(), nil
}
// Stop terminates the subscriber.
func (s *Subscriber) Stop() {
close(s.quitc)
}
func (s *Subscriber) loop(lastIndex uint64) {
var (
instances []string
err error
)
for {
instances, lastIndex, err = s.getInstances(lastIndex, s.quitc)
switch {
case err == io.EOF:
return // stopped via quitc
case err != nil:
s.logger.Log("err", err)
default:
s.cache.Update(instances)
}
}
}
func (s *Subscriber) getInstances(lastIndex uint64, interruptc chan struct{}) ([]string, uint64, error) {
tag := ""
if len(s.tags) > 0 {
tag = s.tags[0]
}
// Consul doesn't support more than one tag in its service query method.
// https://github.com/hashicorp/consul/issues/294
// Hashi suggest prepared queries, but they don't support blocking.
// https://www.consul.io/docs/agent/http/query.html#execute
// If we want blocking for efficiency, we must filter tags manually.
type response struct {
instances []string
index uint64
}
var (
errc = make(chan error, 1)
resc = make(chan response, 1)
)
go func() {
entries, meta, err := s.client.Service(s.service, tag, s.passingOnly, &consul.QueryOptions{
WaitIndex: lastIndex,
})
if err != nil {
errc <- err
return
}
if len(s.tags) > 1 {
entries = filterEntries(entries, s.tags[1:]...)
}
resc <- response{
instances: makeInstances(entries),
index: meta.LastIndex,
}
}()
select {
case err := <-errc:
return nil, 0, err
case res := <-resc:
return res.instances, res.index, nil
case <-interruptc:
return nil, 0, io.EOF
}
}
func filterEntries(entries []*consul.ServiceEntry, tags ...string) []*consul.ServiceEntry {
var es []*consul.ServiceEntry
ENTRIES:
for _, entry := range entries {
ts := make(map[string]struct{}, len(entry.Service.Tags))
for _, tag := range entry.Service.Tags {
ts[tag] = struct{}{}
}
for _, tag := range tags {
if _, ok := ts[tag]; !ok {
continue ENTRIES
}
}
es = append(es, entry)
}
return es
}
func makeInstances(entries []*consul.ServiceEntry) []string {
instances := make([]string, len(entries))
for i, entry := range entries {
addr := entry.Node.Address
if entry.Service.Address != "" {
addr = entry.Service.Address
}
instances[i] = fmt.Sprintf("%s:%d", addr, entry.Service.Port)
}
return instances
}

View File

@@ -0,0 +1,138 @@
package consul
import (
"context"
"testing"
consul "github.com/hashicorp/consul/api"
"github.com/go-kit/kit/log"
)
var consulState = []*consul.ServiceEntry{
{
Node: &consul.Node{
Address: "10.0.0.0",
Node: "app00.local",
},
Service: &consul.AgentService{
ID: "search-api-0",
Port: 8000,
Service: "search",
Tags: []string{
"api",
"v1",
},
},
},
{
Node: &consul.Node{
Address: "10.0.0.1",
Node: "app01.local",
},
Service: &consul.AgentService{
ID: "search-api-1",
Port: 8001,
Service: "search",
Tags: []string{
"api",
"v2",
},
},
},
{
Node: &consul.Node{
Address: "10.0.0.1",
Node: "app01.local",
},
Service: &consul.AgentService{
Address: "10.0.0.10",
ID: "search-db-0",
Port: 9000,
Service: "search",
Tags: []string{
"db",
},
},
},
}
func TestSubscriber(t *testing.T) {
var (
logger = log.NewNopLogger()
client = newTestClient(consulState)
)
s := NewSubscriber(client, testFactory, logger, "search", []string{"api"}, true)
defer s.Stop()
endpoints, err := s.Endpoints()
if err != nil {
t.Fatal(err)
}
if want, have := 2, len(endpoints); want != have {
t.Errorf("want %d, have %d", want, have)
}
}
func TestSubscriberNoService(t *testing.T) {
var (
logger = log.NewNopLogger()
client = newTestClient(consulState)
)
s := NewSubscriber(client, testFactory, logger, "feed", []string{}, true)
defer s.Stop()
endpoints, err := s.Endpoints()
if err != nil {
t.Fatal(err)
}
if want, have := 0, len(endpoints); want != have {
t.Fatalf("want %d, have %d", want, have)
}
}
func TestSubscriberWithTags(t *testing.T) {
var (
logger = log.NewNopLogger()
client = newTestClient(consulState)
)
s := NewSubscriber(client, testFactory, logger, "search", []string{"api", "v2"}, true)
defer s.Stop()
endpoints, err := s.Endpoints()
if err != nil {
t.Fatal(err)
}
if want, have := 1, len(endpoints); want != have {
t.Fatalf("want %d, have %d", want, have)
}
}
func TestSubscriberAddressOverride(t *testing.T) {
s := NewSubscriber(newTestClient(consulState), testFactory, log.NewNopLogger(), "search", []string{"db"}, true)
defer s.Stop()
endpoints, err := s.Endpoints()
if err != nil {
t.Fatal(err)
}
if want, have := 1, len(endpoints); want != have {
t.Fatalf("want %d, have %d", want, have)
}
response, err := endpoints[0](context.Background(), struct{}{})
if err != nil {
t.Fatal(err)
}
if want, have := "10.0.0.10:9000", response.(string); want != have {
t.Errorf("want %q, have %q", want, have)
}
}