github.com/gofunct/common@v0.0.0-20190131174352-fd058c7fbf22/pkg/transport/engine/gateway.go (about) 1 package engine 2 3 import ( 4 "context" 5 "github.com/gofunct/common/pkg/transport/api" 6 "github.com/gofunct/common/pkg/transport/config" 7 "net" 8 "net/http" 9 "time" 10 11 "github.com/grpc-ecosystem/grpc-gateway/runtime" 12 "github.com/pkg/errors" 13 "google.golang.org/grpc" 14 "google.golang.org/grpc/grpclog" 15 ) 16 17 // NewGatewayServer creates GrpcServer instance. 18 func NewGatewayServer(c *config.Config) api.Interface { 19 return &GatewayServer{ 20 Config: c, 21 } 22 } 23 24 // GatewayServer wraps gRPC gateway server setup process. 25 type GatewayServer struct { 26 server *http.Server 27 *config.Config 28 } 29 30 // Serve implements Server.Shutdown 31 func (s *GatewayServer) Serve(l net.Listener) error { 32 conn, err := s.createConn() 33 if err != nil { 34 return errors.Wrap(err, "failed to create connection with grpc-gateway server") 35 } 36 defer conn.Close() 37 38 s.server, err = s.createServer(conn) 39 if err != nil { 40 return errors.Wrap(err, "failed to create gRPC Gateway server: %v") 41 } 42 43 grpclog.Infof("grpc-gateway server is starting %s", l.Addr()) 44 45 err = s.server.Serve(l) 46 47 grpclog.Infof("stopped taking more http(s) requests: %v", err) 48 49 if err != http.ErrServerClosed { 50 return errors.Wrap(err, "failed to serve grpc-gateway server") 51 } 52 53 return nil 54 } 55 56 // Shutdown implements Server.Shutdown 57 func (s *GatewayServer) Shutdown() { 58 ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) 59 defer cancel() 60 err := s.server.Shutdown(ctx) 61 grpclog.Info("All http(s) requets finished") 62 if err != nil { 63 grpclog.Errorf("failed to shutdown grpc-gateway server: %v", err) 64 } 65 } 66 67 func (s *GatewayServer) createConn() (conn *grpc.ClientConn, err error) { 68 conn, err = grpc.Dial(s.GrpcInternalAddr.Addr, s.ClientOptions()...) 69 if err != nil { 70 err = errors.Wrap(err, "failed to connect to gRPC server") 71 } 72 return 73 } 74 75 func (s *GatewayServer) createServer(conn *grpc.ClientConn) (*http.Server, error) { 76 mux := runtime.NewServeMux( 77 append( 78 []runtime.ServeMuxOption{runtime.WithProtoErrorHandler(runtime.DefaultHTTPProtoErrorHandler)}, 79 s.GatewayMuxOptions..., 80 )..., 81 ) 82 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) 83 defer cancel() 84 85 for _, svr := range s.Servers { 86 err := svr.RegisterWithHandler(ctx, mux, conn) 87 if err != nil { 88 return nil, errors.Wrap(err, "failed to register handler") 89 } 90 } 91 92 var handler http.Handler = mux 93 94 for i := len(s.GatewayServerMiddlewares) - 1; i >= 0; i-- { 95 handler = (s.GatewayServerMiddlewares[i])(handler) 96 } 97 98 svr := &http.Server{ 99 Handler: handler, 100 } 101 if cfg := s.GatewayServerConfig; cfg != nil { 102 cfg.ApplyTo(svr) 103 } 104 105 return svr, nil 106 }