1
0
mirror of https://github.com/go-micro/go-micro.git synced 2025-08-10 21:52:01 +02:00

Restructure go-micro layout and plugins

This commit is contained in:
Asim
2015-05-23 20:04:16 +01:00
parent 018183fa49
commit 74fd1fc989
39 changed files with 673 additions and 577 deletions

11
registry/consul/consul.go Normal file
View File

@@ -0,0 +1,11 @@
package consul
// This is a hack
import (
"github.com/myodc/go-micro/registry"
)
func NewRegistry(addrs []string, opt ...registry.Option) registry.Registry {
return registry.NewRegistry(addrs, opt...)
}

View File

@@ -1,20 +1,20 @@
package registry
type ConsulNode struct {
type consulNode struct {
Node string
NodeId string
NodeAddress string
NodePort int
}
func (c *ConsulNode) Id() string {
func (c *consulNode) Id() string {
return c.NodeId
}
func (c *ConsulNode) Address() string {
func (c *consulNode) Address() string {
return c.NodeAddress
}
func (c *ConsulNode) Port() int {
func (c *consulNode) Port() int {
return c.NodePort
}

View File

@@ -7,7 +7,7 @@ import (
consul "github.com/hashicorp/consul/api"
)
type ConsulRegistry struct {
type consulRegistry struct {
Address string
Client *consul.Client
@@ -15,7 +15,24 @@ type ConsulRegistry struct {
services map[string]Service
}
func (c *ConsulRegistry) Deregister(s Service) error {
func newConsulRegistry(addrs []string, opts ...Option) Registry {
config := consul.DefaultConfig()
client, _ := consul.NewClient(config)
if len(addrs) > 0 {
config.Address = addrs[0]
}
cr := &consulRegistry{
Address: config.Address,
Client: client,
services: make(map[string]Service),
}
cr.Watch()
return cr
}
func (c *consulRegistry) Deregister(s Service) error {
if len(s.Nodes()) == 0 {
return errors.New("Require at least one node")
}
@@ -31,7 +48,7 @@ func (c *ConsulRegistry) Deregister(s Service) error {
return err
}
func (c *ConsulRegistry) Register(s Service) error {
func (c *consulRegistry) Register(s Service) error {
if len(s.Nodes()) == 0 {
return errors.New("Require at least one node")
}
@@ -51,7 +68,7 @@ func (c *ConsulRegistry) Register(s Service) error {
return err
}
func (c *ConsulRegistry) GetService(name string) (Service, error) {
func (c *consulRegistry) GetService(name string) (Service, error) {
c.mtx.RLock()
service, ok := c.services[name]
c.mtx.RUnlock()
@@ -65,7 +82,7 @@ func (c *ConsulRegistry) GetService(name string) (Service, error) {
return nil, err
}
cs := &ConsulService{}
cs := &consulService{}
for _, s := range rsp {
if s.ServiceName != name {
@@ -73,7 +90,7 @@ func (c *ConsulRegistry) GetService(name string) (Service, error) {
}
cs.ServiceName = s.ServiceName
cs.ServiceNodes = append(cs.ServiceNodes, &ConsulNode{
cs.ServiceNodes = append(cs.ServiceNodes, &consulNode{
Node: s.Node,
NodeId: s.ServiceID,
NodeAddress: s.Address,
@@ -84,7 +101,7 @@ func (c *ConsulRegistry) GetService(name string) (Service, error) {
return cs, nil
}
func (c *ConsulRegistry) ListServices() ([]Service, error) {
func (c *consulRegistry) ListServices() ([]Service, error) {
c.mtx.RLock()
serviceMap := c.services
c.mtx.RUnlock()
@@ -104,29 +121,29 @@ func (c *ConsulRegistry) ListServices() ([]Service, error) {
}
for service, _ := range rsp {
services = append(services, &ConsulService{ServiceName: service})
services = append(services, &consulService{ServiceName: service})
}
return services, nil
}
func (c *ConsulRegistry) NewService(name string, nodes ...Node) Service {
var snodes []*ConsulNode
func (c *consulRegistry) NewService(name string, nodes ...Node) Service {
var snodes []*consulNode
for _, node := range nodes {
if n, ok := node.(*ConsulNode); ok {
if n, ok := node.(*consulNode); ok {
snodes = append(snodes, n)
}
}
return &ConsulService{
return &consulService{
ServiceName: name,
ServiceNodes: snodes,
}
}
func (c *ConsulRegistry) NewNode(id, address string, port int) Node {
return &ConsulNode{
func (c *consulRegistry) NewNode(id, address string, port int) Node {
return &consulNode{
Node: id,
NodeId: id,
NodeAddress: address,
@@ -134,23 +151,6 @@ func (c *ConsulRegistry) NewNode(id, address string, port int) Node {
}
}
func (c *ConsulRegistry) Watch() {
NewConsulWatcher(c)
}
func NewConsulRegistry(addrs []string, opts ...Options) Registry {
config := consul.DefaultConfig()
client, _ := consul.NewClient(config)
if len(addrs) > 0 {
config.Address = addrs[0]
}
cr := &ConsulRegistry{
Address: config.Address,
Client: client,
services: make(map[string]Service),
}
cr.Watch()
return cr
func (c *consulRegistry) Watch() {
newConsulWatcher(c)
}

View File

@@ -1,15 +1,15 @@
package registry
type ConsulService struct {
type consulService struct {
ServiceName string
ServiceNodes []*ConsulNode
ServiceNodes []*consulNode
}
func (c *ConsulService) Name() string {
func (c *consulService) Name() string {
return c.ServiceName
}
func (c *ConsulService) Nodes() []Node {
func (c *consulService) Nodes() []Node {
var nodes []Node
for _, node := range c.ServiceNodes {

View File

@@ -5,8 +5,8 @@ import (
"github.com/hashicorp/consul/watch"
)
type ConsulWatcher struct {
Registry *ConsulRegistry
type consulWatcher struct {
Registry *consulRegistry
wp *watch.WatchPlan
watchers map[string]*watch.WatchPlan
}
@@ -15,17 +15,33 @@ type serviceWatcher struct {
name string
}
func (cw *ConsulWatcher) serviceHandler(idx uint64, data interface{}) {
func newConsulWatcher(cr *consulRegistry) *consulWatcher {
cw := &consulWatcher{
Registry: cr,
watchers: make(map[string]*watch.WatchPlan),
}
wp, err := watch.Parse(map[string]interface{}{"type": "services"})
if err == nil {
wp.Handler = cw.Handle
go wp.Run(cr.Address)
cw.wp = wp
}
return cw
}
func (cw *consulWatcher) serviceHandler(idx uint64, data interface{}) {
entries, ok := data.([]*api.ServiceEntry)
if !ok {
return
}
cs := &ConsulService{}
cs := &consulService{}
for _, e := range entries {
cs.ServiceName = e.Service.Service
cs.ServiceNodes = append(cs.ServiceNodes, &ConsulNode{
cs.ServiceNodes = append(cs.ServiceNodes, &consulNode{
Node: e.Node.Node,
NodeId: e.Service.ID,
NodeAddress: e.Node.Address,
@@ -38,7 +54,7 @@ func (cw *ConsulWatcher) serviceHandler(idx uint64, data interface{}) {
cw.Registry.mtx.Unlock()
}
func (cw *ConsulWatcher) Handle(idx uint64, data interface{}) {
func (cw *consulWatcher) Handle(idx uint64, data interface{}) {
services, ok := data.(map[string][]string)
if !ok {
return
@@ -82,25 +98,9 @@ func (cw *ConsulWatcher) Handle(idx uint64, data interface{}) {
}
}
func (cw *ConsulWatcher) Stop() {
func (cw *consulWatcher) Stop() {
if cw.wp == nil {
return
}
cw.wp.Stop()
}
func NewConsulWatcher(cr *ConsulRegistry) *ConsulWatcher {
cw := &ConsulWatcher{
Registry: cr,
watchers: make(map[string]*watch.WatchPlan),
}
wp, err := watch.Parse(map[string]interface{}{"type": "services"})
if err == nil {
wp.Handler = cw.Handle
go wp.Run(cr.Address)
cw.wp = wp
}
return cw
}

View File

@@ -0,0 +1,139 @@
package kubernetes
import (
"fmt"
"os"
"sync"
"github.com/myodc/go-micro/registry"
k8s "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
)
type kregistry struct {
client *k8s.Client
namespace string
mtx sync.RWMutex
services map[string]registry.Service
}
func (c *kregistry) Watch() {
newWatcher(c)
}
func (c *kregistry) Deregister(s registry.Service) error {
return nil
}
func (c *kregistry) Register(s registry.Service) error {
return nil
}
func (c *kregistry) GetService(name string) (registry.Service, error) {
c.mtx.RLock()
svc, ok := c.services[name]
c.mtx.RUnlock()
if ok {
return svc, nil
}
selector := labels.SelectorFromSet(labels.Set{"name": name})
services, err := c.client.Services(c.namespace).List(selector)
if err != nil {
return nil, err
}
if len(services.Items) == 0 {
return nil, fmt.Errorf("Service not found")
}
ks := &service{name: name}
for _, item := range services.Items {
ks.nodes = append(ks.nodes, &node{
address: item.Spec.PortalIP,
port: item.Spec.Ports[0].Port,
})
}
return ks, nil
}
func (c *kregistry) ListServices() ([]registry.Service, error) {
c.mtx.RLock()
serviceMap := c.services
c.mtx.RUnlock()
var services []registry.Service
if len(serviceMap) > 0 {
for _, service := range serviceMap {
services = append(services, service)
}
return services, nil
}
rsp, err := c.client.Services(c.namespace).List(labels.Everything())
if err != nil {
return nil, err
}
for _, svc := range rsp.Items {
if len(svc.ObjectMeta.Labels["name"]) == 0 {
continue
}
services = append(services, &service{
name: svc.ObjectMeta.Labels["name"],
})
}
return services, nil
}
func (c *kregistry) NewService(name string, nodes ...registry.Node) registry.Service {
var snodes []*node
for _, nod := range nodes {
if n, ok := nod.(*node); ok {
snodes = append(snodes, n)
}
}
return &service{
name: name,
nodes: snodes,
}
}
func (c *kregistry) NewNode(id, address string, port int) registry.Node {
return &node{
id: id,
address: address,
port: port,
}
}
func NewRegistry(addrs []string, opts ...registry.Option) registry.Registry {
host := "http://" + os.Getenv("KUBERNETES_RO_SERVICE_HOST") + ":" + os.Getenv("KUBERNETES_RO_SERVICE_PORT")
if len(addrs) > 0 {
host = addrs[0]
}
client, _ := k8s.New(&k8s.Config{
Host: host,
})
kr := &kregistry{
client: client,
namespace: "default",
services: make(map[string]registry.Service),
}
kr.Watch()
return kr
}

View File

@@ -0,0 +1,19 @@
package kubernetes
type node struct {
id string
address string
port int
}
func (n *node) Id() string {
return n.id
}
func (n *node) Address() string {
return n.address
}
func (n *node) Port() int {
return n.port
}

View File

@@ -0,0 +1,24 @@
package kubernetes
import (
"github.com/myodc/go-micro/registry"
)
type service struct {
name string
nodes []*node
}
func (s *service) Name() string {
return s.name
}
func (s *service) Nodes() []registry.Node {
var nodes []registry.Node
for _, node := range s.nodes {
nodes = append(nodes, node)
}
return nodes
}

View File

@@ -0,0 +1,72 @@
package kubernetes
import (
"fmt"
"net"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/config"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
type watcher struct {
registry *kregistry
}
func (k *watcher) OnUpdate(services []api.Service) {
fmt.Println("got update")
activeServices := util.StringSet{}
for _, svc := range services {
fmt.Printf("%#v\n", svc.ObjectMeta)
name, exists := svc.ObjectMeta.Labels["name"]
if !exists {
continue
}
activeServices.Insert(name)
serviceIP := net.ParseIP(svc.Spec.PortalIP)
ks := &service{
name: name,
nodes: []*node{
&node{
address: serviceIP.String(),
port: svc.Spec.Ports[0].Port,
},
},
}
k.registry.mtx.Lock()
k.registry.services[name] = ks
k.registry.mtx.Unlock()
}
k.registry.mtx.Lock()
defer k.registry.mtx.Unlock()
for name, _ := range k.registry.services {
if !activeServices.Has(name) {
delete(k.registry.services, name)
}
}
}
func newWatcher(kr *kregistry) *watcher {
serviceConfig := config.NewServiceConfig()
endpointsConfig := config.NewEndpointsConfig()
config.NewSourceAPI(
kr.client.Services(api.NamespaceAll),
kr.client.Endpoints(api.NamespaceAll),
time.Second*10,
serviceConfig.Channel("api"),
endpointsConfig.Channel("api"),
)
ks := &watcher{
registry: kr,
}
serviceConfig.RegisterHandler(ks)
return ks
}

View File

@@ -1,19 +0,0 @@
package registry
type KubernetesNode struct {
NodeId string
NodeAddress string
NodePort int
}
func (c *KubernetesNode) Id() string {
return c.NodeId
}
func (c *KubernetesNode) Address() string {
return c.NodeAddress
}
func (c *KubernetesNode) Port() int {
return c.NodePort
}

View File

@@ -1,137 +0,0 @@
package registry
import (
"fmt"
"os"
"sync"
k8s "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
)
type KubernetesRegistry struct {
Client *k8s.Client
Namespace string
mtx sync.RWMutex
services map[string]Service
}
func (c *KubernetesRegistry) Watch() {
NewKubernetesWatcher(c)
}
func (c *KubernetesRegistry) Deregister(s Service) error {
return nil
}
func (c *KubernetesRegistry) Register(s Service) error {
return nil
}
func (c *KubernetesRegistry) GetService(name string) (Service, error) {
c.mtx.RLock()
service, ok := c.services[name]
c.mtx.RUnlock()
if ok {
return service, nil
}
selector := labels.SelectorFromSet(labels.Set{"name": name})
services, err := c.Client.Services(c.Namespace).List(selector)
if err != nil {
return nil, err
}
if len(services.Items) == 0 {
return nil, fmt.Errorf("Service not found")
}
ks := &KubernetesService{ServiceName: name}
for _, item := range services.Items {
ks.ServiceNodes = append(ks.ServiceNodes, &KubernetesNode{
NodeAddress: item.Spec.PortalIP,
NodePort: item.Spec.Ports[0].Port,
})
}
return ks, nil
}
func (c *KubernetesRegistry) ListServices() ([]Service, error) {
c.mtx.RLock()
serviceMap := c.services
c.mtx.RUnlock()
var services []Service
if len(serviceMap) > 0 {
for _, service := range serviceMap {
services = append(services, service)
}
return services, nil
}
rsp, err := c.Client.Services(c.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
for _, service := range rsp.Items {
if len(service.ObjectMeta.Labels["name"]) == 0 {
continue
}
services = append(services, &KubernetesService{
ServiceName: service.ObjectMeta.Labels["name"],
})
}
return services, nil
}
func (c *KubernetesRegistry) NewService(name string, nodes ...Node) Service {
var snodes []*KubernetesNode
for _, node := range nodes {
if n, ok := node.(*KubernetesNode); ok {
snodes = append(snodes, n)
}
}
return &KubernetesService{
ServiceName: name,
ServiceNodes: snodes,
}
}
func (c *KubernetesRegistry) NewNode(id, address string, port int) Node {
return &KubernetesNode{
NodeId: id,
NodeAddress: address,
NodePort: port,
}
}
func NewKubernetesRegistry(addrs []string, opts ...Options) Registry {
host := "http://" + os.Getenv("KUBERNETES_RO_SERVICE_HOST") + ":" + os.Getenv("KUBERNETES_RO_SERVICE_PORT")
if len(addrs) > 0 {
host = addrs[0]
}
client, _ := k8s.New(&k8s.Config{
Host: host,
})
kr := &KubernetesRegistry{
Client: client,
Namespace: "default",
services: make(map[string]Service),
}
kr.Watch()
return kr
}

View File

@@ -1,20 +0,0 @@
package registry
type KubernetesService struct {
ServiceName string
ServiceNodes []*KubernetesNode
}
func (c *KubernetesService) Name() string {
return c.ServiceName
}
func (c *KubernetesService) Nodes() []Node {
var nodes []Node
for _, node := range c.ServiceNodes {
nodes = append(nodes, node)
}
return nodes
}

View File

@@ -1,72 +0,0 @@
package registry
import (
"fmt"
"net"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/config"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
type KubernetesWatcher struct {
Registry *KubernetesRegistry
}
func (k *KubernetesWatcher) OnUpdate(services []api.Service) {
fmt.Println("got update")
activeServices := util.StringSet{}
for _, service := range services {
fmt.Printf("%#v\n", service.ObjectMeta)
name, exists := service.ObjectMeta.Labels["name"]
if !exists {
continue
}
activeServices.Insert(name)
serviceIP := net.ParseIP(service.Spec.PortalIP)
ks := &KubernetesService{
ServiceName: name,
ServiceNodes: []*KubernetesNode{
&KubernetesNode{
NodeAddress: serviceIP.String(),
NodePort: service.Spec.Ports[0].Port,
},
},
}
k.Registry.mtx.Lock()
k.Registry.services[name] = ks
k.Registry.mtx.Unlock()
}
k.Registry.mtx.Lock()
defer k.Registry.mtx.Unlock()
for name, _ := range k.Registry.services {
if !activeServices.Has(name) {
delete(k.Registry.services, name)
}
}
}
func NewKubernetesWatcher(kr *KubernetesRegistry) *KubernetesWatcher {
serviceConfig := config.NewServiceConfig()
endpointsConfig := config.NewEndpointsConfig()
config.NewSourceAPI(
kr.Client.Services(api.NamespaceAll),
kr.Client.Endpoints(api.NamespaceAll),
time.Second*10,
serviceConfig.Channel("api"),
endpointsConfig.Channel("api"),
)
ks := &KubernetesWatcher{
Registry: kr,
}
serviceConfig.RegisterHandler(ks)
return ks
}

View File

@@ -11,12 +11,16 @@ type Registry interface {
type options struct{}
type Options func(*options)
type Option func(*options)
var (
DefaultRegistry = NewConsulRegistry([]string{})
DefaultRegistry = newConsulRegistry([]string{})
)
func NewRegistry(addrs []string, opt ...Option) Registry {
return newConsulRegistry(addrs, opt...)
}
func Register(s Service) error {
return DefaultRegistry.Register(s)
}