mirror of
https://github.com/go-micro/go-micro.git
synced 2025-10-06 21:46:55 +02:00
fix: some linting issues (#2563)
This commit is contained in:
@@ -60,7 +60,7 @@ linters-settings:
|
|||||||
# The longest distance, in source lines, that is being considered a "small scope".
|
# The longest distance, in source lines, that is being considered a "small scope".
|
||||||
# Variables used in at most this many lines will be ignored.
|
# Variables used in at most this many lines will be ignored.
|
||||||
# Default: 5
|
# Default: 5
|
||||||
max-distance: 16
|
max-distance: 26
|
||||||
ignore-names:
|
ignore-names:
|
||||||
- err
|
- err
|
||||||
- id
|
- id
|
||||||
@@ -86,7 +86,7 @@ linters-settings:
|
|||||||
check-blank: true
|
check-blank: true
|
||||||
govet:
|
govet:
|
||||||
# report about shadowed variables
|
# report about shadowed variables
|
||||||
check-shadowing: true
|
check-shadowing: false
|
||||||
gofmt:
|
gofmt:
|
||||||
# simplify code: gofmt with `-s` option, true by default
|
# simplify code: gofmt with `-s` option, true by default
|
||||||
simplify: true
|
simplify: true
|
||||||
@@ -182,6 +182,7 @@ linters:
|
|||||||
- nonamedreturns
|
- nonamedreturns
|
||||||
- makezero
|
- makezero
|
||||||
- gofumpt
|
- gofumpt
|
||||||
|
- nlreturn
|
||||||
|
|
||||||
# Can be considered to be enabled
|
# Can be considered to be enabled
|
||||||
- gochecknoinits
|
- gochecknoinits
|
||||||
|
27
api/api.go
27
api/api.go
@@ -12,10 +12,10 @@ import (
|
|||||||
"go-micro.dev/v4/server"
|
"go-micro.dev/v4/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The gateway interface provides a way to
|
// API interface provides a way to
|
||||||
// create composable API gateways
|
// create composable API gateways.
|
||||||
type Api interface {
|
type Api interface {
|
||||||
// Initialise options
|
// Initialize options
|
||||||
Init(...Option) error
|
Init(...Option) error
|
||||||
// Get the options
|
// Get the options
|
||||||
Options() Options
|
Options() Options
|
||||||
@@ -29,6 +29,7 @@ type Api interface {
|
|||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Options are API options.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// Address of the server
|
// Address of the server
|
||||||
Address string
|
Address string
|
||||||
@@ -36,9 +37,10 @@ type Options struct {
|
|||||||
Router router.Router
|
Router router.Router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Option type are API option args.
|
||||||
type Option func(*Options) error
|
type Option func(*Options) error
|
||||||
|
|
||||||
// Endpoint is a mapping between an RPC method and HTTP endpoint
|
// Endpoint is a mapping between an RPC method and HTTP endpoint.
|
||||||
type Endpoint struct {
|
type Endpoint struct {
|
||||||
// RPC Method e.g. Greeter.Hello
|
// RPC Method e.g. Greeter.Hello
|
||||||
Name string
|
Name string
|
||||||
@@ -56,7 +58,7 @@ type Endpoint struct {
|
|||||||
Stream bool
|
Stream bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service represents an API service
|
// Service represents an API service.
|
||||||
type Service struct {
|
type Service struct {
|
||||||
// Name of service
|
// Name of service
|
||||||
Name string
|
Name string
|
||||||
@@ -82,21 +84,22 @@ func slice(s string) []string {
|
|||||||
return sl
|
return sl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode encodes an endpoint to endpoint metadata
|
// Encode encodes an endpoint to endpoint metadata.
|
||||||
func Encode(e *Endpoint) map[string]string {
|
func Encode(e *Endpoint) map[string]string {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoint map
|
// endpoint map
|
||||||
ep := make(map[string]string)
|
em := make(map[string]string)
|
||||||
|
|
||||||
// set vals only if they exist
|
// set vals only if they exist
|
||||||
set := func(k, v string) {
|
set := func(k, v string) {
|
||||||
if len(v) == 0 {
|
if len(v) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ep[k] = v
|
|
||||||
|
em[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
set("endpoint", e.Name)
|
set("endpoint", e.Name)
|
||||||
@@ -106,10 +109,10 @@ func Encode(e *Endpoint) map[string]string {
|
|||||||
set("path", strings.Join(e.Path, ","))
|
set("path", strings.Join(e.Path, ","))
|
||||||
set("host", strings.Join(e.Host, ","))
|
set("host", strings.Join(e.Host, ","))
|
||||||
|
|
||||||
return ep
|
return em
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes endpoint metadata into an endpoint
|
// Decode decodes endpoint metadata into an endpoint.
|
||||||
func Decode(e map[string]string) *Endpoint {
|
func Decode(e map[string]string) *Endpoint {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -125,7 +128,7 @@ func Decode(e map[string]string) *Endpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates an endpoint to guarantee it won't blow up when being served
|
// Validate validates an endpoint to guarantee it won't blow up when being served.
|
||||||
func Validate(e *Endpoint) error {
|
func Validate(e *Endpoint) error {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return errors.New("endpoint is nil")
|
return errors.New("endpoint is nil")
|
||||||
@@ -172,7 +175,7 @@ func WithEndpoint(e *Endpoint) server.HandlerOption {
|
|||||||
return server.EndpointMetadata(e.Name, Encode(e))
|
return server.EndpointMetadata(e.Name, Encode(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewApi returns a new api gateway
|
// NewApi returns a new api gateway.
|
||||||
func NewApi(opts ...Option) Api {
|
func NewApi(opts ...Option) Api {
|
||||||
return newApi(opts...)
|
return newApi(opts...)
|
||||||
}
|
}
|
||||||
|
@@ -148,5 +148,4 @@ func TestValidate(t *testing.T) {
|
|||||||
if err := Validate(epPcreInvalid); err == nil {
|
if err := Validate(epPcreInvalid); err == nil {
|
||||||
t.Fatalf("invalid pcre %v", epPcreInvalid.Path[0])
|
t.Fatalf("invalid pcre %v", epPcreInvalid.Path[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -12,14 +12,16 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// local address for api
|
// local address for api.
|
||||||
localAddress = "http://localhost:8080"
|
localAddress = "http://localhost:8080"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Options of the Client
|
// Options of the Client.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// Token for authentication
|
// Token for authentication
|
||||||
Token string
|
Token string
|
||||||
@@ -33,7 +35,7 @@ type Options struct {
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request is the request of the generic `api-client` call
|
// Request is the request of the generic `api-client` call.
|
||||||
type Request struct {
|
type Request struct {
|
||||||
// eg. "go.micro.srv.greeter"
|
// eg. "go.micro.srv.greeter"
|
||||||
Service string `json:"service"`
|
Service string `json:"service"`
|
||||||
@@ -55,17 +57,18 @@ type Response struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client enables generic calls to micro
|
// Client enables generic calls to micro.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
options Options
|
options Options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stream is a websockets stream.
|
||||||
type Stream struct {
|
type Stream struct {
|
||||||
conn *websocket.Conn
|
conn *websocket.Conn
|
||||||
service, endpoint string
|
service, endpoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient returns a generic micro client that connects to live by default
|
// NewClient returns a generic micro client that connects to live by default.
|
||||||
func NewClient(options *Options) *Client {
|
func NewClient(options *Options) *Client {
|
||||||
ret := new(Client)
|
ret := new(Client)
|
||||||
ret.options = Options{
|
ret.options = Options{
|
||||||
@@ -93,17 +96,17 @@ func NewClient(options *Options) *Client {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetToken sets the api auth token
|
// SetToken sets the api auth token.
|
||||||
func (client *Client) SetToken(t string) {
|
func (client *Client) SetToken(t string) {
|
||||||
client.options.Token = t
|
client.options.Token = t
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTimeout sets the http client's timeout
|
// SetTimeout sets the http client's timeout.
|
||||||
func (client *Client) SetTimeout(d time.Duration) {
|
func (client *Client) SetTimeout(d time.Duration) {
|
||||||
client.options.Timeout = d
|
client.options.Timeout = d
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call enables you to access any endpoint of any service on Micro
|
// Call enables you to access any endpoint of any service on Micro.
|
||||||
func (client *Client) Call(service, endpoint string, request, response interface{}) error {
|
func (client *Client) Call(service, endpoint string, request, response interface{}) error {
|
||||||
// example curl: curl -XPOST -d '{"service": "go.micro.srv.greeter", "endpoint": "Say.Hello"}'
|
// example curl: curl -XPOST -d '{"service": "go.micro.srv.greeter", "endpoint": "Say.Hello"}'
|
||||||
// -H 'Content-Type: application/json' http://localhost:8080/client {"body":"eyJtc2ciOiJIZWxsbyAifQ=="}
|
// -H 'Content-Type: application/json' http://localhost:8080/client {"body":"eyJtc2ciOiJIZWxsbyAifQ=="}
|
||||||
@@ -115,7 +118,7 @@ func (client *Client) Call(service, endpoint string, request, response interface
|
|||||||
// set the url to go through the v1 api
|
// set the url to go through the v1 api
|
||||||
uri.Path = "/" + service + "/" + endpoint
|
uri.Path = "/" + service + "/" + endpoint
|
||||||
|
|
||||||
b, err := marshalRequest(service, endpoint, request)
|
b, err := marshalRequest(endpoint, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -141,21 +144,28 @@ func (client *Client) Call(service, endpoint string, request, response interface
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
|
||||||
|
defer func() {
|
||||||
|
if err = resp.Body.Close(); err != nil {
|
||||||
|
logger.DefaultLogger.Log(logger.ErrorLevel, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !(resp.StatusCode >= 200 && resp.StatusCode < 300) {
|
|
||||||
|
if resp.StatusCode <= 200 || resp.StatusCode > 300 {
|
||||||
return errors.New(string(body))
|
return errors.New(string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
return unmarshalResponse(body, response)
|
return unmarshalResponse(body, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream enables the ability to stream via websockets
|
// Stream enables the ability to stream via websockets.
|
||||||
func (client *Client) Stream(service, endpoint string, request interface{}) (*Stream, error) {
|
func (client *Client) Stream(service, endpoint string, request interface{}) (*Stream, error) {
|
||||||
b, err := marshalRequest(service, endpoint, request)
|
b, err := marshalRequest(endpoint, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -177,9 +187,10 @@ func (client *Client) Stream(service, endpoint string, request interface{}) (*St
|
|||||||
if len(client.options.Token) > 0 {
|
if len(client.options.Token) > 0 {
|
||||||
header.Set("Authorization", "Bearer "+client.options.Token)
|
header.Set("Authorization", "Bearer "+client.options.Token)
|
||||||
}
|
}
|
||||||
|
|
||||||
header.Set("Content-Type", "application/json")
|
header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
// dial the connection
|
// dial the connection, connection not closed as conn is returned
|
||||||
conn, _, err := websocket.DefaultDialer.Dial(uri.String(), header)
|
conn, _, err := websocket.DefaultDialer.Dial(uri.String(), header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -193,24 +204,28 @@ func (client *Client) Stream(service, endpoint string, request interface{}) (*St
|
|||||||
return &Stream{conn, service, endpoint}, nil
|
return &Stream{conn, service, endpoint}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recv will receive a message from a stream and unmarshal it.
|
||||||
func (s *Stream) Recv(v interface{}) error {
|
func (s *Stream) Recv(v interface{}) error {
|
||||||
// read response
|
// read response
|
||||||
_, message, err := s.conn.ReadMessage()
|
_, message, err := s.conn.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return unmarshalResponse(message, v)
|
return unmarshalResponse(message, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send will send a message into the stream.
|
||||||
func (s *Stream) Send(v interface{}) error {
|
func (s *Stream) Send(v interface{}) error {
|
||||||
b, err := marshalRequest(s.service, s.endpoint, v)
|
b, err := marshalRequest(s.endpoint, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.conn.WriteMessage(websocket.TextMessage, b)
|
return s.conn.WriteMessage(websocket.TextMessage, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalRequest(service, endpoint string, v interface{}) ([]byte, error) {
|
func marshalRequest(endpoint string, v interface{}) ([]byte, error) {
|
||||||
return json.Marshal(v)
|
return json.Marshal(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,7 +45,6 @@ func newApi(opts ...Option) Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise options
|
|
||||||
func (a *api) Init(opts ...Option) error {
|
func (a *api) Init(opts ...Option) error {
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&a.options)
|
o(&a.options)
|
||||||
@@ -53,17 +52,17 @@ func (a *api) Init(opts ...Option) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the options
|
// Get the options.
|
||||||
func (a *api) Options() Options {
|
func (a *api) Options() Options {
|
||||||
return a.options
|
return a.options
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register a http handler
|
// Register a http handler.
|
||||||
func (a *api) Register(*Endpoint) error {
|
func (a *api) Register(*Endpoint) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register a route
|
// Register a route.
|
||||||
func (a *api) Deregister(*Endpoint) error {
|
func (a *api) Deregister(*Endpoint) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ const (
|
|||||||
Handler = "api"
|
Handler = "api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// API handler is the default handler which takes api.Request and returns api.Response
|
// API handler is the default handler which takes api.Request and returns api.Response.
|
||||||
func (a *apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (a *apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
bsize := handler.DefaultMaxRecvSize
|
bsize := handler.DefaultMaxRecvSize
|
||||||
if a.opts.MaxRecvSize > 0 {
|
if a.opts.MaxRecvSize > 0 {
|
||||||
|
@@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// need to calculate later to specify useful defaults
|
// need to calculate later to specify useful defaults.
|
||||||
bufferPool = bpool.NewSizedBufferPool(1024, 8)
|
bufferPool = bpool.NewSizedBufferPool(1024, 8)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,11 +34,11 @@ func requestToProto(r *http.Request) (*api.Request, error) {
|
|||||||
|
|
||||||
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ct = "text/plain; charset=UTF-8" //default CT is text/plain
|
ct = "text/plain; charset=UTF-8" // default CT is text/plain
|
||||||
r.Header.Set("Content-Type", ct)
|
r.Header.Set("Content-Type", ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the body:
|
// set the body:
|
||||||
if r.Body != nil {
|
if r.Body != nil {
|
||||||
switch ct {
|
switch ct {
|
||||||
case "application/x-www-form-urlencoded":
|
case "application/x-www-form-urlencoded":
|
||||||
@@ -110,7 +110,7 @@ func requestToProto(r *http.Request) (*api.Request, error) {
|
|||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// strategy is a hack for selection
|
// strategy is a hack for selection.
|
||||||
func strategy(services []*registry.Service) selector.Strategy {
|
func strategy(services []*registry.Service) selector.Strategy {
|
||||||
return func(_ []*registry.Service) selector.Next {
|
return func(_ []*registry.Service) selector.Next {
|
||||||
// ignore input to this function, use services above
|
// ignore input to this function, use services above
|
||||||
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler represents a HTTP handler that manages a request
|
// Handler represents a HTTP handler that manages a request.
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
// standard http handler
|
// standard http handler
|
||||||
http.Handler
|
http.Handler
|
||||||
|
@@ -42,7 +42,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
httputil.NewSingleHostReverseProxy(rp).ServeHTTP(w, r)
|
httputil.NewSingleHostReverseProxy(rp).ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getService returns the service for this request from the selector
|
// getService returns the service for this request from the selector.
|
||||||
func (h *httpHandler) getService(r *http.Request) (string, error) {
|
func (h *httpHandler) getService(r *http.Request) (string, error) {
|
||||||
var service *router.Route
|
var service *router.Route
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ func (h *httpHandler) String() string {
|
|||||||
return "http"
|
return "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHandler returns a http proxy handler
|
// NewHandler returns a http proxy handler.
|
||||||
func NewHandler(opts ...handler.Option) handler.Handler {
|
func NewHandler(opts ...handler.Option) handler.Handler {
|
||||||
options := handler.NewOptions(opts...)
|
options := handler.NewOptions(opts...)
|
||||||
|
|
||||||
|
@@ -52,7 +52,7 @@ func testHttp(t *testing.T, path, service, ns string) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialise the handler
|
// initialize the handler
|
||||||
rt := regRouter.NewRouter(
|
rt := regRouter.NewRouter(
|
||||||
router.WithHandler("http"),
|
router.WithHandler("http"),
|
||||||
router.WithRegistry(r),
|
router.WithRegistry(r),
|
||||||
|
@@ -20,7 +20,7 @@ type Options struct {
|
|||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
// NewOptions fills in the blanks
|
// NewOptions fills in the blanks.
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
options := Options{
|
options := Options{
|
||||||
Logger: logger.DefaultLogger,
|
Logger: logger.DefaultLogger,
|
||||||
@@ -45,14 +45,14 @@ func NewOptions(opts ...Option) Options {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithNamespace specifies the namespace for the handler
|
// WithNamespace specifies the namespace for the handler.
|
||||||
func WithNamespace(s string) Option {
|
func WithNamespace(s string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Namespace = s
|
o.Namespace = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRouter specifies a router to be used by the handler
|
// WithRouter specifies a router to be used by the handler.
|
||||||
func WithRouter(r router.Router) Option {
|
func WithRouter(r router.Router) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Router = r
|
o.Router = r
|
||||||
@@ -65,14 +65,14 @@ func WithClient(c client.Client) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithMaxRecvSize specifies max body size
|
// WithMaxRecvSize specifies max body size.
|
||||||
func WithMaxRecvSize(size int64) Option {
|
func WithMaxRecvSize(size int64) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.MaxRecvSize = size
|
o.MaxRecvSize = size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithLogger specifies the logger
|
// WithLogger specifies the logger.
|
||||||
func WithLogger(l logger.Logger) Option {
|
func WithLogger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
|
@@ -34,14 +34,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// supported json codecs
|
// supported json codecs.
|
||||||
jsonCodecs = []string{
|
jsonCodecs = []string{
|
||||||
"application/grpc+json",
|
"application/grpc+json",
|
||||||
"application/json",
|
"application/json",
|
||||||
"application/json-rpc",
|
"application/json-rpc",
|
||||||
}
|
}
|
||||||
|
|
||||||
// support proto codecs
|
// support proto codecs.
|
||||||
protoCodecs = []string{
|
protoCodecs = []string{
|
||||||
"application/grpc",
|
"application/grpc",
|
||||||
"application/grpc+proto",
|
"application/grpc+proto",
|
||||||
@@ -66,7 +66,7 @@ func (b *buffer) Write(_ []byte) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// strategy is a hack for selection
|
// strategy is a hack for selection.
|
||||||
func strategy(services []*registry.Service) selector.Strategy {
|
func strategy(services []*registry.Service) selector.Strategy {
|
||||||
return func(_ []*registry.Service) selector.Next {
|
return func(_ []*registry.Service) selector.Next {
|
||||||
// ignore input to this function, use services above
|
// ignore input to this function, use services above
|
||||||
@@ -141,7 +141,7 @@ func (h *rpcHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if isStream(r, service) {
|
if isStream(r, service) {
|
||||||
// drop older context as it can have timeouts and create new
|
// drop older context as it can have timeouts and create new
|
||||||
// md, _ := metadata.FromContext(cx)
|
// md, _ := metadata.FromContext(cx)
|
||||||
//serveWebsocket(context.TODO(), w, r, service, c)
|
// serveWebsocket(context.TODO(), w, r, service, c)
|
||||||
if err := serveWebsocket(cx, w, r, service, c); err != nil {
|
if err := serveWebsocket(cx, w, r, service, c); err != nil {
|
||||||
logger.Log(log.ErrorLevel, err)
|
logger.Log(log.ErrorLevel, err)
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ func hasCodec(ct string, codecs []string) bool {
|
|||||||
|
|
||||||
// requestPayload takes a *http.Request.
|
// requestPayload takes a *http.Request.
|
||||||
// If the request is a GET the query string parameters are extracted and marshaled to JSON and the raw bytes are returned.
|
// If the request is a GET the query string parameters are extracted and marshaled to JSON and the raw bytes are returned.
|
||||||
// If the request method is a POST the request body is read and returned
|
// If the request method is a POST the request body is read and returned.
|
||||||
func requestPayload(r *http.Request) ([]byte, error) {
|
func requestPayload(r *http.Request) ([]byte, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -430,7 +430,7 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
|||||||
if jsonbody != nil {
|
if jsonbody != nil {
|
||||||
dstmap[ps[0]] = jsonbody
|
dstmap[ps[0]] = jsonbody
|
||||||
} else {
|
} else {
|
||||||
// old unexpected behaviour
|
// old unexpected behavior
|
||||||
dstmap[ps[0]] = bodybuf
|
dstmap[ps[0]] = bodybuf
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -438,7 +438,7 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
|||||||
if jsonbody != nil {
|
if jsonbody != nil {
|
||||||
em[ps[len(ps)-1]] = jsonbody
|
em[ps[len(ps)-1]] = jsonbody
|
||||||
} else {
|
} else {
|
||||||
// old unexpected behaviour
|
// old unexpected behavior
|
||||||
em[ps[len(ps)-1]] = bodybuf
|
em[ps[len(ps)-1]] = bodybuf
|
||||||
}
|
}
|
||||||
for i := len(ps) - 2; i > 0; i-- {
|
for i := len(ps) - 2; i > 0; i-- {
|
||||||
@@ -460,7 +460,6 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
|||||||
|
|
||||||
//fallback to previous unknown behaviour
|
//fallback to previous unknown behaviour
|
||||||
return bodybuf, nil
|
return bodybuf, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
|
@@ -12,8 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestRequestPayloadFromRequest(t *testing.T) {
|
func TestRequestPayloadFromRequest(t *testing.T) {
|
||||||
|
// our test event so that we can validate serializing / deserializing of true protos works
|
||||||
// our test event so that we can validate serialising / deserializing of true protos works
|
|
||||||
protoEvent := go_api.Event{
|
protoEvent := go_api.Event{
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
}
|
}
|
||||||
@@ -85,7 +84,6 @@ func TestRequestPayloadFromRequest(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("extracting params from a GET request", func(t *testing.T) {
|
t.Run("extracting params from a GET request", func(t *testing.T) {
|
||||||
|
|
||||||
r, err := http.NewRequest("GET", "http://localhost/my/path", nil)
|
r, err := http.NewRequest("GET", "http://localhost/my/path", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to created http.Request: %v", err)
|
t.Fatalf("Failed to created http.Request: %v", err)
|
||||||
@@ -105,7 +103,6 @@ func TestRequestPayloadFromRequest(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("GET request with no params", func(t *testing.T) {
|
t.Run("GET request with no params", func(t *testing.T) {
|
||||||
|
|
||||||
r, err := http.NewRequest("GET", "http://localhost/my/path", nil)
|
r, err := http.NewRequest("GET", "http://localhost/my/path", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to created http.Request: %v", err)
|
t.Fatalf("Failed to created http.Request: %v", err)
|
||||||
|
@@ -19,7 +19,7 @@ import (
|
|||||||
"go-micro.dev/v4/selector"
|
"go-micro.dev/v4/selector"
|
||||||
)
|
)
|
||||||
|
|
||||||
// serveWebsocket will stream rpc back over websockets assuming json
|
// serveWebsocket will stream rpc back over websockets assuming json.
|
||||||
func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request, service *router.Route, c client.Client) (err error) {
|
func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request, service *router.Route, c client.Client) (err error) {
|
||||||
var op ws.OpCode
|
var op ws.OpCode
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ func serveWebsocket(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeLoop
|
// writeLoop.
|
||||||
func writeLoop(rw io.ReadWriter, stream client.Stream) error {
|
func writeLoop(rw io.ReadWriter, stream client.Stream) error {
|
||||||
// close stream when done
|
// close stream when done
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
|
@@ -50,7 +50,7 @@ func (wh *webHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
httputil.NewSingleHostReverseProxy(rp).ServeHTTP(w, r)
|
httputil.NewSingleHostReverseProxy(rp).ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getService returns the service for this request from the selector
|
// getService returns the service for this request from the selector.
|
||||||
func (wh *webHandler) getService(r *http.Request) (string, error) {
|
func (wh *webHandler) getService(r *http.Request) (string, error) {
|
||||||
var service *router.Route
|
var service *router.Route
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ func (wh *webHandler) getService(r *http.Request) (string, error) {
|
|||||||
return fmt.Sprintf("http://%s", s.Address), nil
|
return fmt.Sprintf("http://%s", s.Address), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// serveWebSocket used to serve a web socket proxied connection
|
// serveWebSocket used to serve a web socket proxied connection.
|
||||||
func (wh *webHandler) serveWebSocket(host string, w http.ResponseWriter, r *http.Request) {
|
func (wh *webHandler) serveWebSocket(host string, w http.ResponseWriter, r *http.Request) {
|
||||||
req := new(http.Request)
|
req := new(http.Request)
|
||||||
*req = *r
|
*req = *r
|
||||||
|
@@ -16,7 +16,7 @@ func NewOptions(opts ...Option) Options {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRouter sets the router to use e.g static or registry
|
// WithRouter sets the router to use e.g static or registry.
|
||||||
func WithRouter(r router.Router) Option {
|
func WithRouter(r router.Router) Option {
|
||||||
return func(o *Options) error {
|
return func(o *Options) error {
|
||||||
o.Router = r
|
o.Router = r
|
||||||
|
@@ -4,7 +4,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewOptions returns new initialised options
|
|
||||||
func NewOptions(opts ...Option) Options {
|
func NewOptions(opts ...Option) Options {
|
||||||
var options Options
|
var options Options
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@@ -18,14 +17,14 @@ func NewOptions(opts ...Option) Options {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithHandler sets the handler being used
|
// WithHandler sets the handler being used.
|
||||||
func WithHandler(h string) Option {
|
func WithHandler(h string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Handler = h
|
o.Handler = h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithNamespace sets the function which determines the namespace for a request
|
// WithNamespace sets the function which determines the namespace for a request.
|
||||||
func WithNamespace(n func(*http.Request) string) Option {
|
func WithNamespace(n func(*http.Request) string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Namespace = n
|
o.Namespace = n
|
||||||
|
@@ -11,13 +11,13 @@ var (
|
|||||||
ErrInvalidPath = errors.New("invalid path")
|
ErrInvalidPath = errors.New("invalid path")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resolver resolves requests to endpoints
|
// Resolver resolves requests to endpoints.
|
||||||
type Resolver interface {
|
type Resolver interface {
|
||||||
Resolve(r *http.Request) (*Endpoint, error)
|
Resolve(r *http.Request) (*Endpoint, error)
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endpoint is the endpoint for a http request
|
// Endpoint is the endpoint for a http request.
|
||||||
type Endpoint struct {
|
type Endpoint struct {
|
||||||
// e.g greeter
|
// e.g greeter
|
||||||
Name string
|
Name string
|
||||||
@@ -36,7 +36,7 @@ type Options struct {
|
|||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
// StaticNamespace returns the same namespace for each request
|
// StaticNamespace returns the same namespace for each request.
|
||||||
func StaticNamespace(ns string) func(*http.Request) string {
|
func StaticNamespace(ns string) func(*http.Request) string {
|
||||||
return func(*http.Request) string {
|
return func(*http.Request) string {
|
||||||
return ns
|
return ns
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Package vpath resolves using http path and recognised versioned urls
|
// Package vpath resolves using http path and recognized versioned urls
|
||||||
package vpath
|
package vpath
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -22,7 +22,7 @@ func slice(s string) []string {
|
|||||||
return sl
|
return sl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode encodes an endpoint to endpoint metadata
|
// Encode encodes an endpoint to endpoint metadata.
|
||||||
func Encode(e *Endpoint) map[string]string {
|
func Encode(e *Endpoint) map[string]string {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -49,7 +49,7 @@ func Encode(e *Endpoint) map[string]string {
|
|||||||
return ep
|
return ep
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes endpoint metadata into an endpoint
|
// Decode decodes endpoint metadata into an endpoint.
|
||||||
func Decode(e map[string]string) *Endpoint {
|
func Decode(e map[string]string) *Endpoint {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -65,7 +65,7 @@ func Decode(e map[string]string) *Endpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates an endpoint to guarantee it won't blow up when being served
|
// Validate validates an endpoint to guarantee it won't blow up when being served.
|
||||||
func Validate(e *Endpoint) error {
|
func Validate(e *Endpoint) error {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return errors.New("endpoint is nil")
|
return errors.New("endpoint is nil")
|
||||||
|
@@ -54,7 +54,7 @@ func WithResolver(r resolver.Resolver) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithLogger sets the underline logger
|
// WithLogger sets the underline logger.
|
||||||
func WithLogger(l logger.Logger) Option {
|
func WithLogger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
|
@@ -18,14 +18,14 @@ import (
|
|||||||
"go-micro.dev/v4/registry/cache"
|
"go-micro.dev/v4/registry/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
// endpoint struct, that holds compiled pcre
|
// endpoint struct, that holds compiled pcre.
|
||||||
type endpoint struct {
|
type endpoint struct {
|
||||||
hostregs []*regexp.Regexp
|
hostregs []*regexp.Regexp
|
||||||
pathregs []util.Pattern
|
pathregs []util.Pattern
|
||||||
pcreregs []*regexp.Regexp
|
pcreregs []*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
// router is the default router
|
// router is the default router.
|
||||||
type registryRouter struct {
|
type registryRouter struct {
|
||||||
exit chan bool
|
exit chan bool
|
||||||
opts router.Options
|
opts router.Options
|
||||||
@@ -48,7 +48,7 @@ func (r *registryRouter) isStopped() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh list of api services
|
// refresh list of api services.
|
||||||
func (r *registryRouter) refresh() {
|
func (r *registryRouter) refresh() {
|
||||||
var attempts int
|
var attempts int
|
||||||
logger := r.Options().Logger
|
logger := r.Options().Logger
|
||||||
@@ -84,7 +84,7 @@ func (r *registryRouter) refresh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process watch event
|
// process watch event.
|
||||||
func (r *registryRouter) process(res *registry.Result) {
|
func (r *registryRouter) process(res *registry.Result) {
|
||||||
logger := r.Options().Logger
|
logger := r.Options().Logger
|
||||||
// skip these things
|
// skip these things
|
||||||
@@ -103,7 +103,7 @@ func (r *registryRouter) process(res *registry.Result) {
|
|||||||
r.store(service)
|
r.store(service)
|
||||||
}
|
}
|
||||||
|
|
||||||
// store local endpoint cache
|
// store local endpoint cache.
|
||||||
func (r *registryRouter) store(services []*registry.Service) {
|
func (r *registryRouter) store(services []*registry.Service) {
|
||||||
logger := r.Options().Logger
|
logger := r.Options().Logger
|
||||||
// endpoints
|
// endpoints
|
||||||
@@ -209,7 +209,7 @@ func (r *registryRouter) store(services []*registry.Service) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// watch for endpoint changes
|
// watch for endpoint changes.
|
||||||
func (r *registryRouter) watch() {
|
func (r *registryRouter) watch() {
|
||||||
var attempts int
|
var attempts int
|
||||||
logger := r.Options().Logger
|
logger := r.Options().Logger
|
||||||
@@ -467,7 +467,7 @@ func newRouter(opts ...router.Option) *registryRouter {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter returns the default router
|
// NewRouter returns the default router.
|
||||||
func NewRouter(opts ...router.Option) router.Router {
|
func NewRouter(opts ...router.Option) router.Router {
|
||||||
return newRouter(opts...)
|
return newRouter(opts...)
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Router is used to determine an endpoint for a request
|
// Router is used to determine an endpoint for a request.
|
||||||
type Router interface {
|
type Router interface {
|
||||||
// Returns options
|
// Returns options
|
||||||
Options() Options
|
Options() Options
|
||||||
@@ -30,7 +30,7 @@ type Route struct {
|
|||||||
Versions []*registry.Service
|
Versions []*registry.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endpoint is a mapping between an RPC method and HTTP endpoint
|
// Endpoint is a mapping between an RPC method and HTTP endpoint.
|
||||||
type Endpoint struct {
|
type Endpoint struct {
|
||||||
// RPC Method e.g. Greeter.Hello
|
// RPC Method e.g. Greeter.Hello
|
||||||
Name string
|
Name string
|
||||||
|
@@ -23,7 +23,7 @@ type endpoint struct {
|
|||||||
pcreregs []*regexp.Regexp
|
pcreregs []*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
// router is the default router
|
// router is the default router.
|
||||||
type staticRouter struct {
|
type staticRouter struct {
|
||||||
exit chan bool
|
exit chan bool
|
||||||
opts router.Options
|
opts router.Options
|
||||||
@@ -341,7 +341,7 @@ func NewRouter(opts ...router.Option) *staticRouter {
|
|||||||
opts: options,
|
opts: options,
|
||||||
eps: make(map[string]*endpoint),
|
eps: make(map[string]*endpoint),
|
||||||
}
|
}
|
||||||
//go r.watch()
|
// go r.watch()
|
||||||
//go r.refresh()
|
//go r.refresh()
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ func (e InvalidTemplateError) Error() string {
|
|||||||
return fmt.Sprintf("%s: %s", e.msg, e.tmpl)
|
return fmt.Sprintf("%s: %s", e.msg, e.tmpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse parses the string representation of path template
|
// Parse parses the string representation of path template.
|
||||||
func Parse(tmpl string) (Compiler, error) {
|
func Parse(tmpl string) (Compiler, error) {
|
||||||
if !strings.HasPrefix(tmpl, "/") {
|
if !strings.HasPrefix(tmpl, "/") {
|
||||||
return template{}, InvalidTemplateError{tmpl: tmpl, msg: "no leading /"}
|
return template{}, InvalidTemplateError{tmpl: tmpl, msg: "no leading /"}
|
||||||
|
@@ -7,17 +7,17 @@ type OpCode int
|
|||||||
|
|
||||||
// These constants are the valid values of OpCode.
|
// These constants are the valid values of OpCode.
|
||||||
const (
|
const (
|
||||||
// OpNop does nothing
|
// OpNop does nothing.
|
||||||
OpNop = OpCode(iota)
|
OpNop = OpCode(iota)
|
||||||
// OpPush pushes a component to stack
|
// OpPush pushes a component to stack.
|
||||||
OpPush
|
OpPush
|
||||||
// OpLitPush pushes a component to stack if it matches to the literal
|
// OpLitPush pushes a component to stack if it matches to the literal.
|
||||||
OpLitPush
|
OpLitPush
|
||||||
// OpPushM concatenates the remaining components and pushes it to stack
|
// OpPushM concatenates the remaining components and pushes it to stack.
|
||||||
OpPushM
|
OpPushM
|
||||||
// OpConcatN pops N items from stack, concatenates them and pushes it back to stack
|
// OpConcatN pops N items from stack, concatenates them and pushes it back to stack.
|
||||||
OpConcatN
|
OpConcatN
|
||||||
// OpCapture pops an item and binds it to the variable
|
// OpCapture pops an item and binds it to the variable.
|
||||||
OpCapture
|
OpCapture
|
||||||
// OpEnd is the least positive invalid opcode.
|
// OpEnd is the least positive invalid opcode.
|
||||||
OpEnd
|
OpEnd
|
||||||
|
@@ -49,7 +49,7 @@ type patternOptions struct {
|
|||||||
// PatternOpt is an option for creating Patterns.
|
// PatternOpt is an option for creating Patterns.
|
||||||
type PatternOpt func(*patternOptions)
|
type PatternOpt func(*patternOptions)
|
||||||
|
|
||||||
// Logger sets the logger
|
// Logger sets the logger.
|
||||||
func PatternLogger(l log.Logger) PatternOpt {
|
func PatternLogger(l log.Logger) PatternOpt {
|
||||||
return func(po *patternOptions) {
|
return func(po *patternOptions) {
|
||||||
po.logger = l
|
po.logger = l
|
||||||
|
@@ -9,11 +9,11 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrProviderNotImplemented can be returned when attempting to
|
// ErrProviderNotImplemented can be returned when attempting to
|
||||||
// instantiate an unimplemented provider
|
// instantiate an unimplemented provider.
|
||||||
ErrProviderNotImplemented = errors.New("Provider not implemented")
|
ErrProviderNotImplemented = errors.New("Provider not implemented")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provider is a ACME provider interface
|
// Provider is a ACME provider interface.
|
||||||
type Provider interface {
|
type Provider interface {
|
||||||
// Listen returns a new listener
|
// Listen returns a new listener
|
||||||
Listen(...string) (net.Listener, error)
|
Listen(...string) (net.Listener, error)
|
||||||
@@ -21,7 +21,7 @@ type Provider interface {
|
|||||||
TLSConfig(...string) (*tls.Config, error)
|
TLSConfig(...string) (*tls.Config, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Let's Encrypt ACME endpoints
|
// The Let's Encrypt ACME endpoints.
|
||||||
const (
|
const (
|
||||||
LetsEncryptStagingCA = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
LetsEncryptStagingCA = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
LetsEncryptProductionCA = "https://acme-v02.api.letsencrypt.org/directory"
|
LetsEncryptProductionCA = "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
@@ -13,17 +13,17 @@ import (
|
|||||||
log "go-micro.dev/v4/logger"
|
log "go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// autoCertACME is the ACME provider from golang.org/x/crypto/acme/autocert
|
// autoCertACME is the ACME provider from golang.org/x/crypto/acme/autocert.
|
||||||
type autocertProvider struct {
|
type autocertProvider struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen implements acme.Provider
|
// Listen implements acme.Provider.
|
||||||
func (a *autocertProvider) Listen(hosts ...string) (net.Listener, error) {
|
func (a *autocertProvider) Listen(hosts ...string) (net.Listener, error) {
|
||||||
return autocert.NewListener(hosts...), nil
|
return autocert.NewListener(hosts...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSConfig returns a new tls config
|
// TLSConfig returns a new tls config.
|
||||||
func (a *autocertProvider) TLSConfig(hosts ...string) (*tls.Config, error) {
|
func (a *autocertProvider) TLSConfig(hosts ...string) (*tls.Config, error) {
|
||||||
logger := log.LoggerOrDefault(a.logger)
|
logger := log.LoggerOrDefault(a.logger)
|
||||||
// create a new manager
|
// create a new manager
|
||||||
@@ -42,7 +42,7 @@ func (a *autocertProvider) TLSConfig(hosts ...string) (*tls.Config, error) {
|
|||||||
return m.TLSConfig(), nil
|
return m.TLSConfig(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns an autocert acme.Provider
|
// New returns an autocert acme.Provider.
|
||||||
func NewProvider() acme.Provider {
|
func NewProvider() acme.Provider {
|
||||||
return &autocertProvider{}
|
return &autocertProvider{}
|
||||||
}
|
}
|
||||||
|
@@ -6,10 +6,10 @@ import (
|
|||||||
"go-micro.dev/v4/logger"
|
"go-micro.dev/v4/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Option (or Options) are passed to New() to configure providers
|
// Option (or Options) are passed to New() to configure providers.
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
// Options represents various options you can present to ACME providers
|
// Options represents various options you can present to ACME providers.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// AcceptTLS must be set to true to indicate that you have read your
|
// AcceptTLS must be set to true to indicate that you have read your
|
||||||
// provider's terms of service.
|
// provider's terms of service.
|
||||||
@@ -31,14 +31,14 @@ type Options struct {
|
|||||||
Logger logger.Logger
|
Logger logger.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcceptToS indicates whether you accept your CA's terms of service
|
// AcceptToS indicates whether you accept your CA's terms of service.
|
||||||
func AcceptToS(b bool) Option {
|
func AcceptToS(b bool) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.AcceptToS = b
|
o.AcceptToS = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CA sets the CA of an acme.Options
|
// CA sets the CA of an acme.Options.
|
||||||
func CA(CA string) Option {
|
func CA(CA string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.CA = CA
|
o.CA = CA
|
||||||
@@ -63,14 +63,14 @@ func OnDemand(b bool) Option {
|
|||||||
|
|
||||||
// Cache provides a cache / storage interface to the underlying ACME library
|
// Cache provides a cache / storage interface to the underlying ACME library
|
||||||
// as there is no standard, this needs to be validated by the underlying
|
// as there is no standard, this needs to be validated by the underlying
|
||||||
// implentation.
|
// implementation.
|
||||||
func Cache(c interface{}) Option {
|
func Cache(c interface{}) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Cache = c
|
o.Cache = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger sets the underline logger
|
// Logger sets the underline logger.
|
||||||
func Logger(l logger.Logger) Option {
|
func Logger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
|
@@ -11,7 +11,7 @@ type Config struct {
|
|||||||
AllowHeaders string
|
AllowHeaders string
|
||||||
}
|
}
|
||||||
|
|
||||||
// CombinedCORSHandler wraps a server and provides CORS headers
|
// CombinedCORSHandler wraps a server and provides CORS headers.
|
||||||
func CombinedCORSHandler(h http.Handler, config *Config) http.Handler {
|
func CombinedCORSHandler(h http.Handler, config *Config) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if config != nil {
|
if config != nil {
|
||||||
@@ -25,7 +25,7 @@ func CombinedCORSHandler(h http.Handler, config *Config) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHeaders sets the CORS headers
|
// SetHeaders sets the CORS headers.
|
||||||
func SetHeaders(w http.ResponseWriter, _ *http.Request, config *Config) {
|
func SetHeaders(w http.ResponseWriter, _ *http.Request, config *Config) {
|
||||||
set := func(w http.ResponseWriter, k, v string) {
|
set := func(w http.ResponseWriter, k, v string) {
|
||||||
if v := w.Header().Get(k); len(v) > 0 {
|
if v := w.Header().Get(k); len(v) > 0 {
|
||||||
@@ -33,7 +33,7 @@ func SetHeaders(w http.ResponseWriter, _ *http.Request, config *Config) {
|
|||||||
}
|
}
|
||||||
w.Header().Set(k, v)
|
w.Header().Set(k, v)
|
||||||
}
|
}
|
||||||
//For forward-compatible code, default values may not be provided in the future
|
// For forward-compatible code, default values may not be provided in the future
|
||||||
if config.AllowCredentials {
|
if config.AllowCredentials {
|
||||||
set(w, "Access-Control-Allow-Credentials", "true")
|
set(w, "Access-Control-Allow-Credentials", "true")
|
||||||
} else {
|
} else {
|
||||||
|
@@ -94,7 +94,7 @@ func (s *httpServer) Start() error {
|
|||||||
go func() {
|
go func() {
|
||||||
if err := http.Serve(l, s.mux); err != nil {
|
if err := http.Serve(l, s.mux); err != nil {
|
||||||
// temporary fix
|
// temporary fix
|
||||||
//logger.Log(log.FatalLevel, err)
|
// logger.Log(log.FatalLevel, err)
|
||||||
logger.Log(log.ErrorLevel, err)
|
logger.Log(log.ErrorLevel, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@@ -2,11 +2,12 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go-micro.dev/v4/api/server"
|
|
||||||
"go-micro.dev/v4/api/server/cors"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"go-micro.dev/v4/api/server"
|
||||||
|
"go-micro.dev/v4/api/server/cors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHTTPServer(t *testing.T) {
|
func TestHTTPServer(t *testing.T) {
|
||||||
|
@@ -94,7 +94,7 @@ func Resolver(r resolver.Resolver) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger sets the underline logging framework
|
// Logger sets the underline logging framework.
|
||||||
func Logger(l logger.Logger) Option {
|
func Logger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server serves api requests
|
// Server serves api requests.
|
||||||
type Server interface {
|
type Server interface {
|
||||||
Address() string
|
Address() string
|
||||||
Init(opts ...Option) error
|
Init(opts ...Option) error
|
||||||
|
34
auth/auth.go
34
auth/auth.go
@@ -8,22 +8,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// BearerScheme used for Authorization header
|
// BearerScheme used for Authorization header.
|
||||||
BearerScheme = "Bearer "
|
BearerScheme = "Bearer "
|
||||||
// ScopePublic is the scope applied to a rule to allow access to the public
|
// ScopePublic is the scope applied to a rule to allow access to the public.
|
||||||
ScopePublic = ""
|
ScopePublic = ""
|
||||||
// ScopeAccount is the scope applied to a rule to limit to users with any valid account
|
// ScopeAccount is the scope applied to a rule to limit to users with any valid account.
|
||||||
ScopeAccount = "*"
|
ScopeAccount = "*"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrInvalidToken is when the token provided is not valid
|
// ErrInvalidToken is when the token provided is not valid.
|
||||||
ErrInvalidToken = errors.New("invalid token provided")
|
ErrInvalidToken = errors.New("invalid token provided")
|
||||||
// ErrForbidden is when a user does not have the necessary scope to access a resource
|
// ErrForbidden is when a user does not have the necessary scope to access a resource.
|
||||||
ErrForbidden = errors.New("resource forbidden")
|
ErrForbidden = errors.New("resource forbidden")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Auth provides authentication and authorization
|
// Auth provides authentication and authorization.
|
||||||
type Auth interface {
|
type Auth interface {
|
||||||
// Init the auth
|
// Init the auth
|
||||||
Init(opts ...Option)
|
Init(opts ...Option)
|
||||||
@@ -39,7 +39,7 @@ type Auth interface {
|
|||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rules manages access to resources
|
// Rules manages access to resources.
|
||||||
type Rules interface {
|
type Rules interface {
|
||||||
// Verify an account has access to a resource using the rules
|
// Verify an account has access to a resource using the rules
|
||||||
Verify(acc *Account, res *Resource, opts ...VerifyOption) error
|
Verify(acc *Account, res *Resource, opts ...VerifyOption) error
|
||||||
@@ -51,7 +51,7 @@ type Rules interface {
|
|||||||
List(...ListOption) ([]*Rule, error)
|
List(...ListOption) ([]*Rule, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account provided by an auth provider
|
// Account provided by an auth provider.
|
||||||
type Account struct {
|
type Account struct {
|
||||||
// ID of the account e.g. email
|
// ID of the account e.g. email
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
@@ -67,7 +67,7 @@ type Account struct {
|
|||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token can be short or long lived
|
// Token can be short or long lived.
|
||||||
type Token struct {
|
type Token struct {
|
||||||
// The token to be used for accessing resources
|
// The token to be used for accessing resources
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
@@ -79,12 +79,12 @@ type Token struct {
|
|||||||
Expiry time.Time `json:"expiry"`
|
Expiry time.Time `json:"expiry"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expired returns a boolean indicating if the token needs to be refreshed
|
// Expired returns a boolean indicating if the token needs to be refreshed.
|
||||||
func (t *Token) Expired() bool {
|
func (t *Token) Expired() bool {
|
||||||
return t.Expiry.Unix() < time.Now().Unix()
|
return t.Expiry.Unix() < time.Now().Unix()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resource is an entity such as a user or
|
// Resource is an entity such as a user or.
|
||||||
type Resource struct {
|
type Resource struct {
|
||||||
// Name of the resource, e.g. go.micro.service.notes
|
// Name of the resource, e.g. go.micro.service.notes
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -94,17 +94,17 @@ type Resource struct {
|
|||||||
Endpoint string `json:"endpoint"`
|
Endpoint string `json:"endpoint"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access defines the type of access a rule grants
|
// Access defines the type of access a rule grants.
|
||||||
type Access int
|
type Access int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// AccessGranted to a resource
|
// AccessGranted to a resource.
|
||||||
AccessGranted Access = iota
|
AccessGranted Access = iota
|
||||||
// AccessDenied to a resource
|
// AccessDenied to a resource.
|
||||||
AccessDenied
|
AccessDenied
|
||||||
)
|
)
|
||||||
|
|
||||||
// Rule is used to verify access to a resource
|
// Rule is used to verify access to a resource.
|
||||||
type Rule struct {
|
type Rule struct {
|
||||||
// ID of the rule, e.g. "public"
|
// ID of the rule, e.g. "public"
|
||||||
ID string
|
ID string
|
||||||
@@ -125,13 +125,13 @@ type accountKey struct{}
|
|||||||
// AccountFromContext gets the account from the context, which
|
// AccountFromContext gets the account from the context, which
|
||||||
// is set by the auth wrapper at the start of a call. If the account
|
// is set by the auth wrapper at the start of a call. If the account
|
||||||
// is not set, a nil account will be returned. The error is only returned
|
// is not set, a nil account will be returned. The error is only returned
|
||||||
// when there was a problem retrieving an account
|
// when there was a problem retrieving an account.
|
||||||
func AccountFromContext(ctx context.Context) (*Account, bool) {
|
func AccountFromContext(ctx context.Context) (*Account, bool) {
|
||||||
acc, ok := ctx.Value(accountKey{}).(*Account)
|
acc, ok := ctx.Value(accountKey{}).(*Account)
|
||||||
return acc, ok
|
return acc, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContextWithAccount sets the account in the context
|
// ContextWithAccount sets the account in the context.
|
||||||
func ContextWithAccount(ctx context.Context, account *Account) context.Context {
|
func ContextWithAccount(ctx context.Context, account *Account) context.Context {
|
||||||
return context.WithValue(ctx, accountKey{}, account)
|
return context.WithValue(ctx, accountKey{}, account)
|
||||||
}
|
}
|
||||||
|
18
auth/noop.go
18
auth/noop.go
@@ -30,24 +30,24 @@ type noop struct {
|
|||||||
|
|
||||||
type noopRules struct{}
|
type noopRules struct{}
|
||||||
|
|
||||||
// String returns the name of the implementation
|
// String returns the name of the implementation.
|
||||||
func (n *noop) String() string {
|
func (n *noop) String() string {
|
||||||
return "noop"
|
return "noop"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init the auth
|
// Init the auth.
|
||||||
func (n *noop) Init(opts ...Option) {
|
func (n *noop) Init(opts ...Option) {
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&n.opts)
|
o(&n.opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options set for auth
|
// Options set for auth.
|
||||||
func (n *noop) Options() Options {
|
func (n *noop) Options() Options {
|
||||||
return n.opts
|
return n.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a new account
|
// Generate a new account.
|
||||||
func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, error) {
|
func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, error) {
|
||||||
options := NewGenerateOptions(opts...)
|
options := NewGenerateOptions(opts...)
|
||||||
|
|
||||||
@@ -60,18 +60,18 @@ func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grant access to a resource
|
// Grant access to a resource.
|
||||||
func (n *noopRules) Grant(rule *Rule) error {
|
func (n *noopRules) Grant(rule *Rule) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revoke access to a resource
|
// Revoke access to a resource.
|
||||||
func (n *noopRules) Revoke(rule *Rule) error {
|
func (n *noopRules) Revoke(rule *Rule) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rules used to verify requests
|
// Rules used to verify requests
|
||||||
// Verify an account has access to a resource
|
// Verify an account has access to a resource.
|
||||||
func (n *noopRules) Verify(acc *Account, res *Resource, opts ...VerifyOption) error {
|
func (n *noopRules) Verify(acc *Account, res *Resource, opts ...VerifyOption) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -80,12 +80,12 @@ func (n *noopRules) List(opts ...ListOption) ([]*Rule, error) {
|
|||||||
return []*Rule{}, nil
|
return []*Rule{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspect a token
|
// Inspect a token.
|
||||||
func (n *noop) Inspect(token string) (*Account, error) {
|
func (n *noop) Inspect(token string) (*Account, error) {
|
||||||
return &Account{ID: uuid.New().String(), Issuer: n.Options().Namespace}, nil
|
return &Account{ID: uuid.New().String(), Issuer: n.Options().Namespace}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token generation using an account id and secret
|
// Token generation using an account id and secret.
|
||||||
func (n *noop) Token(opts ...TokenOption) (*Token, error) {
|
func (n *noop) Token(opts ...TokenOption) (*Token, error) {
|
||||||
return &Token{}, nil
|
return &Token{}, nil
|
||||||
}
|
}
|
||||||
|
@@ -40,42 +40,42 @@ type Options struct {
|
|||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
// Addrs is the auth addresses to use
|
// Addrs is the auth addresses to use.
|
||||||
func Addrs(addrs ...string) Option {
|
func Addrs(addrs ...string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Addrs = addrs
|
o.Addrs = addrs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Namespace the service belongs to
|
// Namespace the service belongs to.
|
||||||
func Namespace(n string) Option {
|
func Namespace(n string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Namespace = n
|
o.Namespace = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKey is the JWT public key
|
// PublicKey is the JWT public key.
|
||||||
func PublicKey(key string) Option {
|
func PublicKey(key string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.PublicKey = key
|
o.PublicKey = key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrivateKey is the JWT private key
|
// PrivateKey is the JWT private key.
|
||||||
func PrivateKey(key string) Option {
|
func PrivateKey(key string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.PrivateKey = key
|
o.PrivateKey = key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithLogger sets the underline logger
|
// WithLogger sets the underline logger.
|
||||||
func WithLogger(l logger.Logger) Option {
|
func WithLogger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Credentials sets the auth credentials
|
// Credentials sets the auth credentials.
|
||||||
func Credentials(id, secret string) Option {
|
func Credentials(id, secret string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.ID = id
|
o.ID = id
|
||||||
@@ -83,7 +83,7 @@ func Credentials(id, secret string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientToken sets the auth token to use when making requests
|
// ClientToken sets the auth token to use when making requests.
|
||||||
func ClientToken(token *Token) Option {
|
func ClientToken(token *Token) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Token = token
|
o.Token = token
|
||||||
@@ -105,42 +105,42 @@ type GenerateOptions struct {
|
|||||||
|
|
||||||
type GenerateOption func(o *GenerateOptions)
|
type GenerateOption func(o *GenerateOptions)
|
||||||
|
|
||||||
// WithSecret for the generated account
|
// WithSecret for the generated account.
|
||||||
func WithSecret(s string) GenerateOption {
|
func WithSecret(s string) GenerateOption {
|
||||||
return func(o *GenerateOptions) {
|
return func(o *GenerateOptions) {
|
||||||
o.Secret = s
|
o.Secret = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithType for the generated account
|
// WithType for the generated account.
|
||||||
func WithType(t string) GenerateOption {
|
func WithType(t string) GenerateOption {
|
||||||
return func(o *GenerateOptions) {
|
return func(o *GenerateOptions) {
|
||||||
o.Type = t
|
o.Type = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithMetadata for the generated account
|
// WithMetadata for the generated account.
|
||||||
func WithMetadata(md map[string]string) GenerateOption {
|
func WithMetadata(md map[string]string) GenerateOption {
|
||||||
return func(o *GenerateOptions) {
|
return func(o *GenerateOptions) {
|
||||||
o.Metadata = md
|
o.Metadata = md
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithProvider for the generated account
|
// WithProvider for the generated account.
|
||||||
func WithProvider(p string) GenerateOption {
|
func WithProvider(p string) GenerateOption {
|
||||||
return func(o *GenerateOptions) {
|
return func(o *GenerateOptions) {
|
||||||
o.Provider = p
|
o.Provider = p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithScopes for the generated account
|
// WithScopes for the generated account.
|
||||||
func WithScopes(s ...string) GenerateOption {
|
func WithScopes(s ...string) GenerateOption {
|
||||||
return func(o *GenerateOptions) {
|
return func(o *GenerateOptions) {
|
||||||
o.Scopes = s
|
o.Scopes = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGenerateOptions from a slice of options
|
// NewGenerateOptions from a slice of options.
|
||||||
func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
|
func NewGenerateOptions(opts ...GenerateOption) GenerateOptions {
|
||||||
var options GenerateOptions
|
var options GenerateOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@@ -162,7 +162,7 @@ type TokenOptions struct {
|
|||||||
|
|
||||||
type TokenOption func(o *TokenOptions)
|
type TokenOption func(o *TokenOptions)
|
||||||
|
|
||||||
// WithExpiry for the token
|
// WithExpiry for the token.
|
||||||
func WithExpiry(ex time.Duration) TokenOption {
|
func WithExpiry(ex time.Duration) TokenOption {
|
||||||
return func(o *TokenOptions) {
|
return func(o *TokenOptions) {
|
||||||
o.Expiry = ex
|
o.Expiry = ex
|
||||||
@@ -182,14 +182,14 @@ func WithToken(rt string) TokenOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTokenOptions from a slice of options
|
// NewTokenOptions from a slice of options.
|
||||||
func NewTokenOptions(opts ...TokenOption) TokenOptions {
|
func NewTokenOptions(opts ...TokenOption) TokenOptions {
|
||||||
var options TokenOptions
|
var options TokenOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&options)
|
o(&options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set defualt expiry of token
|
// set default expiry of token
|
||||||
if options.Expiry == 0 {
|
if options.Expiry == 0 {
|
||||||
options.Expiry = time.Minute
|
options.Expiry = time.Minute
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
// Verify an account has access to a resource using the rules provided. If the account does not have
|
// Verify an account has access to a resource using the rules provided. If the account does not have
|
||||||
// access an error will be returned. If there are no rules provided which match the resource, an error
|
// access an error will be returned. If there are no rules provided which match the resource, an error
|
||||||
// will be returned
|
// will be returned.
|
||||||
func Verify(rules []*Rule, acc *Account, res *Resource) error {
|
func Verify(rules []*Rule, acc *Account, res *Resource) error {
|
||||||
// the rule is only to be applied if the type matches the resource or is catch-all (*)
|
// the rule is only to be applied if the type matches the resource or is catch-all (*)
|
||||||
validTypes := []string{"*", res.Type}
|
validTypes := []string{"*", res.Type}
|
||||||
|
@@ -42,7 +42,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "",
|
Scope: "",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
},
|
},
|
||||||
@@ -52,7 +52,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Name: "CatchallPublicNoAccount",
|
Name: "CatchallPublicNoAccount",
|
||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "",
|
Scope: "",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
},
|
},
|
||||||
@@ -63,7 +63,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
},
|
},
|
||||||
@@ -73,7 +73,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Name: "CatchallPrivateNoAccount",
|
Name: "CatchallPrivateNoAccount",
|
||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
},
|
},
|
||||||
@@ -85,7 +85,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: &Resource{
|
Resource: &Resource{
|
||||||
Type: srvResource.Type,
|
Type: srvResource.Type,
|
||||||
@@ -100,7 +100,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: &Resource{
|
Resource: &Resource{
|
||||||
Type: srvResource.Type,
|
Type: srvResource.Type,
|
||||||
@@ -118,7 +118,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Scopes: []string{"neededscope"},
|
Scopes: []string{"neededscope"},
|
||||||
},
|
},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "neededscope",
|
Scope: "neededscope",
|
||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
},
|
},
|
||||||
@@ -131,7 +131,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Scopes: []string{"neededscope"},
|
Scopes: []string{"neededscope"},
|
||||||
},
|
},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "invalidscope",
|
Scope: "invalidscope",
|
||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
},
|
},
|
||||||
@@ -143,7 +143,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
Access: AccessDenied,
|
Access: AccessDenied,
|
||||||
@@ -156,7 +156,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
Access: AccessDenied,
|
Access: AccessDenied,
|
||||||
@@ -169,13 +169,13 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
Access: AccessGranted,
|
Access: AccessGranted,
|
||||||
Priority: 1,
|
Priority: 1,
|
||||||
},
|
},
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
Access: AccessDenied,
|
Access: AccessDenied,
|
||||||
@@ -188,13 +188,13 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: srvResource,
|
Resource: srvResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
Access: AccessGranted,
|
Access: AccessGranted,
|
||||||
Priority: 0,
|
Priority: 0,
|
||||||
},
|
},
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: catchallResource,
|
Resource: catchallResource,
|
||||||
Access: AccessDenied,
|
Access: AccessDenied,
|
||||||
@@ -208,7 +208,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: webResource,
|
Resource: webResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: webResource,
|
Resource: webResource,
|
||||||
},
|
},
|
||||||
@@ -219,7 +219,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: webResource,
|
Resource: webResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: &Resource{
|
Resource: &Resource{
|
||||||
Type: webResource.Type,
|
Type: webResource.Type,
|
||||||
@@ -235,7 +235,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: webResource,
|
Resource: webResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: &Resource{
|
Resource: &Resource{
|
||||||
Type: webResource.Type,
|
Type: webResource.Type,
|
||||||
@@ -250,7 +250,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: webResource,
|
Resource: webResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: &Resource{
|
Resource: &Resource{
|
||||||
Type: webResource.Type,
|
Type: webResource.Type,
|
||||||
@@ -265,7 +265,7 @@ func TestVerify(t *testing.T) {
|
|||||||
Resource: webResource,
|
Resource: webResource,
|
||||||
Account: &Account{},
|
Account: &Account{},
|
||||||
Rules: []*Rule{
|
Rules: []*Rule{
|
||||||
&Rule{
|
{
|
||||||
Scope: "*",
|
Scope: "*",
|
||||||
Resource: &Resource{
|
Resource: &Resource{
|
||||||
Type: webResource.Type,
|
Type: webResource.Type,
|
||||||
|
@@ -23,7 +23,7 @@ type Message struct {
|
|||||||
Body []byte
|
Body []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event is given to a subscription handler for processing
|
// Event is given to a subscription handler for processing.
|
||||||
type Event interface {
|
type Event interface {
|
||||||
Topic() string
|
Topic() string
|
||||||
Message() *Message
|
Message() *Message
|
||||||
@@ -31,7 +31,7 @@ type Event interface {
|
|||||||
Error() error
|
Error() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscriber is a convenience return type for the Subscribe method
|
// Subscriber is a convenience return type for the Subscribe method.
|
||||||
type Subscriber interface {
|
type Subscriber interface {
|
||||||
Options() SubscribeOptions
|
Options() SubscribeOptions
|
||||||
Topic() string
|
Topic() string
|
||||||
|
@@ -27,7 +27,7 @@ import (
|
|||||||
mls "go-micro.dev/v4/util/tls"
|
mls "go-micro.dev/v4/util/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTP Broker is a point to point async broker
|
// HTTP Broker is a point to point async broker.
|
||||||
type httpBroker struct {
|
type httpBroker struct {
|
||||||
id string
|
id string
|
||||||
address string
|
address string
|
||||||
@@ -315,7 +315,7 @@ func (h *httpBroker) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
topic := m.Header["Micro-Topic"]
|
topic := m.Header["Micro-Topic"]
|
||||||
//delete(m.Header, ":topic")
|
// delete(m.Header, ":topic")
|
||||||
|
|
||||||
if len(topic) == 0 {
|
if len(topic) == 0 {
|
||||||
errr := merr.InternalServerError("go.micro.broker", "Topic not found")
|
errr := merr.InternalServerError("go.micro.broker", "Topic not found")
|
||||||
@@ -703,7 +703,7 @@ func (h *httpBroker) String() string {
|
|||||||
return "http"
|
return "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBroker returns a new http broker
|
// NewBroker returns a new http broker.
|
||||||
func NewBroker(opts ...Option) Broker {
|
func NewBroker(opts ...Option) Broker {
|
||||||
return newHttpBroker(opts...)
|
return newHttpBroker(opts...)
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// mock data
|
// mock data.
|
||||||
testData = map[string][]*registry.Service{
|
testData = map[string][]*registry.Service{
|
||||||
"foo": {
|
"foo": {
|
||||||
{
|
{
|
||||||
|
@@ -53,7 +53,7 @@ type Option func(*Options)
|
|||||||
|
|
||||||
type PublishOption func(*PublishOptions)
|
type PublishOption func(*PublishOptions)
|
||||||
|
|
||||||
// PublishContext set context
|
// PublishContext set context.
|
||||||
func PublishContext(ctx context.Context) PublishOption {
|
func PublishContext(ctx context.Context) PublishOption {
|
||||||
return func(o *PublishOptions) {
|
return func(o *PublishOptions) {
|
||||||
o.Context = ctx
|
o.Context = ctx
|
||||||
@@ -87,7 +87,7 @@ func NewSubscribeOptions(opts ...SubscribeOption) SubscribeOptions {
|
|||||||
return opt
|
return opt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addrs sets the host addresses to be used by the broker
|
// Addrs sets the host addresses to be used by the broker.
|
||||||
func Addrs(addrs ...string) Option {
|
func Addrs(addrs ...string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Addrs = addrs
|
o.Addrs = addrs
|
||||||
@@ -95,7 +95,7 @@ func Addrs(addrs ...string) Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Codec sets the codec used for encoding/decoding used where
|
// Codec sets the codec used for encoding/decoding used where
|
||||||
// a broker does not support headers
|
// a broker does not support headers.
|
||||||
func Codec(c codec.Marshaler) Option {
|
func Codec(c codec.Marshaler) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Codec = c
|
o.Codec = c
|
||||||
@@ -111,14 +111,14 @@ func DisableAutoAck() SubscribeOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ErrorHandler will catch all broker errors that cant be handled
|
// ErrorHandler will catch all broker errors that cant be handled
|
||||||
// in normal way, for example Codec errors
|
// in normal way, for example Codec errors.
|
||||||
func ErrorHandler(h Handler) Option {
|
func ErrorHandler(h Handler) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.ErrorHandler = h
|
o.ErrorHandler = h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue sets the name of the queue to share messages on
|
// Queue sets the name of the queue to share messages on.
|
||||||
func Queue(name string) SubscribeOption {
|
func Queue(name string) SubscribeOption {
|
||||||
return func(o *SubscribeOptions) {
|
return func(o *SubscribeOptions) {
|
||||||
o.Queue = name
|
o.Queue = name
|
||||||
@@ -131,28 +131,28 @@ func Registry(r registry.Registry) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secure communication with the broker
|
// Secure communication with the broker.
|
||||||
func Secure(b bool) Option {
|
func Secure(b bool) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Secure = b
|
o.Secure = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify TLS Config
|
// Specify TLS Config.
|
||||||
func TLSConfig(t *tls.Config) Option {
|
func TLSConfig(t *tls.Config) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.TLSConfig = t
|
o.TLSConfig = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger sets the underline logger
|
// Logger sets the underline logger.
|
||||||
func Logger(l logger.Logger) Option {
|
func Logger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubscribeContext set context
|
// SubscribeContext set context.
|
||||||
func SubscribeContext(ctx context.Context) SubscribeOption {
|
func SubscribeContext(ctx context.Context) SubscribeOption {
|
||||||
return func(o *SubscribeOptions) {
|
return func(o *SubscribeOptions) {
|
||||||
o.Context = ctx
|
o.Context = ctx
|
||||||
|
6
cache/options.go
vendored
6
cache/options.go
vendored
@@ -36,21 +36,21 @@ func Items(i map[string]Item) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithAddress sets the cache service address or connection information
|
// WithAddress sets the cache service address or connection information.
|
||||||
func WithAddress(addr string) Option {
|
func WithAddress(addr string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Address = addr
|
o.Address = addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithContext sets the cache context, for any extra configuration
|
// WithContext sets the cache context, for any extra configuration.
|
||||||
func WithContext(c context.Context) Option {
|
func WithContext(c context.Context) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Context = c
|
o.Context = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithLogger sets underline logger
|
// WithLogger sets underline logger.
|
||||||
func WithLogger(l logger.Logger) Option {
|
func WithLogger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
|
@@ -11,29 +11,29 @@ import (
|
|||||||
"go-micro.dev/v4/metadata"
|
"go-micro.dev/v4/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCache returns an initialised cache.
|
// NewCache returns an initialized cache.
|
||||||
func NewCache() *Cache {
|
func NewCache() *Cache {
|
||||||
return &Cache{
|
return &Cache{
|
||||||
cache: cache.New(cache.NoExpiration, 30*time.Second),
|
cache: cache.New(cache.NoExpiration, 30*time.Second),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache for responses
|
// Cache for responses.
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
cache *cache.Cache
|
cache *cache.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a response from the cache
|
// Get a response from the cache.
|
||||||
func (c *Cache) Get(ctx context.Context, req *Request) (interface{}, bool) {
|
func (c *Cache) Get(ctx context.Context, req *Request) (interface{}, bool) {
|
||||||
return c.cache.Get(key(ctx, req))
|
return c.cache.Get(key(ctx, req))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a response in the cache
|
// Set a response in the cache.
|
||||||
func (c *Cache) Set(ctx context.Context, req *Request, rsp interface{}, expiry time.Duration) {
|
func (c *Cache) Set(ctx context.Context, req *Request, rsp interface{}, expiry time.Duration) {
|
||||||
c.cache.Set(key(ctx, req), rsp, expiry)
|
c.cache.Set(key(ctx, req), rsp, expiry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// List the key value pairs in the cache
|
// List the key value pairs in the cache.
|
||||||
func (c *Cache) List() map[string]string {
|
func (c *Cache) List() map[string]string {
|
||||||
items := c.cache.Items()
|
items := c.cache.Items()
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func (c *Cache) List() map[string]string {
|
|||||||
return rsp
|
return rsp
|
||||||
}
|
}
|
||||||
|
|
||||||
// key returns a hash for the context and request
|
// key returns a hash for the context and request.
|
||||||
func key(ctx context.Context, req *Request) string {
|
func key(ctx context.Context, req *Request) string {
|
||||||
ns, _ := metadata.Get(ctx, "Micro-Namespace")
|
ns, _ := metadata.Get(ctx, "Micro-Namespace")
|
||||||
|
|
||||||
|
@@ -22,19 +22,19 @@ type Client interface {
|
|||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Router manages request routing
|
// Router manages request routing.
|
||||||
type Router interface {
|
type Router interface {
|
||||||
SendRequest(context.Context, Request) (Response, error)
|
SendRequest(context.Context, Request) (Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message is the interface for publishing asynchronously
|
// Message is the interface for publishing asynchronously.
|
||||||
type Message interface {
|
type Message interface {
|
||||||
Topic() string
|
Topic() string
|
||||||
Payload() interface{}
|
Payload() interface{}
|
||||||
ContentType() string
|
ContentType() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request is the interface for a synchronous request used by Call or Stream
|
// Request is the interface for a synchronous request used by Call or Stream.
|
||||||
type Request interface {
|
type Request interface {
|
||||||
// The service to call
|
// The service to call
|
||||||
Service() string
|
Service() string
|
||||||
@@ -52,7 +52,7 @@ type Request interface {
|
|||||||
Stream() bool
|
Stream() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response is the response received from a service
|
// Response is the response received from a service.
|
||||||
type Response interface {
|
type Response interface {
|
||||||
// Read the response
|
// Read the response
|
||||||
Codec() codec.Reader
|
Codec() codec.Reader
|
||||||
@@ -62,7 +62,7 @@ type Response interface {
|
|||||||
Read() ([]byte, error)
|
Read() ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream is the inteface for a bidirectional synchronous stream
|
// Stream is the inteface for a bidirectional synchronous stream.
|
||||||
type Stream interface {
|
type Stream interface {
|
||||||
Closer
|
Closer
|
||||||
// Context for the stream
|
// Context for the stream
|
||||||
@@ -81,48 +81,48 @@ type Stream interface {
|
|||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closer handle client close
|
// Closer handle client close.
|
||||||
type Closer interface {
|
type Closer interface {
|
||||||
// CloseSend closes the send direction of the stream.
|
// CloseSend closes the send direction of the stream.
|
||||||
CloseSend() error
|
CloseSend() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option used by the Client
|
// Option used by the Client.
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
|
|
||||||
// CallOption used by Call or Stream
|
// CallOption used by Call or Stream.
|
||||||
type CallOption func(*CallOptions)
|
type CallOption func(*CallOptions)
|
||||||
|
|
||||||
// PublishOption used by Publish
|
// PublishOption used by Publish.
|
||||||
type PublishOption func(*PublishOptions)
|
type PublishOption func(*PublishOptions)
|
||||||
|
|
||||||
// MessageOption used by NewMessage
|
// MessageOption used by NewMessage.
|
||||||
type MessageOption func(*MessageOptions)
|
type MessageOption func(*MessageOptions)
|
||||||
|
|
||||||
// RequestOption used by NewRequest
|
// RequestOption used by NewRequest.
|
||||||
type RequestOption func(*RequestOptions)
|
type RequestOption func(*RequestOptions)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// DefaultClient is a default client to use out of the box
|
// DefaultClient is a default client to use out of the box.
|
||||||
DefaultClient Client = newRpcClient()
|
DefaultClient Client = newRpcClient()
|
||||||
// DefaultBackoff is the default backoff function for retries
|
// DefaultBackoff is the default backoff function for retries.
|
||||||
DefaultBackoff = exponentialBackoff
|
DefaultBackoff = exponentialBackoff
|
||||||
// DefaultRetry is the default check-for-retry function for retries
|
// DefaultRetry is the default check-for-retry function for retries.
|
||||||
DefaultRetry = RetryOnError
|
DefaultRetry = RetryOnError
|
||||||
// DefaultRetries is the default number of times a request is tried
|
// DefaultRetries is the default number of times a request is tried.
|
||||||
DefaultRetries = 1
|
DefaultRetries = 1
|
||||||
// DefaultRequestTimeout is the default request timeout
|
// DefaultRequestTimeout is the default request timeout.
|
||||||
DefaultRequestTimeout = time.Second * 5
|
DefaultRequestTimeout = time.Second * 5
|
||||||
// DefaultPoolSize sets the connection pool size
|
// DefaultPoolSize sets the connection pool size.
|
||||||
DefaultPoolSize = 100
|
DefaultPoolSize = 100
|
||||||
// DefaultPoolTTL sets the connection pool ttl
|
// DefaultPoolTTL sets the connection pool ttl.
|
||||||
DefaultPoolTTL = time.Minute
|
DefaultPoolTTL = time.Minute
|
||||||
|
|
||||||
// NewClient returns a new client
|
// NewClient returns a new client.
|
||||||
NewClient func(...Option) Client = newRpcClient
|
NewClient func(...Option) Client = newRpcClient
|
||||||
)
|
)
|
||||||
|
|
||||||
// Makes a synchronous call to a service using the default client
|
// Makes a synchronous call to a service using the default client.
|
||||||
func Call(ctx context.Context, request Request, response interface{}, opts ...CallOption) error {
|
func Call(ctx context.Context, request Request, response interface{}, opts ...CallOption) error {
|
||||||
return DefaultClient.Call(ctx, request, response, opts...)
|
return DefaultClient.Call(ctx, request, response, opts...)
|
||||||
}
|
}
|
||||||
@@ -133,13 +133,13 @@ func Publish(ctx context.Context, msg Message, opts ...PublishOption) error {
|
|||||||
return DefaultClient.Publish(ctx, msg, opts...)
|
return DefaultClient.Publish(ctx, msg, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new message using the default client
|
// Creates a new message using the default client.
|
||||||
func NewMessage(topic string, payload interface{}, opts ...MessageOption) Message {
|
func NewMessage(topic string, payload interface{}, opts ...MessageOption) Message {
|
||||||
return DefaultClient.NewMessage(topic, payload, opts...)
|
return DefaultClient.NewMessage(topic, payload, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new request using the default client. Content Type will
|
// Creates a new request using the default client. Content Type will
|
||||||
// be set to the default within options and use the appropriate codec
|
// be set to the default within options and use the appropriate codec.
|
||||||
func NewRequest(service, endpoint string, request interface{}, reqOpts ...RequestOption) Request {
|
func NewRequest(service, endpoint string, request interface{}, reqOpts ...RequestOption) Request {
|
||||||
return DefaultClient.NewRequest(service, endpoint, request, reqOpts...)
|
return DefaultClient.NewRequest(service, endpoint, request, reqOpts...)
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// mock data
|
// mock data.
|
||||||
testData = map[string][]*registry.Service{
|
testData = map[string][]*registry.Service{
|
||||||
"foo": {
|
"foo": {
|
||||||
{
|
{
|
||||||
|
@@ -127,42 +127,42 @@ func NewOptions(options ...Option) Options {
|
|||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broker to be used for pub/sub
|
// Broker to be used for pub/sub.
|
||||||
func Broker(b broker.Broker) Option {
|
func Broker(b broker.Broker) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Broker = b
|
o.Broker = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Codec to be used to encode/decode requests for a given content type
|
// Codec to be used to encode/decode requests for a given content type.
|
||||||
func Codec(contentType string, c codec.NewCodec) Option {
|
func Codec(contentType string, c codec.NewCodec) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Codecs[contentType] = c
|
o.Codecs[contentType] = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default content type of the client
|
// Default content type of the client.
|
||||||
func ContentType(ct string) Option {
|
func ContentType(ct string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.ContentType = ct
|
o.ContentType = ct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoolSize sets the connection pool size
|
// PoolSize sets the connection pool size.
|
||||||
func PoolSize(d int) Option {
|
func PoolSize(d int) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.PoolSize = d
|
o.PoolSize = d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoolTTL sets the connection pool ttl
|
// PoolTTL sets the connection pool ttl.
|
||||||
func PoolTTL(d time.Duration) Option {
|
func PoolTTL(d time.Duration) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.PoolTTL = d
|
o.PoolTTL = d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registry to find nodes for a given service
|
// Registry to find nodes for a given service.
|
||||||
func Registry(r registry.Registry) Option {
|
func Registry(r registry.Registry) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Registry = r
|
o.Registry = r
|
||||||
@@ -171,28 +171,28 @@ func Registry(r registry.Registry) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transport to use for communication e.g http, rabbitmq, etc
|
// Transport to use for communication e.g http, rabbitmq, etc.
|
||||||
func Transport(t transport.Transport) Option {
|
func Transport(t transport.Transport) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Transport = t
|
o.Transport = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select is used to select a node to route a request to
|
// Select is used to select a node to route a request to.
|
||||||
func Selector(s selector.Selector) Option {
|
func Selector(s selector.Selector) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Selector = s
|
o.Selector = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a Wrapper to a list of options passed into the client
|
// Adds a Wrapper to a list of options passed into the client.
|
||||||
func Wrap(w Wrapper) Option {
|
func Wrap(w Wrapper) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Wrappers = append(o.Wrappers, w)
|
o.Wrappers = append(o.Wrappers, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a Wrapper to the list of CallFunc wrappers
|
// Adds a Wrapper to the list of CallFunc wrappers.
|
||||||
func WrapCall(cw ...CallWrapper) Option {
|
func WrapCall(cw ...CallWrapper) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.CallOptions.CallWrappers = append(o.CallOptions.CallWrappers, cw...)
|
o.CallOptions.CallWrappers = append(o.CallOptions.CallWrappers, cw...)
|
||||||
@@ -200,7 +200,7 @@ func WrapCall(cw ...CallWrapper) Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Backoff is used to set the backoff function used
|
// Backoff is used to set the backoff function used
|
||||||
// when retrying Calls
|
// when retrying Calls.
|
||||||
func Backoff(fn BackoffFunc) Option {
|
func Backoff(fn BackoffFunc) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.CallOptions.Backoff = fn
|
o.CallOptions.Backoff = fn
|
||||||
@@ -230,14 +230,14 @@ func RequestTimeout(d time.Duration) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StreamTimeout sets the stream timeout
|
// StreamTimeout sets the stream timeout.
|
||||||
func StreamTimeout(d time.Duration) Option {
|
func StreamTimeout(d time.Duration) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.CallOptions.StreamTimeout = d
|
o.CallOptions.StreamTimeout = d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transport dial timeout
|
// Transport dial timeout.
|
||||||
func DialTimeout(d time.Duration) Option {
|
func DialTimeout(d time.Duration) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.CallOptions.DialTimeout = d
|
o.CallOptions.DialTimeout = d
|
||||||
@@ -246,21 +246,21 @@ func DialTimeout(d time.Duration) Option {
|
|||||||
|
|
||||||
// Call Options
|
// Call Options
|
||||||
|
|
||||||
// WithExchange sets the exchange to route a message through
|
// WithExchange sets the exchange to route a message through.
|
||||||
func WithExchange(e string) PublishOption {
|
func WithExchange(e string) PublishOption {
|
||||||
return func(o *PublishOptions) {
|
return func(o *PublishOptions) {
|
||||||
o.Exchange = e
|
o.Exchange = e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublishContext sets the context in publish options
|
// PublishContext sets the context in publish options.
|
||||||
func PublishContext(ctx context.Context) PublishOption {
|
func PublishContext(ctx context.Context) PublishOption {
|
||||||
return func(o *PublishOptions) {
|
return func(o *PublishOptions) {
|
||||||
o.Context = ctx
|
o.Context = ctx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithAddress sets the remote addresses to use rather than using service discovery
|
// WithAddress sets the remote addresses to use rather than using service discovery.
|
||||||
func WithAddress(a ...string) CallOption {
|
func WithAddress(a ...string) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.Address = a
|
o.Address = a
|
||||||
@@ -273,7 +273,7 @@ func WithSelectOption(so ...selector.SelectOption) CallOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCallWrapper is a CallOption which adds to the existing CallFunc wrappers
|
// WithCallWrapper is a CallOption which adds to the existing CallFunc wrappers.
|
||||||
func WithCallWrapper(cw ...CallWrapper) CallOption {
|
func WithCallWrapper(cw ...CallWrapper) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.CallWrappers = append(o.CallWrappers, cw...)
|
o.CallWrappers = append(o.CallWrappers, cw...)
|
||||||
@@ -281,7 +281,7 @@ func WithCallWrapper(cw ...CallWrapper) CallOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithBackoff is a CallOption which overrides that which
|
// WithBackoff is a CallOption which overrides that which
|
||||||
// set in Options.CallOptions
|
// set in Options.CallOptions.
|
||||||
func WithBackoff(fn BackoffFunc) CallOption {
|
func WithBackoff(fn BackoffFunc) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.Backoff = fn
|
o.Backoff = fn
|
||||||
@@ -289,7 +289,7 @@ func WithBackoff(fn BackoffFunc) CallOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithRetry is a CallOption which overrides that which
|
// WithRetry is a CallOption which overrides that which
|
||||||
// set in Options.CallOptions
|
// set in Options.CallOptions.
|
||||||
func WithRetry(fn RetryFunc) CallOption {
|
func WithRetry(fn RetryFunc) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.Retry = fn
|
o.Retry = fn
|
||||||
@@ -297,7 +297,7 @@ func WithRetry(fn RetryFunc) CallOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithRetries is a CallOption which overrides that which
|
// WithRetries is a CallOption which overrides that which
|
||||||
// set in Options.CallOptions
|
// set in Options.CallOptions.
|
||||||
func WithRetries(i int) CallOption {
|
func WithRetries(i int) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.Retries = i
|
o.Retries = i
|
||||||
@@ -305,14 +305,14 @@ func WithRetries(i int) CallOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithRequestTimeout is a CallOption which overrides that which
|
// WithRequestTimeout is a CallOption which overrides that which
|
||||||
// set in Options.CallOptions
|
// set in Options.CallOptions.
|
||||||
func WithRequestTimeout(d time.Duration) CallOption {
|
func WithRequestTimeout(d time.Duration) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.RequestTimeout = d
|
o.RequestTimeout = d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithStreamTimeout sets the stream timeout
|
// WithStreamTimeout sets the stream timeout.
|
||||||
func WithStreamTimeout(d time.Duration) CallOption {
|
func WithStreamTimeout(d time.Duration) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.StreamTimeout = d
|
o.StreamTimeout = d
|
||||||
@@ -320,7 +320,7 @@ func WithStreamTimeout(d time.Duration) CallOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithDialTimeout is a CallOption which overrides that which
|
// WithDialTimeout is a CallOption which overrides that which
|
||||||
// set in Options.CallOptions
|
// set in Options.CallOptions.
|
||||||
func WithDialTimeout(d time.Duration) CallOption {
|
func WithDialTimeout(d time.Duration) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.DialTimeout = d
|
o.DialTimeout = d
|
||||||
@@ -328,7 +328,7 @@ func WithDialTimeout(d time.Duration) CallOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithServiceToken is a CallOption which overrides the
|
// WithServiceToken is a CallOption which overrides the
|
||||||
// authorization header with the services own auth token
|
// authorization header with the services own auth token.
|
||||||
func WithServiceToken() CallOption {
|
func WithServiceToken() CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.ServiceToken = true
|
o.ServiceToken = true
|
||||||
@@ -336,7 +336,7 @@ func WithServiceToken() CallOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithCache is a CallOption which sets the duration the response
|
// WithCache is a CallOption which sets the duration the response
|
||||||
// shoull be cached for
|
// shoull be cached for.
|
||||||
func WithCache(c time.Duration) CallOption {
|
func WithCache(c time.Duration) CallOption {
|
||||||
return func(o *CallOptions) {
|
return func(o *CallOptions) {
|
||||||
o.CacheExpiry = c
|
o.CacheExpiry = c
|
||||||
@@ -363,14 +363,14 @@ func StreamingRequest() RequestOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRouter sets the client router
|
// WithRouter sets the client router.
|
||||||
func WithRouter(r Router) Option {
|
func WithRouter(r Router) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Router = r
|
o.Router = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithLogger sets the underline logger
|
// WithLogger sets the underline logger.
|
||||||
func WithLogger(l logger.Logger) Option {
|
func WithLogger(l logger.Logger) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Logger = l
|
o.Logger = l
|
||||||
|
@@ -78,8 +78,6 @@ func TestCallOptions(t *testing.T) {
|
|||||||
if e := o.CallOptions.DialTimeout * (time.Second * 10); callOpts.DialTimeout != e {
|
if e := o.CallOptions.DialTimeout * (time.Second * 10); callOpts.DialTimeout != e {
|
||||||
t.Fatalf("Expected %v got %v", e, callOpts.DialTimeout)
|
t.Fatalf("Expected %v got %v", e, callOpts.DialTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,15 +6,15 @@ import (
|
|||||||
"go-micro.dev/v4/errors"
|
"go-micro.dev/v4/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// note that returning either false or a non-nil error will result in the call not being retried
|
// note that returning either false or a non-nil error will result in the call not being retried.
|
||||||
type RetryFunc func(ctx context.Context, req Request, retryCount int, err error) (bool, error)
|
type RetryFunc func(ctx context.Context, req Request, retryCount int, err error) (bool, error)
|
||||||
|
|
||||||
// RetryAlways always retry on error
|
// RetryAlways always retry on error.
|
||||||
func RetryAlways(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
|
func RetryAlways(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetryOnError retries a request on a 500 or timeout error
|
// RetryOnError retries a request on a 500 or timeout error.
|
||||||
func RetryOnError(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
|
func RetryOnError(ctx context.Context, req Request, retryCount int, err error) (bool, error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@@ -320,7 +320,7 @@ func (r *rpcClient) Options() Options {
|
|||||||
return r.opts
|
return r.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
// next returns an iterator for the next nodes to call
|
// next returns an iterator for the next nodes to call.
|
||||||
func (r *rpcClient) next(request Request, opts CallOptions) (selector.Next, error) {
|
func (r *rpcClient) next(request Request, opts CallOptions) (selector.Next, error) {
|
||||||
// try get the proxy
|
// try get the proxy
|
||||||
service, address, _ := net.Proxy(request.Service(), opts.Address)
|
service, address, _ := net.Proxy(request.Service(), opts.Address)
|
||||||
|
@@ -58,7 +58,6 @@ func TestCallAddress(t *testing.T) {
|
|||||||
if !called {
|
if !called {
|
||||||
t.Fatal("wrapper not called")
|
t.Fatal("wrapper not called")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCallRetry(t *testing.T) {
|
func TestCallRetry(t *testing.T) {
|
||||||
|
@@ -28,7 +28,7 @@ func (e serverError) Error() string {
|
|||||||
return string(e)
|
return string(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// errShutdown holds the specific error for closing/closed connections
|
// errShutdown holds the specific error for closing/closed connections.
|
||||||
var (
|
var (
|
||||||
errShutdown = errs.New("connection is shut down")
|
errShutdown = errs.New("connection is shut down")
|
||||||
)
|
)
|
||||||
@@ -63,7 +63,7 @@ var (
|
|||||||
"application/octet-stream": raw.NewCodec,
|
"application/octet-stream": raw.NewCodec,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove legacy codec list
|
// TODO: remove legacy codec list.
|
||||||
defaultCodecs = map[string]codec.NewCodec{
|
defaultCodecs = map[string]codec.NewCodec{
|
||||||
"application/json": jsonrpc.NewCodec,
|
"application/json": jsonrpc.NewCodec,
|
||||||
"application/json-rpc": jsonrpc.NewCodec,
|
"application/json-rpc": jsonrpc.NewCodec,
|
||||||
@@ -127,7 +127,7 @@ func setHeaders(m *codec.Message, stream string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupProtocol sets up the old protocol
|
// setupProtocol sets up the old protocol.
|
||||||
func setupProtocol(msg *transport.Message, node *registry.Node) codec.NewCodec {
|
func setupProtocol(msg *transport.Message, node *registry.Node) codec.NewCodec {
|
||||||
protocol := node.Metadata["protocol"]
|
protocol := node.Metadata["protocol"]
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Implements the streamer interface
|
// Implements the streamer interface.
|
||||||
type rpcStream struct {
|
type rpcStream struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
id string
|
id string
|
||||||
|
@@ -6,14 +6,14 @@ import (
|
|||||||
"go-micro.dev/v4/registry"
|
"go-micro.dev/v4/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CallFunc represents the individual call func
|
// CallFunc represents the individual call func.
|
||||||
type CallFunc func(ctx context.Context, node *registry.Node, req Request, rsp interface{}, opts CallOptions) error
|
type CallFunc func(ctx context.Context, node *registry.Node, req Request, rsp interface{}, opts CallOptions) error
|
||||||
|
|
||||||
// CallWrapper is a low level wrapper for the CallFunc
|
// CallWrapper is a low level wrapper for the CallFunc.
|
||||||
type CallWrapper func(CallFunc) CallFunc
|
type CallWrapper func(CallFunc) CallFunc
|
||||||
|
|
||||||
// Wrapper wraps a client and returns a client
|
// Wrapper wraps a client and returns a client.
|
||||||
type Wrapper func(Client) Client
|
type Wrapper func(Client) Client
|
||||||
|
|
||||||
// StreamWrapper wraps a Stream and returns the equivalent
|
// StreamWrapper wraps a Stream and returns the equivalent.
|
||||||
type StreamWrapper func(Stream) Stream
|
type StreamWrapper func(Stream) Stream
|
||||||
|
@@ -12,7 +12,7 @@ type Codec struct {
|
|||||||
Conn io.ReadWriteCloser
|
Conn io.ReadWriteCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frame gives us the ability to define raw data to send over the pipes
|
// Frame gives us the ability to define raw data to send over the pipes.
|
||||||
type Frame struct {
|
type Frame struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ var (
|
|||||||
|
|
||||||
type MessageType int
|
type MessageType int
|
||||||
|
|
||||||
// Takes in a connection/buffer and returns a new Codec
|
// Takes in a connection/buffer and returns a new Codec.
|
||||||
type NewCodec func(io.ReadWriteCloser) Codec
|
type NewCodec func(io.ReadWriteCloser) Codec
|
||||||
|
|
||||||
// Codec encodes/decodes various types of messages used within go-micro.
|
// Codec encodes/decodes various types of messages used within go-micro.
|
||||||
|
@@ -89,7 +89,7 @@ func (c *Codec) Write(m *codec.Message, b interface{}) error {
|
|||||||
m.Header[":authority"] = m.Target
|
m.Header[":authority"] = m.Target
|
||||||
m.Header["content-type"] = c.ContentType
|
m.Header["content-type"] = c.ContentType
|
||||||
case codec.Response:
|
case codec.Response:
|
||||||
m.Header["Trailer"] = "grpc-status" //, grpc-message"
|
m.Header["Trailer"] = "grpc-status" // , grpc-message"
|
||||||
m.Header["content-type"] = c.ContentType
|
m.Header["content-type"] = c.ContentType
|
||||||
m.Header[":status"] = "200"
|
m.Header[":status"] = "200"
|
||||||
m.Header["grpc-status"] = "0"
|
m.Header["grpc-status"] = "0"
|
||||||
|
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
var jsonpbMarshaler = &jsonpb.Marshaler{}
|
var jsonpbMarshaler = &jsonpb.Marshaler{}
|
||||||
|
|
||||||
// create buffer pool with 16 instances each preallocated with 256 bytes
|
// create buffer pool with 16 instances each preallocated with 256 bytes.
|
||||||
var bufferPool = bpool.NewSizedBufferPool(16, 256)
|
var bufferPool = bpool.NewSizedBufferPool(16, 256)
|
||||||
|
|
||||||
type Marshaler struct{}
|
type Marshaler struct{}
|
||||||
|
@@ -41,7 +41,7 @@ func (j *jsonCodec) Write(m *codec.Message, b interface{}) error {
|
|||||||
_, err = j.rwc.Write(data)
|
_, err = j.rwc.Write(data)
|
||||||
return err
|
return err
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unrecognised message type: %v", m.Type)
|
return fmt.Errorf("Unrecognized message type: %v", m.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ func (j *jsonCodec) ReadHeader(m *codec.Message, mt codec.MessageType) error {
|
|||||||
_, err := io.Copy(j.buf, j.rwc)
|
_, err := io.Copy(j.buf, j.rwc)
|
||||||
return err
|
return err
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unrecognised message type: %v", mt)
|
return fmt.Errorf("Unrecognized message type: %v", mt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ func (j *jsonCodec) ReadBody(b interface{}) error {
|
|||||||
return json.Unmarshal(j.buf.Bytes(), b)
|
return json.Unmarshal(j.buf.Bytes(), b)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unrecognised message type: %v", j.mt)
|
return fmt.Errorf("Unrecognized message type: %v", j.mt)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"go-micro.dev/v4/codec"
|
"go-micro.dev/v4/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// create buffer pool with 16 instances each preallocated with 256 bytes
|
// create buffer pool with 16 instances each preallocated with 256 bytes.
|
||||||
var bufferPool = bpool.NewSizedBufferPool(16, 256)
|
var bufferPool = bpool.NewSizedBufferPool(16, 256)
|
||||||
|
|
||||||
type Marshaler struct{}
|
type Marshaler struct{}
|
||||||
|
@@ -114,7 +114,7 @@ func (c *protoCodec) Write(m *codec.Message, b interface{}) error {
|
|||||||
}
|
}
|
||||||
c.rwc.Write(data)
|
c.rwc.Write(data)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unrecognised message type: %v", m.Type)
|
return fmt.Errorf("Unrecognized message type: %v", m.Type)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ func (c *protoCodec) ReadHeader(m *codec.Message, mt codec.MessageType) error {
|
|||||||
_, err := io.Copy(c.buf, c.rwc)
|
_, err := io.Copy(c.buf, c.rwc)
|
||||||
return err
|
return err
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unrecognised message type: %v", mt)
|
return fmt.Errorf("Unrecognized message type: %v", mt)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ func (c *protoCodec) ReadBody(b interface{}) error {
|
|||||||
case codec.Event:
|
case codec.Event:
|
||||||
data = c.buf.Bytes()
|
data = c.buf.Bytes()
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unrecognised message type: %v", c.mt)
|
return fmt.Errorf("Unrecognized message type: %v", c.mt)
|
||||||
}
|
}
|
||||||
if b != nil {
|
if b != nil {
|
||||||
return proto.Unmarshal(data, b.(proto.Message))
|
return proto.Unmarshal(data, b.(proto.Message))
|
||||||
|
@@ -12,7 +12,7 @@ type Codec struct {
|
|||||||
Conn io.ReadWriteCloser
|
Conn io.ReadWriteCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frame gives us the ability to define raw data to send over the pipes
|
// Frame gives us the ability to define raw data to send over the pipes.
|
||||||
type Frame struct {
|
type Frame struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ import (
|
|||||||
"go-micro.dev/v4/config/source/file"
|
"go-micro.dev/v4/config/source/file"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is an interface abstraction for dynamic configuration
|
// Config is an interface abstraction for dynamic configuration.
|
||||||
type Config interface {
|
type Config interface {
|
||||||
// provide the reader.Values interface
|
// provide the reader.Values interface
|
||||||
reader.Values
|
reader.Values
|
||||||
@@ -28,7 +28,7 @@ type Config interface {
|
|||||||
Watch(path ...string) (Watcher, error)
|
Watch(path ...string) (Watcher, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watcher is the config watcher
|
// Watcher is the config watcher.
|
||||||
type Watcher interface {
|
type Watcher interface {
|
||||||
Next() (reader.Value, error)
|
Next() (reader.Value, error)
|
||||||
Stop() error
|
Stop() error
|
||||||
@@ -48,51 +48,51 @@ type Options struct {
|
|||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Default Config Manager
|
// Default Config Manager.
|
||||||
DefaultConfig, _ = NewConfig()
|
DefaultConfig, _ = NewConfig()
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewConfig returns new config
|
// NewConfig returns new config.
|
||||||
func NewConfig(opts ...Option) (Config, error) {
|
func NewConfig(opts ...Option) (Config, error) {
|
||||||
return newConfig(opts...)
|
return newConfig(opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return config as raw json
|
// Return config as raw json.
|
||||||
func Bytes() []byte {
|
func Bytes() []byte {
|
||||||
return DefaultConfig.Bytes()
|
return DefaultConfig.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return config as a map
|
// Return config as a map.
|
||||||
func Map() map[string]interface{} {
|
func Map() map[string]interface{} {
|
||||||
return DefaultConfig.Map()
|
return DefaultConfig.Map()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan values to a go type
|
// Scan values to a go type.
|
||||||
func Scan(v interface{}) error {
|
func Scan(v interface{}) error {
|
||||||
return DefaultConfig.Scan(v)
|
return DefaultConfig.Scan(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a source changeset sync
|
// Force a source changeset sync.
|
||||||
func Sync() error {
|
func Sync() error {
|
||||||
return DefaultConfig.Sync()
|
return DefaultConfig.Sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a value from the config
|
// Get a value from the config.
|
||||||
func Get(path ...string) reader.Value {
|
func Get(path ...string) reader.Value {
|
||||||
return DefaultConfig.Get(path...)
|
return DefaultConfig.Get(path...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load config sources
|
// Load config sources.
|
||||||
func Load(source ...source.Source) error {
|
func Load(source ...source.Source) error {
|
||||||
return DefaultConfig.Load(source...)
|
return DefaultConfig.Load(source...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch a value for changes
|
// Watch a value for changes.
|
||||||
func Watch(path ...string) (Watcher, error) {
|
func Watch(path ...string) (Watcher, error) {
|
||||||
return DefaultConfig.Watch(path...)
|
return DefaultConfig.Watch(path...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadFile is short hand for creating a file source and loading it
|
// LoadFile is short hand for creating a file source and loading it.
|
||||||
func LoadFile(path string) error {
|
func LoadFile(path string) error {
|
||||||
return Load(file.NewSource(
|
return Load(file.NewSource(
|
||||||
file.WithPath(path),
|
file.WithPath(path),
|
||||||
|
@@ -159,7 +159,7 @@ func (c *config) Scan(v interface{}) error {
|
|||||||
return c.vals.Scan(v)
|
return c.vals.Scan(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sync loads all the sources, calls the parser and updates the config
|
// sync loads all the sources, calls the parser and updates the config.
|
||||||
func (c *config) Sync() error {
|
func (c *config) Sync() error {
|
||||||
if err := c.opts.Loader.Sync(); err != nil {
|
if err := c.opts.Loader.Sync(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"go-micro.dev/v4/config/source"
|
"go-micro.dev/v4/config/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Loader manages loading sources
|
// Loader manages loading sources.
|
||||||
type Loader interface {
|
type Loader interface {
|
||||||
// Stop the loader
|
// Stop the loader
|
||||||
Close() error
|
Close() error
|
||||||
@@ -24,7 +24,7 @@ type Loader interface {
|
|||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watcher lets you watch sources and returns a merged ChangeSet
|
// Watcher lets you watch sources and returns a merged ChangeSet.
|
||||||
type Watcher interface {
|
type Watcher interface {
|
||||||
// First call to next may return the current Snapshot
|
// First call to next may return the current Snapshot
|
||||||
// If you are watching a path then only the data from
|
// If you are watching a path then only the data from
|
||||||
@@ -34,7 +34,7 @@ type Watcher interface {
|
|||||||
Stop() error
|
Stop() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot is a merged ChangeSet
|
// Snapshot is a merged ChangeSet.
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
// The merged ChangeSet
|
// The merged ChangeSet
|
||||||
ChangeSet *source.ChangeSet
|
ChangeSet *source.ChangeSet
|
||||||
@@ -54,7 +54,7 @@ type Options struct {
|
|||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
// Copy snapshot
|
// Copy snapshot.
|
||||||
func Copy(s *Snapshot) *Snapshot {
|
func Copy(s *Snapshot) *Snapshot {
|
||||||
cs := *(s.ChangeSet)
|
cs := *(s.ChangeSet)
|
||||||
|
|
||||||
|
@@ -128,7 +128,7 @@ func (m *memory) loaded() bool {
|
|||||||
return loaded
|
return loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
// reload reads the sets and creates new values
|
// reload reads the sets and creates new values.
|
||||||
func (m *memory) reload() error {
|
func (m *memory) reload() error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ func (m *memory) update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot returns a snapshot of the current loaded config
|
// Snapshot returns a snapshot of the current loaded config.
|
||||||
func (m *memory) Snapshot() (*loader.Snapshot, error) {
|
func (m *memory) Snapshot() (*loader.Snapshot, error) {
|
||||||
if m.loaded() {
|
if m.loaded() {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
@@ -207,7 +207,7 @@ func (m *memory) Snapshot() (*loader.Snapshot, error) {
|
|||||||
return snap, nil
|
return snap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync loads all the sources, calls the parser and updates the config
|
// Sync loads all the sources, calls the parser and updates the config.
|
||||||
func (m *memory) Sync() error {
|
func (m *memory) Sync() error {
|
||||||
//nolint:prealloc
|
//nolint:prealloc
|
||||||
var sets []*source.ChangeSet
|
var sets []*source.ChangeSet
|
||||||
@@ -394,7 +394,6 @@ func (w *watcher) Next() (*loader.Snapshot, error) {
|
|||||||
ChangeSet: cs,
|
ChangeSet: cs,
|
||||||
Version: w.version,
|
Version: w.version,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@@ -6,14 +6,14 @@ import (
|
|||||||
"go-micro.dev/v4/config/source"
|
"go-micro.dev/v4/config/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithSource appends a source to list of sources
|
// WithSource appends a source to list of sources.
|
||||||
func WithSource(s source.Source) loader.Option {
|
func WithSource(s source.Source) loader.Option {
|
||||||
return func(o *loader.Options) {
|
return func(o *loader.Options) {
|
||||||
o.Source = append(o.Source, s)
|
o.Source = append(o.Source, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithReader sets the config reader
|
// WithReader sets the config reader.
|
||||||
func WithReader(r reader.Reader) loader.Option {
|
func WithReader(r reader.Reader) loader.Option {
|
||||||
return func(o *loader.Options) {
|
return func(o *loader.Options) {
|
||||||
o.Reader = r
|
o.Reader = r
|
||||||
|
@@ -6,21 +6,21 @@ import (
|
|||||||
"go-micro.dev/v4/config/source"
|
"go-micro.dev/v4/config/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithLoader sets the loader for manager config
|
// WithLoader sets the loader for manager config.
|
||||||
func WithLoader(l loader.Loader) Option {
|
func WithLoader(l loader.Loader) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Loader = l
|
o.Loader = l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSource appends a source to list of sources
|
// WithSource appends a source to list of sources.
|
||||||
func WithSource(s source.Source) Option {
|
func WithSource(s source.Source) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Source = append(o.Source, s)
|
o.Source = append(o.Source, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithReader sets the config reader
|
// WithReader sets the config reader.
|
||||||
func WithReader(r reader.Reader) Option {
|
func WithReader(r reader.Reader) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Reader = r
|
o.Reader = r
|
||||||
|
@@ -73,7 +73,7 @@ func (j *jsonReader) String() string {
|
|||||||
return "json"
|
return "json"
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReader creates a json reader
|
// NewReader creates a json reader.
|
||||||
func NewReader(opts ...reader.Option) reader.Reader {
|
func NewReader(opts ...reader.Option) reader.Reader {
|
||||||
options := reader.NewOptions(opts...)
|
options := reader.NewOptions(opts...)
|
||||||
return &jsonReader{
|
return &jsonReader{
|
||||||
|
@@ -190,7 +190,7 @@ func (j *jsonValue) Scan(v interface{}) error {
|
|||||||
func (j *jsonValue) Bytes() []byte {
|
func (j *jsonValue) Bytes() []byte {
|
||||||
b, err := j.Json.Bytes()
|
b, err := j.Json.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// try return marshalled
|
// try return marshaled
|
||||||
b, err = j.Json.MarshalJSON()
|
b, err = j.Json.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}
|
return []byte{}
|
||||||
|
@@ -7,14 +7,14 @@ import (
|
|||||||
"go-micro.dev/v4/config/source"
|
"go-micro.dev/v4/config/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reader is an interface for merging changesets
|
// Reader is an interface for merging changesets.
|
||||||
type Reader interface {
|
type Reader interface {
|
||||||
Merge(...*source.ChangeSet) (*source.ChangeSet, error)
|
Merge(...*source.ChangeSet) (*source.ChangeSet, error)
|
||||||
Values(*source.ChangeSet) (Values, error)
|
Values(*source.ChangeSet) (Values, error)
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values is returned by the reader
|
// Values is returned by the reader.
|
||||||
type Values interface {
|
type Values interface {
|
||||||
Bytes() []byte
|
Bytes() []byte
|
||||||
Get(path ...string) Value
|
Get(path ...string) Value
|
||||||
@@ -24,7 +24,7 @@ type Values interface {
|
|||||||
Scan(v interface{}) error
|
Scan(v interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value represents a value of any type
|
// Value represents a value of any type.
|
||||||
type Value interface {
|
type Value interface {
|
||||||
Bool(def bool) bool
|
Bool(def bool) bool
|
||||||
Int(def int) int
|
Int(def int) int
|
||||||
|
@@ -18,7 +18,7 @@ type box struct {
|
|||||||
privateKey [keyLength]byte
|
privateKey [keyLength]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSecrets returns a nacl-box codec
|
// NewSecrets returns a nacl-box codec.
|
||||||
func NewSecrets(opts ...secrets.Option) secrets.Secrets {
|
func NewSecrets(opts ...secrets.Option) secrets.Secrets {
|
||||||
b := &box{}
|
b := &box{}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@@ -27,7 +27,6 @@ func NewSecrets(opts ...secrets.Option) secrets.Secrets {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initialises a box
|
|
||||||
func (b *box) Init(opts ...secrets.Option) error {
|
func (b *box) Init(opts ...secrets.Option) error {
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&b.options)
|
o(&b.options)
|
||||||
@@ -40,17 +39,17 @@ func (b *box) Init(opts ...secrets.Option) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options returns options
|
// Options returns options.
|
||||||
func (b *box) Options() secrets.Options {
|
func (b *box) Options() secrets.Options {
|
||||||
return b.options
|
return b.options
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns nacl-box
|
// String returns nacl-box.
|
||||||
func (*box) String() string {
|
func (*box) String() string {
|
||||||
return "nacl-box"
|
return "nacl-box"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt encrypts a message with the sender's private key and the receipient's public key
|
// Encrypt encrypts a message with the sender's private key and the receipient's public key.
|
||||||
func (b *box) Encrypt(in []byte, opts ...secrets.EncryptOption) ([]byte, error) {
|
func (b *box) Encrypt(in []byte, opts ...secrets.EncryptOption) ([]byte, error) {
|
||||||
var options secrets.EncryptOptions
|
var options secrets.EncryptOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
@@ -68,7 +67,7 @@ func (b *box) Encrypt(in []byte, opts ...secrets.EncryptOption) ([]byte, error)
|
|||||||
return naclbox.Seal(nonce[:], in, &nonce, &recipientPublicKey, &b.privateKey), nil
|
return naclbox.Seal(nonce[:], in, &nonce, &recipientPublicKey, &b.privateKey), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt Decrypts a message with the receiver's private key and the sender's public key
|
// Decrypt Decrypts a message with the receiver's private key and the sender's public key.
|
||||||
func (b *box) Decrypt(in []byte, opts ...secrets.DecryptOption) ([]byte, error) {
|
func (b *box) Decrypt(in []byte, opts ...secrets.DecryptOption) ([]byte, error) {
|
||||||
var options secrets.DecryptOptions
|
var options secrets.DecryptOptions
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
|
@@ -30,14 +30,14 @@ func TestBox(t *testing.T) {
|
|||||||
}
|
}
|
||||||
aliceSecret := []byte("Why is a raven like a writing-desk?")
|
aliceSecret := []byte("Why is a raven like a writing-desk?")
|
||||||
if _, err := alice.Encrypt(aliceSecret); err == nil {
|
if _, err := alice.Encrypt(aliceSecret); err == nil {
|
||||||
t.Error("alice.Encrypt succeded without a public key")
|
t.Error("alice.Encrypt succeeded without a public key")
|
||||||
}
|
}
|
||||||
enc, err := alice.Encrypt(aliceSecret, secrets.RecipientPublicKey(bob.Options().PublicKey))
|
enc, err := alice.Encrypt(aliceSecret, secrets.RecipientPublicKey(bob.Options().PublicKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("alice.Encrypt failed")
|
t.Error("alice.Encrypt failed")
|
||||||
}
|
}
|
||||||
if _, err := bob.Decrypt(enc); err == nil {
|
if _, err := bob.Decrypt(enc); err == nil {
|
||||||
t.Error("bob.Decrypt succeded without a public key")
|
t.Error("bob.Decrypt succeeded without a public key")
|
||||||
}
|
}
|
||||||
if dec, err := bob.Decrypt(enc, secrets.SenderPublicKey(alice.Options().PublicKey)); err == nil {
|
if dec, err := bob.Decrypt(enc, secrets.SenderPublicKey(alice.Options().PublicKey)); err == nil {
|
||||||
if !reflect.DeepEqual(dec, aliceSecret) {
|
if !reflect.DeepEqual(dec, aliceSecret) {
|
||||||
|
@@ -18,7 +18,7 @@ type secretBox struct {
|
|||||||
secretKey [keyLength]byte
|
secretKey [keyLength]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSecrets returns a secretbox codec
|
// NewSecrets returns a secretbox codec.
|
||||||
func NewSecrets(opts ...secrets.Option) secrets.Secrets {
|
func NewSecrets(opts ...secrets.Option) secrets.Secrets {
|
||||||
sb := &secretBox{}
|
sb := &secretBox{}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
|
@@ -3,9 +3,9 @@ package secrets
|
|||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
|
||||||
// Secrets encrypts or decrypts arbitrary data. The data should be as small as possible
|
// Secrets encrypts or decrypts arbitrary data. The data should be as small as possible.
|
||||||
type Secrets interface {
|
type Secrets interface {
|
||||||
// Initialise options
|
// Initialize options
|
||||||
Init(...Option) error
|
Init(...Option) error
|
||||||
// Return the options
|
// Return the options
|
||||||
Options() Options
|
Options() Options
|
||||||
@@ -28,10 +28,10 @@ type Options struct {
|
|||||||
Context context.Context
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// Option sets options
|
// Option sets options.
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
|
|
||||||
// Key sets the symmetric secret key
|
// Key sets the symmetric secret key.
|
||||||
func Key(k []byte) Option {
|
func Key(k []byte) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Key = make([]byte, len(k))
|
o.Key = make([]byte, len(k))
|
||||||
@@ -39,7 +39,7 @@ func Key(k []byte) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKey sets the asymmetric Public Key of this codec
|
// PublicKey sets the asymmetric Public Key of this codec.
|
||||||
func PublicKey(key []byte) Option {
|
func PublicKey(key []byte) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.PublicKey = make([]byte, len(key))
|
o.PublicKey = make([]byte, len(key))
|
||||||
@@ -47,7 +47,7 @@ func PublicKey(key []byte) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrivateKey sets the asymmetric Private Key of this codec
|
// PrivateKey sets the asymmetric Private Key of this codec.
|
||||||
func PrivateKey(key []byte) Option {
|
func PrivateKey(key []byte) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.PrivateKey = make([]byte, len(key))
|
o.PrivateKey = make([]byte, len(key))
|
||||||
@@ -55,15 +55,15 @@ func PrivateKey(key []byte) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptOptions can be passed to Secrets.Decrypt
|
// DecryptOptions can be passed to Secrets.Decrypt.
|
||||||
type DecryptOptions struct {
|
type DecryptOptions struct {
|
||||||
SenderPublicKey []byte
|
SenderPublicKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptOption sets DecryptOptions
|
// DecryptOption sets DecryptOptions.
|
||||||
type DecryptOption func(*DecryptOptions)
|
type DecryptOption func(*DecryptOptions)
|
||||||
|
|
||||||
// SenderPublicKey is the Public Key of the Secrets that encrypted this message
|
// SenderPublicKey is the Public Key of the Secrets that encrypted this message.
|
||||||
func SenderPublicKey(key []byte) DecryptOption {
|
func SenderPublicKey(key []byte) DecryptOption {
|
||||||
return func(d *DecryptOptions) {
|
return func(d *DecryptOptions) {
|
||||||
d.SenderPublicKey = make([]byte, len(key))
|
d.SenderPublicKey = make([]byte, len(key))
|
||||||
@@ -71,15 +71,15 @@ func SenderPublicKey(key []byte) DecryptOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptOptions can be passed to Secrets.Encrypt
|
// EncryptOptions can be passed to Secrets.Encrypt.
|
||||||
type EncryptOptions struct {
|
type EncryptOptions struct {
|
||||||
RecipientPublicKey []byte
|
RecipientPublicKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptOption Sets EncryptOptions
|
// EncryptOption Sets EncryptOptions.
|
||||||
type EncryptOption func(*EncryptOptions)
|
type EncryptOption func(*EncryptOptions)
|
||||||
|
|
||||||
// RecipientPublicKey is the Public Key of the Secrets that will decrypt this message
|
// RecipientPublicKey is the Public Key of the Secrets that will decrypt this message.
|
||||||
func RecipientPublicKey(key []byte) EncryptOption {
|
func RecipientPublicKey(key []byte) EncryptOption {
|
||||||
return func(e *EncryptOptions) {
|
return func(e *EncryptOptions) {
|
||||||
e.RecipientPublicKey = make([]byte, len(key))
|
e.RecipientPublicKey = make([]byte, len(key))
|
||||||
|
@@ -5,7 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sum returns the md5 checksum of the ChangeSet data
|
// Sum returns the md5 checksum of the ChangeSet data.
|
||||||
func (c *ChangeSet) Sum() string {
|
func (c *ChangeSet) Sum() string {
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
h.Write(c.Data)
|
h.Write(c.Data)
|
||||||
|
@@ -75,7 +75,7 @@ func (c *cliSource) Watch() (source.Watcher, error) {
|
|||||||
return source.NewNoopWatcher()
|
return source.NewNoopWatcher()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write is unsupported
|
// Write is unsupported.
|
||||||
func (c *cliSource) Write(cs *source.ChangeSet) error {
|
func (c *cliSource) Write(cs *source.ChangeSet) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -104,7 +104,6 @@ func test(t *testing.T, withContext bool) {
|
|||||||
if actualDB["host"] != "localhost" {
|
if actualDB["host"] != "localhost" {
|
||||||
t.Errorf("expected localhost, got %v", actualDB["name"])
|
t.Errorf("expected localhost, got %v", actualDB["name"])
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCliSource(t *testing.T) {
|
func TestCliSource(t *testing.T) {
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
type contextKey struct{}
|
type contextKey struct{}
|
||||||
|
|
||||||
// Context sets the cli context
|
// Context sets the cli context.
|
||||||
func Context(c *cli.Context) source.Option {
|
func Context(c *cli.Context) source.Option {
|
||||||
return func(o *source.Options) {
|
return func(o *source.Options) {
|
||||||
if o.Context == nil {
|
if o.Context == nil {
|
||||||
|
1
config/source/env/env.go
vendored
1
config/source/env/env.go
vendored
@@ -24,7 +24,6 @@ func (e *env) Read() (*source.ChangeSet, error) {
|
|||||||
var changes map[string]interface{}
|
var changes map[string]interface{}
|
||||||
|
|
||||||
for _, env := range os.Environ() {
|
for _, env := range os.Environ() {
|
||||||
|
|
||||||
if len(e.prefixes) > 0 || len(e.strippedPrefixes) > 0 {
|
if len(e.prefixes) > 0 || len(e.strippedPrefixes) > 0 {
|
||||||
notFound := true
|
notFound := true
|
||||||
|
|
||||||
|
@@ -27,5 +27,4 @@ func TestFormat(t *testing.T) {
|
|||||||
t.Fatalf("%s: expected %s got %s", d.p, d.f, f)
|
t.Fatalf("%s: expected %s got %s", d.p, d.f, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ import (
|
|||||||
type filePathKey struct{}
|
type filePathKey struct{}
|
||||||
type fsKey struct{}
|
type fsKey struct{}
|
||||||
|
|
||||||
// WithPath sets the path to file
|
// WithPath sets the path to file.
|
||||||
func WithPath(p string) source.Option {
|
func WithPath(p string) source.Option {
|
||||||
return func(o *source.Options) {
|
return func(o *source.Options) {
|
||||||
if o.Context == nil {
|
if o.Context == nil {
|
||||||
@@ -20,7 +20,7 @@ func WithPath(p string) source.Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithFS sets the underlying filesystem to lookup file from (default os.FS)
|
// WithFS sets the underlying filesystem to lookup file from (default os.FS).
|
||||||
func WithFS(fs fs.FS) source.Option {
|
func WithFS(fs fs.FS) source.Option {
|
||||||
return func(o *source.Options) {
|
return func(o *source.Options) {
|
||||||
if o.Context == nil {
|
if o.Context == nil {
|
||||||
|
@@ -3,10 +3,11 @@ package flag
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/imdario/mergo"
|
|
||||||
"go-micro.dev/v4/config/source"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/imdario/mergo"
|
||||||
|
"go-micro.dev/v4/config/source"
|
||||||
)
|
)
|
||||||
|
|
||||||
type flagsrc struct {
|
type flagsrc struct {
|
||||||
|
@@ -20,7 +20,7 @@ func withData(d []byte, f string) source.Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithChangeSet allows a changeset to be set
|
// WithChangeSet allows a changeset to be set.
|
||||||
func WithChangeSet(cs *source.ChangeSet) source.Option {
|
func WithChangeSet(cs *source.ChangeSet) source.Option {
|
||||||
return func(o *source.Options) {
|
return func(o *source.Options) {
|
||||||
if o.Context == nil {
|
if o.Context == nil {
|
||||||
@@ -30,12 +30,12 @@ func WithChangeSet(cs *source.ChangeSet) source.Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithJSON allows the source data to be set to json
|
// WithJSON allows the source data to be set to json.
|
||||||
func WithJSON(d []byte) source.Option {
|
func WithJSON(d []byte) source.Option {
|
||||||
return withData(d, "json")
|
return withData(d, "json")
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithYAML allows the source data to be set to yaml
|
// WithYAML allows the source data to be set to yaml.
|
||||||
func WithYAML(d []byte) source.Option {
|
func WithYAML(d []byte) source.Option {
|
||||||
return withData(d, "yaml")
|
return withData(d, "yaml")
|
||||||
}
|
}
|
||||||
|
@@ -35,14 +35,14 @@ func NewOptions(opts ...Option) Options {
|
|||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithEncoder sets the source encoder
|
// WithEncoder sets the source encoder.
|
||||||
func WithEncoder(e encoder.Encoder) Option {
|
func WithEncoder(e encoder.Encoder) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Encoder = e
|
o.Encoder = e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithClient sets the source client
|
// WithClient sets the source client.
|
||||||
func WithClient(c client.Client) Option {
|
func WithClient(c client.Client) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Client = c
|
o.Client = c
|
||||||
|
@@ -7,11 +7,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrWatcherStopped is returned when source watcher has been stopped
|
// ErrWatcherStopped is returned when source watcher has been stopped.
|
||||||
ErrWatcherStopped = errors.New("watcher stopped")
|
ErrWatcherStopped = errors.New("watcher stopped")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Source is the source from which config is loaded
|
// Source is the source from which config is loaded.
|
||||||
type Source interface {
|
type Source interface {
|
||||||
Read() (*ChangeSet, error)
|
Read() (*ChangeSet, error)
|
||||||
Write(*ChangeSet) error
|
Write(*ChangeSet) error
|
||||||
@@ -19,7 +19,7 @@ type Source interface {
|
|||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeSet represents a set of changes from a source
|
// ChangeSet represents a set of changes from a source.
|
||||||
type ChangeSet struct {
|
type ChangeSet struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
Checksum string
|
Checksum string
|
||||||
@@ -28,7 +28,7 @@ type ChangeSet struct {
|
|||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watcher watches a source for changes
|
// Watcher watches a source for changes.
|
||||||
type Watcher interface {
|
type Watcher interface {
|
||||||
Next() (*ChangeSet, error)
|
Next() (*ChangeSet, error)
|
||||||
Stop() error
|
Stop() error
|
||||||
|
@@ -13,7 +13,7 @@ import (
|
|||||||
"go-micro.dev/v4/server"
|
"go-micro.dev/v4/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewHandler returns an instance of the Debug Handler
|
// NewHandler returns an instance of the Debug Handler.
|
||||||
func NewHandler(c client.Client) *Debug {
|
func NewHandler(c client.Client) *Debug {
|
||||||
return &Debug{
|
return &Debug{
|
||||||
log: log.DefaultLog,
|
log: log.DefaultLog,
|
||||||
@@ -23,7 +23,7 @@ func NewHandler(c client.Client) *Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Debug struct {
|
type Debug struct {
|
||||||
// must honour the debug handler
|
// must honor the debug handler
|
||||||
proto.DebugHandler
|
proto.DebugHandler
|
||||||
// the logger for retrieving logs
|
// the logger for retrieving logs
|
||||||
log log.Log
|
log log.Log
|
||||||
|
@@ -8,15 +8,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Default buffer size if any
|
// Default buffer size if any.
|
||||||
DefaultSize = 1024
|
DefaultSize = 1024
|
||||||
// DefaultLog logger
|
// DefaultLog logger.
|
||||||
DefaultLog = NewLog()
|
DefaultLog = NewLog()
|
||||||
// Default formatter
|
// Default formatter.
|
||||||
DefaultFormat = TextFormat
|
DefaultFormat = TextFormat
|
||||||
)
|
)
|
||||||
|
|
||||||
// Log is debug log interface for reading and writing logs
|
// Log is debug log interface for reading and writing logs.
|
||||||
type Log interface {
|
type Log interface {
|
||||||
// Read reads log entries from the logger
|
// Read reads log entries from the logger
|
||||||
Read(...ReadOption) ([]Record, error)
|
Read(...ReadOption) ([]Record, error)
|
||||||
@@ -26,7 +26,7 @@ type Log interface {
|
|||||||
Stream() (Stream, error)
|
Stream() (Stream, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record is log record entry
|
// Record is log record entry.
|
||||||
type Record struct {
|
type Record struct {
|
||||||
// Timestamp of logged event
|
// Timestamp of logged event
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
@@ -36,22 +36,22 @@ type Record struct {
|
|||||||
Message interface{} `json:"message"`
|
Message interface{} `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream returns a log stream
|
// Stream returns a log stream.
|
||||||
type Stream interface {
|
type Stream interface {
|
||||||
Chan() <-chan Record
|
Chan() <-chan Record
|
||||||
Stop() error
|
Stop() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format is a function which formats the output
|
// Format is a function which formats the output.
|
||||||
type FormatFunc func(Record) string
|
type FormatFunc func(Record) string
|
||||||
|
|
||||||
// TextFormat returns text format
|
// TextFormat returns text format.
|
||||||
func TextFormat(r Record) string {
|
func TextFormat(r Record) string {
|
||||||
t := r.Timestamp.Format("2006-01-02 15:04:05")
|
t := r.Timestamp.Format("2006-01-02 15:04:05")
|
||||||
return fmt.Sprintf("%s %v", t, r.Message)
|
return fmt.Sprintf("%s %v", t, r.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSONFormat is a json Format func
|
// JSONFormat is a json Format func.
|
||||||
func JSONFormat(r Record) string {
|
func JSONFormat(r Record) string {
|
||||||
b, _ := json.Marshal(r)
|
b, _ := json.Marshal(r)
|
||||||
return string(b)
|
return string(b)
|
||||||
|
@@ -9,16 +9,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// DefaultSize of the logger buffer
|
// DefaultSize of the logger buffer.
|
||||||
DefaultSize = 1024
|
DefaultSize = 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
// memoryLog is default micro log
|
// memoryLog is default micro log.
|
||||||
type memoryLog struct {
|
type memoryLog struct {
|
||||||
*ring.Buffer
|
*ring.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLog returns default Logger with
|
// NewLog returns default Logger with.
|
||||||
func NewLog(opts ...log.Option) log.Log {
|
func NewLog(opts ...log.Option) log.Log {
|
||||||
// get default options
|
// get default options
|
||||||
options := log.DefaultOptions()
|
options := log.DefaultOptions()
|
||||||
@@ -33,13 +33,13 @@ func NewLog(opts ...log.Option) log.Log {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes logs into logger
|
// Write writes logs into logger.
|
||||||
func (l *memoryLog) Write(r log.Record) error {
|
func (l *memoryLog) Write(r log.Record) error {
|
||||||
l.Buffer.Put(fmt.Sprint(r.Message))
|
l.Buffer.Put(fmt.Sprint(r.Message))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read reads logs and returns them
|
// Read reads logs and returns them.
|
||||||
func (l *memoryLog) Read(opts ...log.ReadOption) ([]log.Record, error) {
|
func (l *memoryLog) Read(opts ...log.ReadOption) ([]log.Record, error) {
|
||||||
options := log.ReadOptions{}
|
options := log.ReadOptions{}
|
||||||
// initialize the read options
|
// initialize the read options
|
||||||
@@ -83,7 +83,7 @@ func (l *memoryLog) Read(opts ...log.ReadOption) ([]log.Record, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stream returns channel for reading log records
|
// Stream returns channel for reading log records
|
||||||
// along with a stop channel, close it when done
|
// along with a stop channel, close it when done.
|
||||||
func (l *memoryLog) Stream() (log.Stream, error) {
|
func (l *memoryLog) Stream() (log.Stream, error) {
|
||||||
// get stream channel from ring buffer
|
// get stream channel from ring buffer
|
||||||
stream, stop := l.Buffer.Stream()
|
stream, stop := l.Buffer.Stream()
|
||||||
|
@@ -2,10 +2,10 @@ package log
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// Option used by the logger
|
// Option used by the logger.
|
||||||
type Option func(*Options)
|
type Option func(*Options)
|
||||||
|
|
||||||
// Options are logger options
|
// Options are logger options.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// Name of the log
|
// Name of the log
|
||||||
Name string
|
Name string
|
||||||
@@ -15,14 +15,14 @@ type Options struct {
|
|||||||
Format FormatFunc
|
Format FormatFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name of the log
|
// Name of the log.
|
||||||
func Name(n string) Option {
|
func Name(n string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Name = n
|
o.Name = n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size sets the size of the ring buffer
|
// Size sets the size of the ring buffer.
|
||||||
func Size(s int) Option {
|
func Size(s int) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Size = s
|
o.Size = s
|
||||||
@@ -35,14 +35,14 @@ func Format(f FormatFunc) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultOptions returns default options
|
// DefaultOptions returns default options.
|
||||||
func DefaultOptions() Options {
|
func DefaultOptions() Options {
|
||||||
return Options{
|
return Options{
|
||||||
Size: DefaultSize,
|
Size: DefaultSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadOptions for querying the logs
|
// ReadOptions for querying the logs.
|
||||||
type ReadOptions struct {
|
type ReadOptions struct {
|
||||||
// Since what time in past to return the logs
|
// Since what time in past to return the logs
|
||||||
Since time.Time
|
Since time.Time
|
||||||
@@ -52,17 +52,17 @@ type ReadOptions struct {
|
|||||||
Stream bool
|
Stream bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadOption used for reading the logs
|
// ReadOption used for reading the logs.
|
||||||
type ReadOption func(*ReadOptions)
|
type ReadOption func(*ReadOptions)
|
||||||
|
|
||||||
// Since sets the time since which to return the log records
|
// Since sets the time since which to return the log records.
|
||||||
func Since(s time.Time) ReadOption {
|
func Since(s time.Time) ReadOption {
|
||||||
return func(o *ReadOptions) {
|
return func(o *ReadOptions) {
|
||||||
o.Since = s
|
o.Since = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count sets the number of log records to return
|
// Count sets the number of log records to return.
|
||||||
func Count(c int) ReadOption {
|
func Count(c int) ReadOption {
|
||||||
return func(o *ReadOptions) {
|
return func(o *ReadOptions) {
|
||||||
o.Count = c
|
o.Count = c
|
||||||
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"go-micro.dev/v4/util/ring"
|
"go-micro.dev/v4/util/ring"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Should stream from OS
|
// Should stream from OS.
|
||||||
type osLog struct {
|
type osLog struct {
|
||||||
format FormatFunc
|
format FormatFunc
|
||||||
once sync.Once
|
once sync.Once
|
||||||
@@ -21,7 +21,7 @@ type osStream struct {
|
|||||||
stream chan Record
|
stream chan Record
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read reads log entries from the logger
|
// Read reads log entries from the logger.
|
||||||
func (o *osLog) Read(...ReadOption) ([]Record, error) {
|
func (o *osLog) Read(...ReadOption) ([]Record, error) {
|
||||||
var records []Record
|
var records []Record
|
||||||
|
|
||||||
@@ -33,13 +33,13 @@ func (o *osLog) Read(...ReadOption) ([]Record, error) {
|
|||||||
return records, nil
|
return records, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes records to log
|
// Write writes records to log.
|
||||||
func (o *osLog) Write(r Record) error {
|
func (o *osLog) Write(r Record) error {
|
||||||
o.buffer.Put(r)
|
o.buffer.Put(r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream log records
|
// Stream log records.
|
||||||
func (o *osLog) Stream() (Stream, error) {
|
func (o *osLog) Stream() (Stream, error) {
|
||||||
o.Lock()
|
o.Lock()
|
||||||
defer o.Unlock()
|
defer o.Unlock()
|
||||||
|
@@ -20,7 +20,7 @@ var (
|
|||||||
DefaultAddress = ":6060"
|
DefaultAddress = ":6060"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start the profiler
|
// Start the profiler.
|
||||||
func (h *httpProfile) Start() error {
|
func (h *httpProfile) Start() error {
|
||||||
h.Lock()
|
h.Lock()
|
||||||
defer h.Unlock()
|
defer h.Unlock()
|
||||||
@@ -42,7 +42,7 @@ func (h *httpProfile) Start() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the profiler
|
// Stop the profiler.
|
||||||
func (h *httpProfile) Stop() error {
|
func (h *httpProfile) Stop() error {
|
||||||
h.Lock()
|
h.Lock()
|
||||||
defer h.Unlock()
|
defer h.Unlock()
|
||||||
|
@@ -35,7 +35,7 @@ type Options struct {
|
|||||||
|
|
||||||
type Option func(o *Options)
|
type Option func(o *Options)
|
||||||
|
|
||||||
// Name of the profile
|
// Name of the profile.
|
||||||
func Name(n string) Option {
|
func Name(n string) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
o.Name = n
|
o.Name = n
|
||||||
|
@@ -80,7 +80,7 @@ func (s *stats) Record(err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewStats returns a new in memory stats buffer
|
// NewStats returns a new in memory stats buffer
|
||||||
// TODO add options
|
// TODO add options.
|
||||||
func NewStats() Stats {
|
func NewStats() Stats {
|
||||||
return &stats{
|
return &stats{
|
||||||
started: time.Now().Unix(),
|
started: time.Now().Unix(),
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// Package stats provides runtime stats
|
// Package stats provides runtime stats
|
||||||
package stats
|
package stats
|
||||||
|
|
||||||
// Stats provides stats interface
|
// Stats provides stats interface.
|
||||||
type Stats interface {
|
type Stats interface {
|
||||||
// Read stat snapshot
|
// Read stat snapshot
|
||||||
Read() ([]*Stat, error)
|
Read() ([]*Stat, error)
|
||||||
@@ -11,7 +11,7 @@ type Stats interface {
|
|||||||
Record(error) error
|
Record(error) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// A runtime stat
|
// A runtime stat.
|
||||||
type Stat struct {
|
type Stat struct {
|
||||||
// Timestamp of recording
|
// Timestamp of recording
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
|
@@ -14,7 +14,7 @@ type ReadOptions struct {
|
|||||||
|
|
||||||
type ReadOption func(o *ReadOptions)
|
type ReadOption func(o *ReadOptions)
|
||||||
|
|
||||||
// Read the given trace
|
// Read the given trace.
|
||||||
func ReadTrace(t string) ReadOption {
|
func ReadTrace(t string) ReadOption {
|
||||||
return func(o *ReadOptions) {
|
return func(o *ReadOptions) {
|
||||||
o.Trace = t
|
o.Trace = t
|
||||||
@@ -22,11 +22,11 @@ func ReadTrace(t string) ReadOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultSize of the buffer
|
// DefaultSize of the buffer.
|
||||||
DefaultSize = 64
|
DefaultSize = 64
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultOptions returns default options
|
// DefaultOptions returns default options.
|
||||||
func DefaultOptions() Options {
|
func DefaultOptions() Options {
|
||||||
return Options{
|
return Options{
|
||||||
Size: DefaultSize,
|
Size: DefaultSize,
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"go-micro.dev/v4/metadata"
|
"go-micro.dev/v4/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tracer is an interface for distributed tracing
|
// Tracer is an interface for distributed tracing.
|
||||||
type Tracer interface {
|
type Tracer interface {
|
||||||
// Start a trace
|
// Start a trace
|
||||||
Start(ctx context.Context, name string) (context.Context, *Span)
|
Start(ctx context.Context, name string) (context.Context, *Span)
|
||||||
@@ -18,17 +18,17 @@ type Tracer interface {
|
|||||||
Read(...ReadOption) ([]*Span, error)
|
Read(...ReadOption) ([]*Span, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpanType describe the nature of the trace span
|
// SpanType describe the nature of the trace span.
|
||||||
type SpanType int
|
type SpanType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// SpanTypeRequestInbound is a span created when serving a request
|
// SpanTypeRequestInbound is a span created when serving a request.
|
||||||
SpanTypeRequestInbound SpanType = iota
|
SpanTypeRequestInbound SpanType = iota
|
||||||
// SpanTypeRequestOutbound is a span created when making a service call
|
// SpanTypeRequestOutbound is a span created when making a service call.
|
||||||
SpanTypeRequestOutbound
|
SpanTypeRequestOutbound
|
||||||
)
|
)
|
||||||
|
|
||||||
// Span is used to record an entry
|
// Span is used to record an entry.
|
||||||
type Span struct {
|
type Span struct {
|
||||||
// Id of the trace
|
// Id of the trace
|
||||||
Trace string
|
Trace string
|
||||||
@@ -53,7 +53,7 @@ const (
|
|||||||
spanIDKey = "Micro-Span-Id"
|
spanIDKey = "Micro-Span-Id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FromContext returns a span from context
|
// FromContext returns a span from context.
|
||||||
func FromContext(ctx context.Context) (traceID string, parentSpanID string, isFound bool) {
|
func FromContext(ctx context.Context) (traceID string, parentSpanID string, isFound bool) {
|
||||||
traceID, traceOk := metadata.Get(ctx, traceIDKey)
|
traceID, traceOk := metadata.Get(ctx, traceIDKey)
|
||||||
microID, microOk := metadata.Get(ctx, "Micro-Id")
|
microID, microOk := metadata.Get(ctx, "Micro-Id")
|
||||||
@@ -68,7 +68,7 @@ func FromContext(ctx context.Context) (traceID string, parentSpanID string, isFo
|
|||||||
return traceID, parentSpanID, ok
|
return traceID, parentSpanID, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToContext saves the trace and span ids in the context
|
// ToContext saves the trace and span ids in the context.
|
||||||
func ToContext(ctx context.Context, traceID, parentSpanID string) context.Context {
|
func ToContext(ctx context.Context, traceID, parentSpanID string) context.Context {
|
||||||
return metadata.MergeContext(ctx, map[string]string{
|
return metadata.MergeContext(ctx, map[string]string{
|
||||||
traceIDKey: traceID,
|
traceIDKey: traceID,
|
||||||
|
@@ -117,7 +117,7 @@ func InternalServerError(id, format string, a ...interface{}) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal tries to compare errors
|
// Equal tries to compare errors.
|
||||||
func Equal(err1 error, err2 error) bool {
|
func Equal(err1 error, err2 error) bool {
|
||||||
verr1, ok1 := err1.(*Error)
|
verr1, ok1 := err1.(*Error)
|
||||||
verr2, ok2 := err2.(*Error)
|
verr2, ok2 := err2.(*Error)
|
||||||
@@ -137,7 +137,7 @@ func Equal(err1 error, err2 error) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromError try to convert go error to *Error
|
// FromError try to convert go error to *Error.
|
||||||
func FromError(err error) *Error {
|
func FromError(err error) *Error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -149,7 +149,7 @@ func FromError(err error) *Error {
|
|||||||
return Parse(err.Error())
|
return Parse(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// As finds the first error in err's chain that matches *Error
|
// As finds the first error in err's chain that matches *Error.
|
||||||
func As(err error) (*Error, bool) {
|
func As(err error) (*Error, bool) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user