Skip to content

Commit

Permalink
Merge pull request #1 from joelurraco/grpc_gw_options
Browse files Browse the repository at this point in the history
Grpc gw options
  • Loading branch information
joelurraco committed Jul 2, 2018
2 parents 2a0396a + 9330691 commit d0f4299
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 8 deletions.
14 changes: 14 additions & 0 deletions cmd/sample/impl/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"bitbucket.org/acbapis/acbapis/common"
"bitbucket.org/acbapis/acbapis/status"
"github.com/jllopis/mifo/version"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)

// StatusService provides a service that offers basic status functionality:
Expand All @@ -17,11 +19,19 @@ type StatusService struct{}

// GetServerTime returns the current UTC server time in nanoseconds
func (st *StatusService) GetServerTime(ctx context.Context, empty *common.EmptyMessage) (*status.ServerTimeMessage, error) {
headerVal := "max-age=600, s-maxage=600"
grpc.SetHeader(ctx, metadata.Pairs("Grpc-Metadata-Cache-Control", headerVal))
grpc.SetHeader(ctx, metadata.Pairs("Grpc-Metadata-X-App-Cache-Control", headerVal))

return &status.ServerTimeMessage{Value: time.Now().UTC().UnixNano()}, nil
}

// GetVersion returns the current API Version. It is a direct mapping from go-version "github.com/hashicorp/go-version.Version
func (st *StatusService) GetVersion(ctx context.Context, empty *common.EmptyMessage) (*common.Version, error) {
headerVal := "max-age=600, s-maxage=600"
grpc.SetHeader(ctx, metadata.Pairs("Grpc-Metadata-Cache-Control", headerVal))
grpc.SetHeader(ctx, metadata.Pairs("Grpc-Metadata-X-App-Cache-Control", headerVal))

return &common.Version{
Version: version.Version,
APIVersion: version.APIVersion,
Expand All @@ -31,6 +41,10 @@ func (st *StatusService) GetVersion(ctx context.Context, empty *common.EmptyMess
}

func (st *StatusService) GetGlobalServiceStatus(ctx context.Context, empty *common.EmptyMessage) (*status.ServerStatusMessage, error) {
headerVal := "max-age=600, s-maxage=600"
grpc.SetHeader(ctx, metadata.Pairs("Grpc-Metadata-Cache-Control", headerVal))
grpc.SetHeader(ctx, metadata.Pairs("Grpc-Metadata-X-App-Cache-Control", headerVal))

serverStatus := &status.ServerStatusMessage{
Status: status.ServerStatus_OK,
}
Expand Down
7 changes: 6 additions & 1 deletion cmd/sample/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ func main() {
api.Register(statusRegistrator)

// Use grpc-gw ...
api.UseGrpcGw()
api.UseGrpcGw(
mifo.WithCORS(),
mifo.WithMetrics(),
mifo.LogRequests(),
mifo.WithOutgoingHeaderMatcher(runtime.DefaultHeaderMatcher),
)
// ... and register http proxy services
opts := []grpc.DialOption{
grpc.WithInsecure(),
Expand Down
1 change: 1 addition & 0 deletions microserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type GrpcServer struct {
HttpMux *http.ServeMux
HttpSrv *http.Server
GrpcGwMux *runtime.ServeMux
grpcGwOpts options
// Interceptors
UnaryInter []grpc.UnaryServerInterceptor
StreamInter []grpc.StreamServerInterceptor
Expand Down
75 changes: 68 additions & 7 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,39 @@ import (
"github.com/soheilhy/cmux"
)

type options struct {
cors bool
metrics bool
logRequests bool
outgoingHeaderMatcher runtime.HeaderMatcherFunc
}

type Option func(*options)

func WithCORS() Option {
return func(o *options) {
o.cors = true
}
}

func WithMetrics() Option {
return func(o *options) {
o.metrics = true
}
}

func WithOutgoingHeaderMatcher(fn runtime.HeaderMatcherFunc) Option {
return func(o *options) {
o.outgoingHeaderMatcher = fn
}
}

func LogRequests() Option {
return func(o *options) {
o.logRequests = true
}
}

func (g *GrpcServer) WithListener(l net.Listener) *GrpcServer {
// Crear el muxer cmux
g.CmuxSrv = newCMux(l)
Expand Down Expand Up @@ -49,21 +82,49 @@ func (g *GrpcServer) UseReflection() *GrpcServer {
return g
}

func (g *GrpcServer) UseGrpcGw() *GrpcServer {
g.GrpcGwMux = runtime.NewServeMux()
g.HttpMux.Handle("/", logh(g.GrpcGwMux))
func (g *GrpcServer) UseGrpcGw(opts ...Option) *GrpcServer {
grpcGwOpts := &options{}
for _, opt := range opts {
opt(grpcGwOpts)
}

g.grpcGwOpts = *grpcGwOpts

outgoingHeaderMatcher := g.grpcGwOpts.outgoingHeaderMatcher
g.GrpcGwMux = runtime.NewServeMux(runtime.WithOutgoingHeaderMatcher(outgoingHeaderMatcher))
g.HttpMux.Handle("/", g.indexHandler(g.GrpcGwMux))
return g
}

func (g *GrpcServer) String() string {
return fmt.Sprintf("gRPC Microservice\n=================\n Name: %s\n ID: %s\n", g.Name, g.ID)
}

func logh(handler http.Handler) http.Handler {
func (g *GrpcServer) indexHandler(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Info(fmt.Sprintf("%s %s %s", r.RemoteAddr, r.Method, r.URL))
// Registrar llamada REST
metrics.Counter("rest.requests").Add()
if g.grpcGwOpts.logRequests {
log.Info(fmt.Sprintf("%s %s %s", r.RemoteAddr, r.Method, r.URL))
}

if g.grpcGwOpts.metrics {
// Registrar llamada REST
metrics.Counter("rest.requests").Add()
}

if g.grpcGwOpts.cors {
enableCors(&w)

if r.Method == "OPTIONS" {
return
}
}

handler.ServeHTTP(w, r)
})
}

func enableCors(w *http.ResponseWriter) {
(*w).Header().Set("Access-Control-Allow-Origin", "*")
(*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
(*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}

0 comments on commit d0f4299

Please sign in to comment.