1
0
mirror of https://github.com/go-kratos/kratos.git synced 2025-03-29 21:57:16 +02:00

add feat endpoint (#972)

* add feature endpoint
This commit is contained in:
longxboy 2021-05-31 16:10:17 +08:00 committed by GitHub
parent 493373dc13
commit e1d6377542
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 28 deletions

11
app.go
View File

@ -116,22 +116,27 @@ func (a *App) Stop() error {
} }
func (a *App) buildInstance() (*registry.ServiceInstance, error) { func (a *App) buildInstance() (*registry.ServiceInstance, error) {
if len(a.opts.endpoints) == 0 { var endpoints []string
for _, e := range a.opts.endpoints {
endpoints = append(endpoints, e.String())
}
if len(endpoints) == 0 {
for _, srv := range a.opts.servers { for _, srv := range a.opts.servers {
if r, ok := srv.(transport.Endpointer); ok { if r, ok := srv.(transport.Endpointer); ok {
e, err := r.Endpoint() e, err := r.Endpoint()
if err != nil { if err != nil {
return nil, err return nil, err
} }
a.opts.endpoints = append(a.opts.endpoints, e) endpoints = append(endpoints, e.String())
} }
} }
} }
return &registry.ServiceInstance{ return &registry.ServiceInstance{
ID: a.opts.id, ID: a.opts.id,
Name: a.opts.name, Name: a.opts.name,
Version: a.opts.version, Version: a.opts.version,
Metadata: a.opts.metadata, Metadata: a.opts.metadata,
Endpoints: a.opts.endpoints, Endpoints: endpoints,
}, nil }, nil
} }

View File

@ -2,6 +2,7 @@ package kratos
import ( import (
"context" "context"
"net/url"
"os" "os"
"github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/log"
@ -18,7 +19,7 @@ type options struct {
name string name string
version string version string
metadata map[string]string metadata map[string]string
endpoints []string endpoints []*url.URL
ctx context.Context ctx context.Context
sigs []os.Signal sigs []os.Signal
@ -50,7 +51,7 @@ func Metadata(md map[string]string) Option {
} }
// Endpoint with service endpoint. // Endpoint with service endpoint.
func Endpoint(endpoints ...string) Option { func Endpoint(endpoints ...*url.URL) Option {
return func(o *options) { o.endpoints = endpoints } return func(o *options) { o.endpoints = endpoints }
} }

View File

@ -1,6 +1,9 @@
package grpc package grpc
import "context" import (
"context"
"net/url"
)
// ServerInfo represent gRPC server information. // ServerInfo represent gRPC server information.
type ServerInfo struct { type ServerInfo struct {
@ -8,6 +11,8 @@ type ServerInfo struct {
Server interface{} Server interface{}
// FullMethod is the full RPC method string, i.e., /package.service/method. // FullMethod is the full RPC method string, i.e., /package.service/method.
FullMethod string FullMethod string
// Endpoint is a real address to registry endpoint.
Endpoint *url.URL
} }
type serverKey struct{} type serverKey struct{}

View File

@ -2,8 +2,8 @@ package grpc
import ( import (
"context" "context"
"fmt"
"net" "net"
"net/url"
"strings" "strings"
"time" "time"
@ -75,6 +75,7 @@ type Server struct {
lis net.Listener lis net.Listener
network string network string
address string address string
endpoint *url.URL
timeout time.Duration timeout time.Duration
log *log.Helper log *log.Helper
middleware middleware.Middleware middleware middleware.Middleware
@ -118,19 +119,24 @@ func NewServer(opts ...ServerOption) *Server {
// Endpoint return a real address to registry endpoint. // Endpoint return a real address to registry endpoint.
// examples: // examples:
// grpc://127.0.0.1:9000?isSecure=false // grpc://127.0.0.1:9000?isSecure=false
func (s *Server) Endpoint() (string, error) { func (s *Server) Endpoint() (*url.URL, error) {
if s.lis == nil && strings.HasSuffix(s.address, ":0") { if s.lis == nil && strings.HasSuffix(s.address, ":0") {
lis, err := net.Listen(s.network, s.address) lis, err := net.Listen(s.network, s.address)
if err != nil { if err != nil {
return "", err return nil, err
} }
s.lis = lis s.lis = lis
} }
addr, err := host.Extract(s.address, s.lis) addr, err := host.Extract(s.address, s.lis)
if err != nil { if err != nil {
return "", err return nil, err
} }
return fmt.Sprintf("grpc://%s", addr), nil u := &url.URL{
Scheme: "grpc",
Host: addr,
}
s.endpoint = u
return u, nil
} }
// Start start the gRPC server. // Start start the gRPC server.
@ -161,7 +167,7 @@ func (s *Server) unaryServerInterceptor() grpc.UnaryServerInterceptor {
ctx, cancel := ic.Merge(ctx, s.ctx) ctx, cancel := ic.Merge(ctx, s.ctx)
defer cancel() defer cancel()
ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindGRPC}) ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindGRPC})
ctx = NewServerContext(ctx, ServerInfo{Server: info.Server, FullMethod: info.FullMethod}) ctx = NewServerContext(ctx, ServerInfo{Server: info.Server, FullMethod: info.FullMethod, Endpoint: s.endpoint})
if s.timeout > 0 { if s.timeout > 0 {
var cancel context.CancelFunc var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, s.timeout) ctx, cancel = context.WithTimeout(ctx, s.timeout)

View File

@ -15,7 +15,7 @@ func TestServer(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ctx = context.WithValue(ctx, testKey{}, "test") ctx = context.WithValue(ctx, testKey{}, "test")
srv := NewServer() srv := NewServer()
if e, err := srv.Endpoint(); err != nil || e == "" { if e, err := srv.Endpoint(); err != nil || e == nil {
t.Fatal(e, err) t.Fatal(e, err)
} }

View File

@ -3,12 +3,14 @@ package http
import ( import (
"context" "context"
"net/http" "net/http"
"net/url"
) )
// ServerInfo represent HTTP server information. // ServerInfo represent HTTP server information.
type ServerInfo struct { type ServerInfo struct {
Request *http.Request Request *http.Request
Response http.ResponseWriter Response http.ResponseWriter
Endpoint *url.URL
} }
type serverKey struct{} type serverKey struct{}

View File

@ -3,9 +3,9 @@ package http
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"net" "net"
"net/http" "net/http"
"net/url"
"strings" "strings"
"time" "time"
@ -54,13 +54,14 @@ func Logger(logger log.Logger) ServerOption {
// Server is an HTTP server wrapper. // Server is an HTTP server wrapper.
type Server struct { type Server struct {
*http.Server *http.Server
ctx context.Context ctx context.Context
lis net.Listener lis net.Listener
network string network string
address string address string
timeout time.Duration endpoint *url.URL
router *mux.Router timeout time.Duration
log *log.Helper router *mux.Router
log *log.Helper
} }
// NewServer creates an HTTP server by options. // NewServer creates an HTTP server by options.
@ -99,7 +100,7 @@ func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
ctx, cancel := ic.Merge(req.Context(), s.ctx) ctx, cancel := ic.Merge(req.Context(), s.ctx)
defer cancel() defer cancel()
ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindHTTP}) ctx = transport.NewContext(ctx, transport.Transport{Kind: transport.KindHTTP})
ctx = NewServerContext(ctx, ServerInfo{Request: req, Response: res}) ctx = NewServerContext(ctx, ServerInfo{Request: req, Response: res, Endpoint: s.endpoint})
if s.timeout > 0 { if s.timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, s.timeout) ctx, cancel = context.WithTimeout(ctx, s.timeout)
defer cancel() defer cancel()
@ -110,19 +111,24 @@ func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
// Endpoint return a real address to registry endpoint. // Endpoint return a real address to registry endpoint.
// examples: // examples:
// http://127.0.0.1:8000?isSecure=false // http://127.0.0.1:8000?isSecure=false
func (s *Server) Endpoint() (string, error) { func (s *Server) Endpoint() (*url.URL, error) {
if s.lis == nil && strings.HasSuffix(s.address, ":0") { if s.lis == nil && strings.HasSuffix(s.address, ":0") {
lis, err := net.Listen(s.network, s.address) lis, err := net.Listen(s.network, s.address)
if err != nil { if err != nil {
return "", err return nil, err
} }
s.lis = lis s.lis = lis
} }
addr, err := host.Extract(s.address, s.lis) addr, err := host.Extract(s.address, s.lis)
if err != nil { if err != nil {
return "", err return nil, err
} }
return fmt.Sprintf("http://%s", addr), nil u := &url.URL{
Scheme: "http",
Host: addr,
}
s.endpoint = u
return u, nil
} }
// Start start the HTTP server. // Start start the HTTP server.

View File

@ -32,7 +32,7 @@ func TestServer(t *testing.T) {
srv := NewServer() srv := NewServer()
srv.HandleFunc("/index", fn) srv.HandleFunc("/index", fn)
if e, err := srv.Endpoint(); err != nil || e == "" { if e, err := srv.Endpoint(); err != nil || e == nil {
t.Fatal(e, err) t.Fatal(e, err)
} }

View File

@ -2,6 +2,7 @@ package transport
import ( import (
"context" "context"
"net/url"
// init encoding // init encoding
_ "github.com/go-kratos/kratos/v2/encoding/json" _ "github.com/go-kratos/kratos/v2/encoding/json"
@ -18,7 +19,7 @@ type Server interface {
// Endpointer is registry endpoint. // Endpointer is registry endpoint.
type Endpointer interface { type Endpointer interface {
Endpoint() (string, error) Endpoint() (*url.URL, error)
} }
// Transport is transport context value. // Transport is transport context value.