// Run runs the apachethrift behavior func Run(t crossdock.T) { fatals := crossdock.Fatals(t) server := t.Param(serverParam) fatals.NotEmpty(server, "apachethriftserver is required") baseURL := fmt.Sprintf("http://%v:%v", server, serverPort) thriftOutbound := http.NewOutbound(baseURL + "/thrift/ThriftTest") secondOutbound := http.NewOutbound(baseURL + "/thrift/SecondService") multiplexOutbound := http.NewOutbound(baseURL + "/thrift/multiplexed") dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "apache-thrift-client", Outbounds: yarpc.Outbounds{ "ThriftTest": { Unary: thriftOutbound, Oneway: thriftOutbound, }, "SecondService": { Unary: secondOutbound, }, "Multiplexed": { Unary: multiplexOutbound, Oneway: multiplexOutbound, }, }, }) fatals.NoError(dispatcher.Start(), "could not start Dispatcher") defer dispatcher.Stop() // We can just run all the gauntlet tests against each URL because // tests for undefined methods are skipped. tests := []struct { ServerName string Services gauntlet.ServiceSet Options []thrift.ClientOption }{ { ServerName: "ThriftTest", Services: gauntlet.ThriftTest, }, { ServerName: "SecondService", Services: gauntlet.SecondService, }, { ServerName: "Multiplexed", Services: gauntlet.AllServices, Options: []thrift.ClientOption{thrift.Multiplexed}, }, } for _, tt := range tests { t.Tag("outbound", tt.ServerName) gauntlet.RunGauntlet(t, gauntlet.Config{ Dispatcher: dispatcher, ServerName: tt.ServerName, Envelope: true, Services: tt.Services, ClientOptions: tt.Options, }) } }
func withConnectedClient(t *testing.T, recorder *Recorder, f func(raw.Client)) { serverHTTP := http.NewInbound(":0") serverDisp := yarpc.NewDispatcher(yarpc.Config{ Name: "server", Inbounds: []transport.Inbound{serverHTTP}, }) serverDisp.Register(raw.Procedure("hello", func(ctx context.Context, reqMeta yarpc.ReqMeta, body []byte) ([]byte, yarpc.ResMeta, error) { return append(body, []byte(", World")...), nil, nil })) require.NoError(t, serverDisp.Start()) defer serverDisp.Stop() clientDisp := yarpc.NewDispatcher(yarpc.Config{ Name: "client", Outbounds: yarpc.Outbounds{ "server": { Unary: http.NewOutbound(fmt.Sprintf("http://%s", serverHTTP.Addr().String())), }, }, Filter: recorder, }) require.NoError(t, clientDisp.Start()) defer clientDisp.Stop() client := raw.New(clientDisp.Channel("server")) f(client) }
// Run exercises a YARPC client against a tchannel server. func Run(t crossdock.T) { fatals := crossdock.Fatals(t) encoding := t.Param(params.Encoding) server := t.Param(params.Server) serverHostPort := fmt.Sprintf("%v:%v", server, serverPort) ch, err := tchannel.NewChannel("yarpc-client", nil) fatals.NoError(err, "could not create channel") dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "yarpc-client", Outbounds: yarpc.Outbounds{ serverName: { Unary: tch.NewOutbound(ch, tch.HostPort(serverHostPort)), }, }, }) fatals.NoError(dispatcher.Start(), "could not start Dispatcher") defer dispatcher.Stop() switch encoding { case "raw": runRaw(t, dispatcher) case "json": runJSON(t, dispatcher) case "thrift": runThrift(t, dispatcher) default: fatals.Fail("", "unknown encoding %q", encoding) } }
func withDispatcher(t testing.TB, cfg yarpc.Config, f func(yarpc.Dispatcher)) { d := yarpc.NewDispatcher(cfg) require.NoError(t, d.Start(), "failed to start server") defer d.Stop() f(d) }
func main() { dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "hello", Inbounds: []transport.Inbound{ http.NewInbound(":8086"), }, Outbounds: yarpc.Outbounds{ "hello": { Unary: http.NewOutbound("http://127.0.0.1:8086"), }, }, }) dispatcher.Register(helloserver.New(&helloHandler{})) client := helloclient.New(dispatcher.Channel("hello")) if err := dispatcher.Start(); err != nil { log.Fatal(err) } defer dispatcher.Stop() response, headers := call(client, "Hi There") fmt.Println(response, headers) select {} }
func main() { channel, err := tchannel.NewChannel("keyvalue", nil) if err != nil { log.Fatalln(err) } dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "keyvalue", Inbounds: []transport.Inbound{ tch.NewInbound(channel, tch.ListenAddr(":28941")), http.NewInbound(":24034"), }, Interceptor: yarpc.Interceptors(requestLogInterceptor{}), }) handler := handler{items: make(map[string]string)} dispatcher.Register(json.Procedure("get", handler.Get)) dispatcher.Register(json.Procedure("set", handler.Set)) if err := dispatcher.Start(); err != nil { fmt.Println("error:", err.Error()) os.Exit(1) } select {} }
// Create creates an RPC from the given parameters or fails the whole behavior. func Create(t crossdock.T) yarpc.Dispatcher { fatals := crossdock.Fatals(t) server := t.Param(params.Server) fatals.NotEmpty(server, "server is required") var unaryOutbound transport.UnaryOutbound trans := t.Param(params.Transport) switch trans { case "http": unaryOutbound = ht.NewOutbound(fmt.Sprintf("http://%s:8081", server)) case "tchannel": ch, err := tchannel.NewChannel("client", nil) fatals.NoError(err, "couldn't create tchannel") unaryOutbound = tch.NewOutbound(ch, tch.HostPort(server+":8082")) default: fatals.Fail("", "unknown transport %q", trans) } return yarpc.NewDispatcher(yarpc.Config{ Name: "client", Outbounds: yarpc.Outbounds{ "yarpc-test": { Unary: unaryOutbound, }, }, }) }
func TestHandlerPanic(t *testing.T) { inbound := NewInbound("localhost:0") serverDispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "yarpc-test", Inbounds: []transport.Inbound{inbound}, }) serverDispatcher.Register([]transport.Registrant{ { Procedure: "panic", HandlerSpec: transport.NewUnaryHandlerSpec(panickedHandler{}), }, }) require.NoError(t, serverDispatcher.Start()) defer serverDispatcher.Stop() clientDispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "yarpc-test-client", Outbounds: yarpc.Outbounds{ "yarpc-test": { Unary: NewOutbound(fmt.Sprintf("http://%s", inbound.Addr().String())), }, }, }) require.NoError(t, clientDispatcher.Start()) defer clientDispatcher.Stop() client := raw.New(clientDispatcher.Channel("yarpc-test")) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() _, _, err := client.Call(ctx, yarpc.NewReqMeta().Procedure("panic"), []byte{}) assert.True(t, transport.IsUnexpectedError(err), "Must be an UnexpectedError") assert.Equal(t, `UnexpectedError: error for procedure "panic" of service "yarpc-test": panic: oops I panicked!`, err.Error()) }
func withDisconnectedClient(t *testing.T, recorder *Recorder, f func(raw.Client)) { clientDisp := yarpc.NewDispatcher(yarpc.Config{ Name: "client", Outbounds: yarpc.Outbounds{ "server": { Unary: http.NewOutbound("http://localhost:65535"), }, }, Filter: recorder, }) require.NoError(t, clientDisp.Start()) defer clientDisp.Stop() client := raw.New(clientDisp.Channel("server")) f(client) }
func newDispatcher(t crossdock.T) yarpc.Dispatcher { server := t.Param(params.Server) crossdock.Fatals(t).NotEmpty(server, "server is required") dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "client", Outbounds: yarpc.Outbounds{ "oneway-test": { Oneway: http.NewOutbound(fmt.Sprintf("http://%s:8084", server)), }, }, //for call back Inbounds: []transport.Inbound{http.NewInbound(fmt.Sprintf("%s:8089", server))}, }) // register procedure for remote server to call us back on dispatcher.Register(raw.OnewayProcedure("call-back", callBack)) return dispatcher }
func createHTTPDispatcher(tracer opentracing.Tracer) yarpc.Dispatcher { // TODO: Use port 0 once https://github.com/yarpc/yarpc-go/issues/381 is // fixed. dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "yarpc-test", Inbounds: []transport.Inbound{ http.NewInbound(":18080"), }, Outbounds: yarpc.Outbounds{ "yarpc-test": { Unary: http.NewOutbound("http://127.0.0.1:18080"), }, }, Tracer: tracer, }) return dispatcher }
// Start starts the test server that clients will make requests to func Start() { ch, err := tchannel.NewChannel("yarpc-test", nil) if err != nil { log.Fatalln("couldn't create tchannel: %v", err) } dispatcher = yarpc.NewDispatcher(yarpc.Config{ Name: "yarpc-test", Inbounds: []transport.Inbound{ http.NewInbound(":8081"), tch.NewInbound(ch, tch.ListenAddr(":8082")), }, }) register(dispatcher) if err := dispatcher.Start(); err != nil { fmt.Println("error:", err.Error()) } }
// Run exercise a yarpc client against a rigged httpserver. func Run(t crossdock.T) { fatals := crossdock.Fatals(t) server := t.Param(params.HTTPServer) fatals.NotEmpty(server, "server is required") disp := yarpc.NewDispatcher(yarpc.Config{ Name: "client", Outbounds: yarpc.Outbounds{ "yarpc-test": { Unary: ht.NewOutbound(fmt.Sprintf("http://%s:8085", server)), }, }, }) fatals.NoError(disp.Start(), "could not start Dispatcher") defer disp.Stop() runRaw(t, disp) }
func buildDispatcher(t crossdock.T) (dispatcher yarpc.Dispatcher, tconfig server.TransportConfig) { fatals := crossdock.Fatals(t) self := t.Param("ctxclient") subject := t.Param("ctxserver") fatals.NotEmpty(self, "ctxclient is required") fatals.NotEmpty(subject, "ctxserver is required") ch, err := tchannel.NewChannel("ctxclient", nil) fatals.NoError(err, "failed to create TChannel") var outbound transport.UnaryOutbound switch trans := t.Param(params.Transport); trans { case "http": outbound = ht.NewOutbound(fmt.Sprintf("http://%s:8081", subject)) tconfig.TChannel = &server.TChannelTransport{Host: self, Port: 8087} case "tchannel": outbound = tch.NewOutbound(ch, tch.HostPort(fmt.Sprintf("%s:8082", subject))) tconfig.HTTP = &server.HTTPTransport{Host: self, Port: 8086} default: fatals.Fail("", "unknown transport %q", trans) } dispatcher = yarpc.NewDispatcher(yarpc.Config{ Name: "ctxclient", Inbounds: []transport.Inbound{ tch.NewInbound(ch, tch.ListenAddr(":8087")), ht.NewInbound(":8086"), }, Outbounds: yarpc.Outbounds{ "yarpc-test": { Unary: outbound, }, }, }) return dispatcher, tconfig }
func main() { channel, err := tchannel.NewChannel("keyvalue", nil) if err != nil { log.Fatalln(err) } dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "keyvalue", Inbounds: []transport.Inbound{ tch.NewInbound(channel, tch.ListenAddr(":28941")), http.NewInbound(":24034"), }, }) handler := handler{items: make(map[string]string)} dispatcher.Register(keyvalueserver.New(&handler)) if err := dispatcher.Start(); err != nil { fmt.Println("error:", err.Error()) } select {} // block forever }
// Start starts the test server that clients will make requests to func Start() { h := onewayHandler{ Outbound: http.NewOutbound("http://127.0.0.1:8089"), } dispatcher = yarpc.NewDispatcher(yarpc.Config{ Name: "oneway-test", Inbounds: []transport.Inbound{ http.NewInbound(":8084"), }, Outbounds: yarpc.Outbounds{ "client": {Oneway: h.Outbound}, }, }) dispatcher.Register(raw.OnewayProcedure("echo/raw", h.EchoRaw)) dispatcher.Register(json.OnewayProcedure("echo/json", h.EchoJSON)) dispatcher.Register(onewayserver.New(&h)) if err := dispatcher.Start(); err != nil { fmt.Println("error:", err.Error()) } }
func createTChannelDispatcher(tracer opentracing.Tracer, t *testing.T) yarpc.Dispatcher { // Establish the TChannel ch, err := tchannel.NewChannel("yarpc-test", &tchannel.ChannelOptions{ Tracer: tracer, }) assert.NoError(t, err) hp := "127.0.0.1:4040" ch.ListenAndServe(hp) dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "yarpc-test", Inbounds: []transport.Inbound{ ytchannel.NewInbound(ch), }, Outbounds: yarpc.Outbounds{ "yarpc-test": { Unary: ytchannel.NewOutbound(ch, ytchannel.HostPort(hp)), }, }, Tracer: tracer, }) return dispatcher }
func main() { outboundName := "" flag.StringVar( &outboundName, "outbound", "", "name of the outbound to use (http/tchannel)", ) flag.Parse() var outbound transport.UnaryOutbound switch strings.ToLower(outboundName) { case "http": outbound = http.NewOutbound("http://localhost:24034") case "tchannel": channel, err := tchannel.NewChannel("keyvalue-client", nil) if err != nil { log.Fatalln(err) } outbound = tch.NewOutbound(channel, tch.HostPort("localhost:28941")) default: log.Fatalf("invalid outbound: %q\n", outboundName) } cache := NewCacheFilter() dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "keyvalue-client", Outbounds: yarpc.Outbounds{ "keyvalue": { Unary: outbound, }, }, Filter: cache, }) if err := dispatcher.Start(); err != nil { log.Fatalf("failed to start Dispatcher: %v", err) } defer dispatcher.Stop() client := keyvalueclient.New(dispatcher.Channel("keyvalue")) scanner := bufio.NewScanner(os.Stdin) rootCtx := context.Background() for scanner.Scan() { line := scanner.Text() args := strings.Split(line, " ") if len(args) < 1 || len(args[0]) < 3 { continue } cmd := args[0] args = args[1:] switch cmd { case "get": if len(args) != 1 { fmt.Println("usage: get key") continue } key := args[0] ctx, cancel := context.WithTimeout(rootCtx, 100*time.Millisecond) defer cancel() if value, _, err := client.GetValue(ctx, nil, &key); err != nil { fmt.Printf("get %q failed: %s\n", key, err) } else { fmt.Println(key, "=", value) } continue case "set": if len(args) != 2 { fmt.Println("usage: set key value") continue } key, value := args[0], args[1] cache.Invalidate() ctx, cancel := context.WithTimeout(rootCtx, 100*time.Millisecond) defer cancel() if _, err := client.SetValue(ctx, nil, &key, &value); err != nil { fmt.Printf("set %q = %q failed: %v\n", key, value, err.Error()) } continue case "exit": return default: fmt.Println("invalid command", cmd) fmt.Println("valid commansd are: get, set, exit") } } if err := scanner.Err(); err != nil { fmt.Println("error:", err.Error()) } }