Skip to content

Commit

Permalink
Merge pull request #2 from hb-chen/master
Browse files Browse the repository at this point in the history
mv starter-kit's gateway plugin to x-gateway
  • Loading branch information
hb-chen authored Nov 22, 2019
2 parents 1f73f37 + 6a7dc3f commit 282b008
Show file tree
Hide file tree
Showing 27 changed files with 82 additions and 400 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@

## 功能设计

+ 认证&鉴权`JWT`+`Casbin` [Auth](/plugin/auth)
+ 跨域支持 [CORS](/plugin/cors)
+ Metrics [Prometheus](/plugin/metrics)
+ 认证&鉴权`JWT`+`Casbin` [Auth](/pkg/plugin/wrapper/auth)
+ 跨域支持 [CORS](/pkg/plugin/wrapper/cors)
+ Metrics [Prometheus](/pkg/plugin/wrapper/metrics)
+ Trace [Opentracing](/pkg/plugin/wrapper/trace/opentracing)
+ REST to GRPC 转换REST调用到GRPC(HTTP[s] -> API-Gateway -> Micro Srv)[计划中...]
- 高性能
- 智能路由
Expand Down
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
module github.com/micro-community/api-gateway
module github.com/micro-in-cn/x-gateway

go 1.13

replace github.com/gogo/protobuf v0.0.0-20190410021324-65acae22fc9 => github.com/gogo/protobuf v0.0.0-20190723190241-65acae22fc9d

require (
github.com/casbin/casbin/v2 v2.1.1
github.com/chzyer/logex v1.1.10 // indirect
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/micro/cli v0.2.0
github.com/micro/go-micro v1.16.0
Expand All @@ -14,6 +17,7 @@ require (
github.com/opentracing/opentracing-go v1.1.0
github.com/prometheus/client_golang v1.2.1
github.com/rs/cors v1.7.0
github.com/stretchr/testify v1.4.0
github.com/uber/jaeger-client-go v2.20.1+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion plugin/auth/auth.go → pkg/plugin/wrapper/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"github.com/micro/micro/plugin"
)

const id = "hb-go.micro-plugins.micro.auth"
const id = "micro.x-gateway.auth"

var adapters map[string]persist.Adapter
var watchers map[string]persist.Watcher
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions plugin/auth/options.go → pkg/plugin/wrapper/auth/options.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package auth

import (
"github.com/micro-community/api-gateway/plugin/util/request"
"github.com/micro-community/api-gateway/plugin/util/response"
"github.com/micro-in-cn/x-gateway/pkg/plugin/wrapper/util/request"
"github.com/micro-in-cn/x-gateway/pkg/plugin/wrapper/util/response"
)

type Options struct {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package metrics

import (
"github.com/micro-community/api-gateway/plugin/util/request"
"github.com/micro-in-cn/x-gateway/pkg/plugin/wrapper/util/request"
)

type Options struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"

"github.com/micro-community/api-gateway/plugin/util/request"
"github.com/micro-community/api-gateway/plugin/util/response"
"github.com/micro-in-cn/x-gateway/pkg/plugin/wrapper/utilper/util/request"
"github.com/micro-in-cn/x-gateway/pkg/plugin/wrapper/utilper/util/response"
)

var (
Expand Down
File renamed without changes.
3 changes: 0 additions & 3 deletions pkg/plugin/wrapper/trace/opentracing/README.md

This file was deleted.

213 changes: 58 additions & 155 deletions pkg/plugin/wrapper/trace/opentracing/opentracing.go
Original file line number Diff line number Diff line change
@@ -1,188 +1,91 @@
// Package opentracing provides wrappers for OpenTracing
package opentracing

import (
"context"
"fmt"
"net/http"

"github.com/micro/go-micro/client"
"github.com/micro/go-micro/metadata"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/server"
"github.com/micro/micro/plugin"
"github.com/opentracing/opentracing-go"
)

type otWrapper struct {
ot opentracing.Tracer
client.Client
}

// StartSpanFromContext returns a new span with the given operation name and options. If a span
// is found in the context, it will be used as the parent of the resulting span.
func StartSpanFromContext(ctx context.Context, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (context.Context, opentracing.Span, error) {
md, ok := metadata.FromContext(ctx)
if !ok {
md = make(map[string]string)
}
"github.com/micro-in-cn/x-gateway/pkg/plugin/wrapper/util/response"
)

// copy the metadata to prevent race
md = metadata.Copy(md)
// StartSpanFromHeader returns a new span with the given operation name and options. If a span
// is found in the header, it will be used as the parent of the resulting span.
func StartSpanFromHeader(header http.Header, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (opentracing.Span, error) {

// Find parent span.
// First try to get span within current service boundary.
// If there doesn't exist, try to get it from go-micro metadata(which is cross boundary)
if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil {
opts = append(opts, opentracing.ChildOf(parentSpan.Context()))
} else if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.TextMapCarrier(md)); err == nil {
if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err == nil {
opts = append(opts, opentracing.ChildOf(spanCtx))
}

sp := tracer.StartSpan(name, opts...)

if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.TextMapCarrier(md)); err != nil {
return nil, nil, err
if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err != nil {
return nil, err
}

ctx = opentracing.ContextWithSpan(ctx, sp)
ctx = metadata.NewContext(ctx, md)
return ctx, sp, nil
return sp, nil
}

// SpanFromContext returns a new span with the given operation name and options.
// 如果没在context中没有找到span,返回nil
func SpanFromContext(ctx context.Context, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (context.Context, opentracing.Span, error) {
md, ok := metadata.FromContext(ctx)
if !ok {
md = make(map[string]string)
}

// copy the metadata to prevent race
md = metadata.Copy(md)
func SpanFromHeader(header http.Header, tracer opentracing.Tracer, name string, opts ...opentracing.StartSpanOption) (opentracing.Span, error) {

// Find parent span.
// First try to get span within current service boundary.
// If there doesn't exist, try to get it from go-micro metadata(which is cross boundary)
if parentSpan := opentracing.SpanFromContext(ctx); parentSpan != nil {
opts = append(opts, opentracing.ChildOf(parentSpan.Context()))
} else if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.TextMapCarrier(md)); err == nil {
if spanCtx, err := tracer.Extract(opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err == nil {
opts = append(opts, opentracing.ChildOf(spanCtx))
} else {
return ctx, nil, nil
return nil, nil
}

sp := tracer.StartSpan(name, opts...)

if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.TextMapCarrier(md)); err != nil {
return nil, nil, err
}

ctx = opentracing.ContextWithSpan(ctx, sp)
ctx = metadata.NewContext(ctx, md)
return ctx, sp, nil
}

func (o *otWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
ctx, span, err := SpanFromContext(ctx, o.ot, name)
if err != nil {
return err
} else if span != nil {
defer span.Finish()
}

return o.Client.Call(ctx, req, rsp, opts...)
}

func (o *otWrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) {
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
ctx, span, err := SpanFromContext(ctx, o.ot, name)
if err != nil {
if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.HTTPHeadersCarrier(header)); err != nil {
return nil, err
} else if span != nil {
defer span.Finish()
}

return o.Client.Stream(ctx, req, opts...)
}

func (o *otWrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error {
name := fmt.Sprintf("Pub to %s", p.Topic())
ctx, span, err := SpanFromContext(ctx, o.ot, name)
if err != nil {
return err
} else if span != nil {
defer span.Finish()
}

return o.Client.Publish(ctx, p, opts...)
return sp, nil
}

// NewClientWrapper accepts an open tracing Trace and returns a Client Wrapper
func NewClientWrapper(ot opentracing.Tracer) client.Wrapper {
return func(c client.Client) client.Client {
if ot == nil {
ot = opentracing.GlobalTracer()
}
return &otWrapper{ot, c}
}
func newPlugin(opts ...Option) plugin.Plugin {
options := newOptions(opts...)
return plugin.NewPlugin(
plugin.WithName("trace"),
plugin.WithHandler(func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if options.skipperFunc(r) {
h.ServeHTTP(w, r)
return
}

name := r.URL.Path
var span opentracing.Span
var err error
if options.autoStart {
span, err = StartSpanFromHeader(r.Header, options.tracer, name)

} else {
span, err = SpanFromHeader(r.Header, options.tracer, name)
}

if err != nil {
options.responseHandler(w, r, err)
return
} else if span != nil {
defer span.Finish()

span.SetTag("http.host", r.Host)
span.SetTag("http.method", r.Method)

ww := response.WrapWriter{ResponseWriter: w}
h.ServeHTTP(&ww, r)

span.SetTag("http.status_code", ww.StatusCode)
} else {
h.ServeHTTP(w, r)
}
})
}),
)
}

// NewCallWrapper accepts an opentracing Tracer and returns a Call Wrapper
func NewCallWrapper(ot opentracing.Tracer) client.CallWrapper {
return func(cf client.CallFunc) client.CallFunc {
return func(ctx context.Context, node *registry.Node, req client.Request, rsp interface{}, opts client.CallOptions) error {
if ot == nil {
ot = opentracing.GlobalTracer()
}
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
ctx, span, err := SpanFromContext(ctx, ot, name)
if err != nil {
return err
} else if span != nil {
defer span.Finish()
}

return cf(ctx, node, req, rsp, opts)
}
}
}

// NewHandlerWrapper accepts an opentracing Tracer and returns a Handler Wrapper
func NewHandlerWrapper(ot opentracing.Tracer) server.HandlerWrapper {
return func(h server.HandlerFunc) server.HandlerFunc {
return func(ctx context.Context, req server.Request, rsp interface{}) error {
if ot == nil {
ot = opentracing.GlobalTracer()
}
name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
ctx, span, err := SpanFromContext(ctx, ot, name)
if err != nil {
return err
} else if span != nil {
defer span.Finish()
}

return h(ctx, req, rsp)
}
}
}

// NewSubscriberWrapper accepts an opentracing Tracer and returns a Subscriber Wrapper
func NewSubscriberWrapper(ot opentracing.Tracer) server.SubscriberWrapper {
return func(next server.SubscriberFunc) server.SubscriberFunc {
return func(ctx context.Context, msg server.Message) error {
name := "Pub to " + msg.Topic()
if ot == nil {
ot = opentracing.GlobalTracer()
}
ctx, span, err := SpanFromContext(ctx, ot, name)
if err != nil {
return err
} else if span != nil {
defer span.Finish()
}

return next(ctx, msg)
}
}
func NewPlugin(opts ...Option) plugin.Plugin {
return newPlugin(opts...)
}
Loading

0 comments on commit 282b008

Please sign in to comment.