Esempio n. 1
0
func (m *MockClient) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	m.Lock()
	defer m.Unlock()

	response, ok := m.Response[req.Service()]
	if !ok {
		return errors.NotFound("go.micro.client.mock", "service not found")
	}

	for _, r := range response {
		if r.Method != req.Method() {
			continue
		}

		if r.Error != nil {
			return r.Error
		}

		v := reflect.ValueOf(rsp)

		if t := reflect.TypeOf(rsp); t.Kind() == reflect.Ptr {
			v = reflect.Indirect(v)
		}

		v.Set(reflect.ValueOf(r.Response))

		return nil
	}

	return fmt.Errorf("rpc: can't find service %s", req.Method())
}
Esempio n. 2
0
func (c *clientWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	// execute client wrapper?
	if !c.endpoints[req.Method()] {
		// no
		return c.Client.Call(ctx, req, rsp, opts...)
	}

	// yes
	return c.wrapper(c.Client).Call(ctx, req, rsp, opts...)
}
Esempio n. 3
0
func (x *xrayWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	var err error
	s := getSegment(x.opts.Name, ctx)

	defer func() {
		setCallStatus(s, req.Service(), req.Method(), err)
		go record(x.x, s)
	}()

	ctx = newContext(ctx, s)
	err = x.Client.Call(ctx, req, rsp, opts...)
	return err
}
Esempio n. 4
0
func (g *grpcClient) stream(ctx context.Context, address string, req client.Request, opts client.CallOptions) (client.Streamer, error) {
	header := make(map[string]string)
	if md, ok := metadata.FromContext(ctx); ok {
		for k, v := range md {
			header[k] = v
		}
	}

	// set timeout in nanoseconds
	header["timeout"] = fmt.Sprintf("%d", opts.RequestTimeout)
	// set the content type for the request
	header["x-content-type"] = req.ContentType()

	md := gmetadata.New(header)
	ctx = gmetadata.NewContext(ctx, md)

	cf, err := g.newGRPCCodec(req.ContentType())
	if err != nil {
		return nil, errors.InternalServerError("go.micro.client", err.Error())
	}

	// TODO: do not use insecure
	cc, err := grpc.Dial(address, grpc.WithCodec(cf), grpc.WithTimeout(opts.DialTimeout), grpc.WithInsecure())
	if err != nil {
		return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err))
	}

	desc := &grpc.StreamDesc{
		StreamName:    req.Service() + req.Method(),
		ClientStreams: true,
		ServerStreams: true,
	}

	st, err := grpc.NewClientStream(ctx, desc, cc, req.Method())
	if err != nil {
		return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error creating stream: %v", err))
	}

	return &grpcStream{
		context: ctx,
		request: req,
		closed:  make(chan bool),
		stream:  st,
		conn:    cc,
	}, nil
}
Esempio n. 5
0
func (o *otWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	md, _ := metadata.FromContext(ctx)
	name := fmt.Sprintf("%s.%s", req.Service(), req.Method())
	var sp opentracing.Span
	wireContext, err := o.ot.Extract(opentracing.TextMap, opentracing.TextMapCarrier(md))
	if err != nil {
		sp = o.ot.StartSpan(name)
	} else {
		sp = o.ot.StartSpan(name, opentracing.ChildOf(wireContext))
	}
	defer sp.Finish()
	if err := sp.Tracer().Inject(sp.Context(), opentracing.TextMap, opentracing.TextMapCarrier(md)); err != nil {
		return err
	}
	ctx = metadata.NewContext(ctx, md)
	return o.Client.Call(ctx, req, rsp, opts...)
}
Esempio n. 6
0
func (g *grpcClient) call(ctx context.Context, address string, req client.Request, rsp interface{}, opts client.CallOptions) error {
	header := make(map[string]string)
	if md, ok := metadata.FromContext(ctx); ok {
		for k, v := range md {
			header[k] = v
		}
	}

	// set timeout in nanoseconds
	header["timeout"] = fmt.Sprintf("%d", opts.RequestTimeout)
	// set the content type for the request
	header["x-content-type"] = req.ContentType()

	md := gmetadata.New(header)
	ctx = gmetadata.NewContext(ctx, md)

	cf, err := g.newGRPCCodec(req.ContentType())
	if err != nil {
		return errors.InternalServerError("go.micro.client", err.Error())
	}

	var grr error
	// TODO: do not use insecure
	cc, err := grpc.Dial(address, grpc.WithCodec(cf), grpc.WithTimeout(opts.DialTimeout), grpc.WithInsecure())
	if err != nil {
		return errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err))
	}
	defer cc.Close()

	ch := make(chan error, 1)

	go func() {
		ch <- grpc.Invoke(ctx, req.Method(), req.Request(), rsp, cc)
	}()

	select {
	case err := <-ch:
		grr = err
	case <-ctx.Done():
		grr = ctx.Err()
	}

	return grr
}
Esempio n. 7
0
func (c *clientWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	var span *Span
	var ok, okk bool
	var err error
	md := metadata.Metadata{}

	// try pull span from context
	span, ok = c.t.FromContext(ctx)
	if !ok {
		// couldn't do that, try from the metadata

		// So get trace info from metadata
		var kk bool
		md, kk = metadata.FromContext(ctx)
		if !kk {
			// couldn't do that either

			// so this is a new span!
			md = metadata.Metadata{}
			span = c.t.NewSpan(nil)
		} else {
			// ok we got some md

			// can we get the span from the header?
			span, okk = c.t.FromHeader(md)
			if !okk {
				// no, ok create one!
				span = c.t.NewSpan(nil)
			}
		}
	}

	// got parent span from context or metadata
	if okk || ok {
		// setup the span with parent
		span = c.t.NewSpan(&Span{
			// same trace id
			TraceId: span.TraceId,
			// set parent id to parent span id
			ParentId: span.Id,
			// use previous debug
			Debug: span.Debug,
		})
	}

	// start the span
	span.Annotations = append(span.Annotations, &Annotation{
		Timestamp: time.Now(),
		Type:      AnnStart,
		Service:   c.s,
	})

	// and mark as debug? might want to do this based on a setting
	span.Debug = true
	// set uniq span name
	span.Name = req.Service() + "." + req.Method()
	// set source/dest
	span.Source = c.s
	span.Destination = &registry.Service{Name: req.Service()}

	// set context key
	newCtx := c.t.NewContext(ctx, span)
	// set metadata
	newCtx = metadata.NewContext(newCtx, c.t.NewHeader(md, span))

	// mark client request
	span.Annotations = append(span.Annotations, &Annotation{
		Timestamp: time.Now(),
		Type:      AnnClientRequest,
		Service:   c.s,
	})

	// defer the completion of the span
	defer func() {
		// mark client response
		span.Annotations = append(span.Annotations, &Annotation{
			Timestamp: time.Now(),
			Type:      AnnClientResponse,
			Service:   c.s,
		})

		// if we were the creator
		var debug map[string]string
		if err != nil {
			debug = map[string]string{"error": err.Error()}
		}
		// mark end of span
		span.Annotations = append(span.Annotations, &Annotation{
			Timestamp: time.Now(),
			Type:      AnnEnd,
			Service:   c.s,
			Debug:     debug,
		})

		span.Duration = time.Now().Sub(span.Timestamp)

		// flush the span to the collector on return
		c.t.Collect(span)
	}()

	// now just make a regular call down the stack
	err = c.Client.Call(newCtx, req, rsp, opts...)
	return err
}
Esempio n. 8
0
func (c *clientWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	return hystrix.Do(req.Service()+"."+req.Method(), func() error {
		return c.Client.Call(ctx, req, rsp, opts...)
	}, nil)
}
Esempio n. 9
0
func (l *logWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	md, _ := c.GetMetadata(ctx)
	fmt.Printf("[Log Wrapper] ctx: %v service: %s method: %s\n", md, req.Service(), req.Method())
	return l.Client.Call(ctx, req, rsp)
}