Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize examples #618

Merged
merged 8 commits into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,30 @@ before_install:
- go get github.com/dghubble/sling
- go get github.com/go-resty/resty
install:
# Make sure externally referenced packages are go-gettable.
- go get github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
- go get github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
- go get github.com/grpc-ecosystem/grpc-gateway/runtime
- go get github.com/grpc-ecosystem/grpc-gateway/examples
- go get github.com/grpc-ecosystem/grpc-gateway/examples/server
- go get github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-grpc-server
- go get github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-gateway-server
before_script:
- sh -c 'cd examples/browser && npm install'
script:
- if [ "${USE_BAZEL}" = true ]; then ./.travis/bazel-build.sh; fi
- if [ "${USE_BAZEL}" = true ]; then ./.travis/bazel-test.sh; fi

# Make sure examples of generated files are up-to-date
- if [ -z "${USE_BAZEL}" ]; then make realclean && make examples SWAGGER_CODEGEN="java -jar $HOME/local/swagger-codegen-cli.jar"; fi
- if [ -z "${USE_BAZEL}" ] && (go version | grep -q "${GO_VERSION_TO_DIFF_TEST}") && [ -z "${GATEWAY_PLUGIN_FLAGS}" ]; then test -z "$(git status --porcelain)" || (git status; git diff; exit 1); fi

# Unit tests, integration tests and code health checks
- if [ -z "${USE_BAZEL}" ]; then env GLOG_logtostderr=1 go test -race -v github.com/grpc-ecosystem/grpc-gateway/...; fi
- if [ -z "${USE_BAZEL}" ]; then make lint; fi
- if [ -z "${USE_BAZEL}" ]; then sh -c 'cd examples/browser && node ./node_modules/gulp/bin/gulp'; fi
- if (go version | grep -q "${GO_VERSION_TO_DIFF_TEST}") && [ -z "${GATEWAY_PLUGIN_FLAGS}" ]; then env GLOG_logtostderr=1 ./bin/coverage; fi
after_success:
- bash <(curl -s https://codecov.io/bash)

env:
global:
- "PATH=$PATH:$HOME/local/bin"
Expand Down
26 changes: 13 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,33 +48,33 @@ RUNTIME_GO=$(RUNTIME_PROTO:.proto=.pb.go)
OPENAPIV2_PROTO=protoc-gen-swagger/options/openapiv2.proto protoc-gen-swagger/options/annotations.proto
OPENAPIV2_GO=$(OPENAPIV2_PROTO:.proto=.pb.go)

PKGMAP=Mgoogle/protobuf/descriptor.proto=$(GO_PLUGIN_PKG)/descriptor,Mexamples/sub/message.proto=$(PKG)/examples/sub
PKGMAP=Mgoogle/protobuf/descriptor.proto=$(GO_PLUGIN_PKG)/descriptor,Mexamples/proto/sub/message.proto=$(PKG)/examples/proto/sub
ADDITIONAL_FLAGS=
ifneq "$(GATEWAY_PLUGIN_FLAGS)" ""
ADDITIONAL_FLAGS=,$(GATEWAY_PLUGIN_FLAGS)
endif
SWAGGER_EXAMPLES=examples/examplepb/echo_service.proto \
examples/examplepb/a_bit_of_everything.proto \
examples/examplepb/wrappers.proto
EXAMPLES=examples/examplepb/echo_service.proto \
examples/examplepb/a_bit_of_everything.proto \
examples/examplepb/stream.proto \
examples/examplepb/flow_combination.proto \
examples/examplepb/wrappers.proto
SWAGGER_EXAMPLES=examples/proto/examplepb/echo_service.proto \
examples/proto/examplepb/a_bit_of_everything.proto \
examples/proto/examplepb/wrappers.proto
EXAMPLES=examples/proto/examplepb/echo_service.proto \
examples/proto/examplepb/a_bit_of_everything.proto \
examples/proto/examplepb/stream.proto \
examples/proto/examplepb/flow_combination.proto \
examples/proto/examplepb/wrappers.proto
EXAMPLE_SVCSRCS=$(EXAMPLES:.proto=.pb.go)
EXAMPLE_GWSRCS=$(EXAMPLES:.proto=.pb.gw.go)
EXAMPLE_SWAGGERSRCS=$(SWAGGER_EXAMPLES:.proto=.swagger.json)
EXAMPLE_DEPS=examples/sub/message.proto examples/sub2/message.proto
EXAMPLE_DEPS=examples/proto/sub/message.proto examples/proto/sub2/message.proto
EXAMPLE_DEPSRCS=$(EXAMPLE_DEPS:.proto=.pb.go)

EXAMPLE_CLIENT_DIR=examples/clients
ECHO_EXAMPLE_SPEC=examples/examplepb/echo_service.swagger.json
ECHO_EXAMPLE_SPEC=examples/proto/examplepb/echo_service.swagger.json
ECHO_EXAMPLE_SRCS=$(EXAMPLE_CLIENT_DIR)/echo/api_client.go \
$(EXAMPLE_CLIENT_DIR)/echo/api_response.go \
$(EXAMPLE_CLIENT_DIR)/echo/configuration.go \
$(EXAMPLE_CLIENT_DIR)/echo/echo_service_api.go \
$(EXAMPLE_CLIENT_DIR)/echo/examplepb_simple_message.go
ABE_EXAMPLE_SPEC=examples/examplepb/a_bit_of_everything.swagger.json
ABE_EXAMPLE_SPEC=examples/proto/examplepb/a_bit_of_everything.swagger.json
ABE_EXAMPLE_SRCS=$(EXAMPLE_CLIENT_DIR)/abe/a_bit_of_everything_nested.go \
$(EXAMPLE_CLIENT_DIR)/abe/a_bit_of_everything_service_api.go \
$(EXAMPLE_CLIENT_DIR)/abe/api_client.go \
Expand Down Expand Up @@ -141,7 +141,7 @@ $(ABE_EXAMPLE_SRCS): $(ABE_EXAMPLE_SPEC)
examples: $(EXAMPLE_SVCSRCS) $(EXAMPLE_GWSRCS) $(EXAMPLE_DEPSRCS) $(EXAMPLE_SWAGGERSRCS) $(EXAMPLE_CLIENT_SRCS)
test: examples
go test -race $(PKG)/...
go test -race $(PKG)/examples -args -network=unix -endpoint=test.sock
go test -race $(PKG)/examples/integration -args -network=unix -endpoint=test.sock

lint:
golint --set_exit_status $(PKG)/runtime
Expand Down
8 changes: 4 additions & 4 deletions examples/browser/gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ gulp.task('bower', function(){
});

gulp.task('server', shell.task([
'go build -o bin/example-server github.com/grpc-ecosystem/grpc-gateway/examples/server/cmd/example-server',
'go build -o bin/example-server github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-grpc-server',
]));

gulp.task('gateway', shell.task([
'go build -o bin/example-gw github.com/grpc-ecosystem/grpc-gateway/examples',
'go build -o bin/example-gw github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-gateway-server',
]));

gulp.task('serve-server', ['server'], function(){
Expand All @@ -32,9 +32,9 @@ gulp.task('serve-server', ['server'], function(){

gulp.task('serve-gateway', ['gateway', 'serve-server'], function(){
gprocess.start('gateway-server', 'bin/example-gw', [
'--logtostderr', '--swagger_dir', path.join(__dirname, "../examplepb"),
'--logtostderr', '--swagger_dir', path.join(__dirname, "../proto/examplepb"),
]);
gulp.watch('bin/example-gateway', ['serve-gateway']);
gulp.watch('bin/example-gw', ['serve-gateway']);
});

gulp.task('backends', ['serve-gateway', 'serve-server']);
Expand Down
18 changes: 18 additions & 0 deletions examples/cmd/example-gateway-server/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")

go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-gateway-server",
visibility = ["//visibility:private"],
deps = [
"//examples/gateway:go_default_library",
"@com_github_golang_glog//:go_default_library",
],
)

go_binary(
name = "example-gateway-server",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
37 changes: 37 additions & 0 deletions examples/cmd/example-gateway-server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Command example-gateway-server is an example reverse-proxy implementation
whose HTTP handler is generated by grpc-gateway.
*/
package main

import (
"context"
"flag"

"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/examples/gateway"
)

var (
endpoint = flag.String("endpoint", "localhost:9090", "endpoint of the gRPC service")
network = flag.String("network", "tcp", `one of "tcp" or "unix". Must be consistent to -endpoint`)
swaggerDir = flag.String("swagger_dir", "examples/proto/examplepb", "path to the directory which contains swagger definitions")
)

func main() {
flag.Parse()
defer glog.Flush()

ctx := context.Background()
opts := gateway.Options{
Addr: ":8080",
GRPCServer: gateway.Endpoint{
Network: *network,
Addr: *endpoint,
},
SwaggerDir: *swaggerDir,
}
if err := gateway.Run(ctx, opts); err != nil {
glog.Fatal(err)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package(default_visibility = ["//visibility:private"])
go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "github.com/grpc-ecosystem/grpc-gateway/examples/server/cmd/example-server",
importpath = "github.com/grpc-ecosystem/grpc-gateway/examples/cmd/example-grpc-server",
deps = [
"//examples/server:go_default_library",
"@com_github_golang_glog//:go_default_library",
Expand All @@ -15,4 +15,5 @@ go_library(
go_binary(
name = "example-server",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
Command example-grpc-server is an example grpc server
to be called by example-gateway-server.
*/
package main

import (
Expand Down
10 changes: 8 additions & 2 deletions examples/gateway/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")

go_library(
name = "go_default_library",
srcs = ["gateway.go"],
srcs = [
"doc.go",
"gateway.go",
"handlers.go",
"main.go",
],
importpath = "github.com/grpc-ecosystem/grpc-gateway/examples/gateway",
visibility = ["//visibility:public"],
deps = [
"//examples/examplepb:go_default_library",
"//examples/proto/examplepb:go_default_library",
"//runtime:go_default_library",
"@com_github_golang_glog//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
],
)
2 changes: 2 additions & 0 deletions examples/gateway/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package gateway is an example of grpc-gateway server
package gateway
89 changes: 43 additions & 46 deletions examples/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,67 @@ package gateway

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

"github.com/grpc-ecosystem/grpc-gateway/examples/examplepb"
"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/examples/proto/examplepb"
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"
)

type optSet struct {
mux []gwruntime.ServeMuxOption
dial []grpc.DialOption

echoEndpoint, abeEndpoint, flowEndpoint string
}

// newGateway returns a new gateway server which translates HTTP into gRPC.
func newGateway(ctx context.Context, opts optSet) (http.Handler, error) {
mux := gwruntime.NewServeMux(opts.mux...)

err := examplepb.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, opts.echoEndpoint, opts.dial)
if err != nil {
return nil, err
}
err = examplepb.RegisterStreamServiceHandlerFromEndpoint(ctx, mux, opts.abeEndpoint, opts.dial)
if err != nil {
return nil, err
}
err = examplepb.RegisterABitOfEverythingServiceHandlerFromEndpoint(ctx, mux, opts.abeEndpoint, opts.dial)
func newGateway(ctx context.Context, network, addr string, opts []gwruntime.ServeMuxOption) (http.Handler, error) {
conn, err := dial(ctx, network, addr)
if err != nil {
return nil, err
}
err = examplepb.RegisterFlowCombinationHandlerFromEndpoint(ctx, mux, opts.flowEndpoint, opts.dial)
if err != nil {
return nil, err
go func() {
<-ctx.Done()
if err := conn.Close(); err != nil {
glog.Errorf("Failed to close a client connection to the gRPC server: %v", err)
}
}()

mux := gwruntime.NewServeMux(opts...)

for _, f := range []func(context.Context, *gwruntime.ServeMux, *grpc.ClientConn) error{
examplepb.RegisterEchoServiceHandler,
examplepb.RegisterStreamServiceHandler,
examplepb.RegisterABitOfEverythingServiceHandler,
examplepb.RegisterFlowCombinationHandler,
} {
if err := f(ctx, mux, conn); err != nil {
return nil, err
}
}
return mux, nil
}

// NewTCPGateway returns a new gateway server which connect to the gRPC service with TCP.
func dial(ctx context.Context, network, addr string) (*grpc.ClientConn, error) {
switch network {
case "tcp":
return dialTCP(ctx, addr)
case "unix":
return dialUnix(ctx, addr)
default:
return nil, fmt.Errorf("unsupported network type %q", network)
}
}

// dialTCP creates a client connection via TCP.
// "addr" must be a valid TCP address with a port number.
func NewTCPGateway(ctx context.Context, addr string, opts ...gwruntime.ServeMuxOption) (http.Handler, error) {
return newGateway(ctx, optSet{
mux: opts,
dial: []grpc.DialOption{grpc.WithInsecure()},
echoEndpoint: addr,
abeEndpoint: addr,
flowEndpoint: addr,
})
func dialTCP(ctx context.Context, addr string) (*grpc.ClientConn, error) {
return grpc.DialContext(ctx, addr, grpc.WithInsecure())
}

// NewUnixGatway returns a new gateway server which connect to the gRPC service with a unix domain socket.
// dialUnix creates a client connection via a unix domain socket.
// "addr" must be a valid path to the socket.
func NewUnixGateway(ctx context.Context, addr string, opts ...gwruntime.ServeMuxOption) (http.Handler, error) {
return newGateway(ctx, optSet{
mux: opts,
dial: []grpc.DialOption{
grpc.WithInsecure(),
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", addr, timeout)
}),
},
echoEndpoint: addr,
abeEndpoint: addr,
flowEndpoint: addr,
})
func dialUnix(ctx context.Context, addr string) (*grpc.ClientConn, error) {
d := func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", addr, timeout)
}
return grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithDialer(d))
}
48 changes: 48 additions & 0 deletions examples/gateway/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package gateway

import (
"net/http"
"path"
"strings"

"github.com/golang/glog"
)

func swaggerServer(dir string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !strings.HasSuffix(r.URL.Path, ".swagger.json") {
glog.Errorf("Not Found: %s", r.URL.Path)
http.NotFound(w, r)
return
}

glog.Infof("Serving %s", r.URL.Path)
p := strings.TrimPrefix(r.URL.Path, "/swagger/")
p = path.Join(dir, p)
http.ServeFile(w, r, p)
}
}

// allowCORS allows Cross Origin Resoruce Sharing from any origin.
// Don't do this without consideration in production systems.
func allowCORS(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if origin := r.Header.Get("Origin"); origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
if r.Method == "OPTIONS" && r.Header.Get("Access-Control-Request-Method") != "" {
preflightHandler(w, r)
return
}
}
h.ServeHTTP(w, r)
})
}

func preflightHandler(w http.ResponseWriter, r *http.Request) {
headers := []string{"Content-Type", "Accept"}
w.Header().Set("Access-Control-Allow-Headers", strings.Join(headers, ","))
methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE"}
w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ","))
glog.Infof("preflight request for %s", r.URL.Path)
return
}
Loading