Beispiel #1
1
// 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,
		})
	}
}
Beispiel #2
0
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)
}
Beispiel #3
0
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 {}
}
Beispiel #4
0
// 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,
			},
		},
	})
}
Beispiel #5
0
func (ht httpTransport) WithRegistry(r transport.Registry, f func(transport.UnaryOutbound)) {
	i := http.NewInbound("127.0.0.1:0")
	require.NoError(ht.t, i.Start(transport.ServiceDetail{Name: testService, Registry: r}, transport.NoDeps), "failed to start")
	defer i.Stop()

	addr := fmt.Sprintf("http://%v/", i.Addr().String())
	o := http.NewOutbound(addr)
	require.NoError(ht.t, o.Start(transport.NoDeps), "failed to start outbound")
	defer o.Stop()
	f(o)
}
Beispiel #6
0
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)
}
Beispiel #7
0
// Phone implements the phone procedure
func Phone(ctx context.Context, reqMeta yarpc.ReqMeta, body *PhoneRequest) (*PhoneResponse, yarpc.ResMeta, error) {
	var outbound transport.UnaryOutbound

	switch {
	case body.Transport.HTTP != nil:
		t := body.Transport.HTTP
		url := fmt.Sprintf("http://%s:%d", t.Host, t.Port)
		outbound = ht.NewOutbound(url)
	case body.Transport.TChannel != nil:
		t := body.Transport.TChannel
		hostport := fmt.Sprintf("%s:%d", t.Host, t.Port)
		ch, err := tchannel.NewChannel("yarpc-test-client", nil)
		if err != nil {
			return nil, nil, fmt.Errorf("failed to build TChannel: %v", err)
		}
		outbound = tch.NewOutbound(ch, tch.HostPort(hostport))
	default:
		return nil, nil, fmt.Errorf("unconfigured transport")
	}

	if err := outbound.Start(transport.NoDeps); err != nil {
		return nil, nil, err
	}
	defer outbound.Stop()

	// TODO use reqMeta.Service for caller
	client := json.New(channel.MultiOutbound("yarpc-test", body.Service, transport.Outbounds{
		Unary: outbound,
	}))
	resBody := PhoneResponse{
		Service:   "yarpc-test", // TODO use reqMeta.Service
		Procedure: reqMeta.Procedure(),
	}

	ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
	defer cancel()
	_, err := client.Call(
		ctx,
		yarpc.NewReqMeta().Procedure(body.Procedure),
		body.Body,
		&resBody.Body)
	if err != nil {
		return nil, nil, err
	}

	return &resBody, nil, nil
}
Beispiel #8
0
func Benchmark_HTTP_YARPCToNetHTTP(b *testing.B) {
	clientCfg := yarpc.Config{
		Name: "client",
		Outbounds: yarpc.Outbounds{
			"server": {
				Unary: yhttp.NewOutbound("http://localhost:8998"),
			},
		},
	}

	withHTTPServer(b, ":8998", httpEcho(b), func() {
		withDispatcher(b, clientCfg, func(client yarpc.Dispatcher) {
			b.ResetTimer()
			runYARPCClient(b, raw.New(client.Channel("server")))
		})
	})
}
Beispiel #9
0
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
}
Beispiel #10
0
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
}
Beispiel #11
0
// 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)
}
Beispiel #12
0
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
}
Beispiel #13
0
// 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())
	}
}
Beispiel #14
0
func Benchmark_HTTP_YARPCToYARPC(b *testing.B) {
	serverCfg := yarpc.Config{
		Name:     "server",
		Inbounds: []transport.Inbound{yhttp.NewInbound(":8999")},
	}

	clientCfg := yarpc.Config{
		Name: "client",
		Outbounds: yarpc.Outbounds{
			"server": {
				Unary: yhttp.NewOutbound("http://localhost:8999"),
			},
		},
	}

	withDispatcher(b, serverCfg, func(server yarpc.Dispatcher) {
		server.Register(raw.Procedure("echo", yarpcEcho))
		withDispatcher(b, clientCfg, func(client yarpc.Dispatcher) {
			b.ResetTimer()
			runYARPCClient(b, raw.New(client.Channel("server")))
		})
	})
}
Beispiel #15
0
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())
	}
}