// ListSubscriptions lists matching subscriptions.
func (c *SubscriberClient) ListSubscriptions(ctx context.Context, req *pubsubpb.ListSubscriptionsRequest) *SubscriptionIterator {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	it := &SubscriptionIterator{}
	it.InternalFetch = func(pageSize int, pageToken string) ([]*pubsubpb.Subscription, string, error) {
		var resp *pubsubpb.ListSubscriptionsResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context) error {
			var err error
			resp, err = c.subscriberClient.ListSubscriptions(ctx, req)
			return err
		}, c.CallOptions.ListSubscriptions...)
		if err != nil {
			return nil, "", err
		}
		return resp.Subscriptions, resp.NextPageToken, nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	return it
}
Exemple #2
0
// ListMonitoredResourceDescriptors lists the monitored resource descriptors used by Stackdriver Logging.
func (c *Client) ListMonitoredResourceDescriptors(ctx context.Context, req *loggingpb.ListMonitoredResourceDescriptorsRequest) *MonitoredResourceDescriptorIterator {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	it := &MonitoredResourceDescriptorIterator{}

	fetch := func(pageSize int, pageToken string) (string, error) {
		var resp *loggingpb.ListMonitoredResourceDescriptorsResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context) error {
			var err error
			resp, err = c.client.ListMonitoredResourceDescriptors(ctx, req)
			return err
		}, c.CallOptions.ListMonitoredResourceDescriptors...)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, resp.ResourceDescriptors...)
		return resp.NextPageToken, nil
	}
	bufLen := func() int { return len(it.items) }
	takeBuf := func() interface{} {
		b := it.items
		it.items = nil
		return b
	}

	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, bufLen, takeBuf)
	return it
}
func (h *handlerManager) validateTTNAuthAppContext(ctx context.Context, appID string) (context.Context, *claims.Claims, error) {
	md, err := api.MetadataFromContext(ctx)
	if err != nil {
		return ctx, nil, err
	}
	// If token is empty, try to get the access key and convert it into a token
	token, err := api.TokenFromMetadata(md)
	if err != nil || token == "" {
		key, err := api.KeyFromMetadata(md)
		if err != nil {
			return ctx, nil, errors.NewErrInvalidArgument("Metadata", "neither token nor key present")
		}
		token, err := h.handler.Component.ExchangeAppKeyForToken(appID, key)
		if err != nil {
			return ctx, nil, err
		}
		md = metadata.Join(md, metadata.Pairs("token", token))
		ctx = metadata.NewContext(ctx, md)
	}
	claims, err := h.handler.Component.ValidateTTNAuthContext(ctx)
	if err != nil {
		return ctx, nil, err
	}
	if h.clientRate.Limit(claims.Subject) {
		return ctx, claims, grpc.Errorf(codes.ResourceExhausted, "Rate limit for client reached")
	}
	if h.applicationRate.Limit(appID) {
		return ctx, claims, grpc.Errorf(codes.ResourceExhausted, "Rate limit for application reached")
	}
	return ctx, claims, nil
}
Exemple #4
0
// SetTrailer sets the trailer metadata which will be sent with the RPC status
// by the server. This can be called multiple times. Server side only.
func (s *Stream) SetTrailer(md metadata.MD) error {
	if md.Len() == 0 {
		return nil
	}
	s.mu.Lock()
	defer s.mu.Unlock()
	s.trailer = metadata.Join(s.trailer, md)
	return nil
}
// DeleteBreakpoint deletes the breakpoint from the debuggee.
func (c *Debugger2Client) DeleteBreakpoint(ctx context.Context, req *clouddebuggerpb.DeleteBreakpointRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.debugger2Client.DeleteBreakpoint(ctx, req)
		return err
	}, c.CallOptions.DeleteBreakpoint...)
	return err
}
Exemple #6
0
// PatchTraces sends new traces to Stackdriver Trace or updates existing traces. If the ID
// of a trace that you send matches that of an existing trace, any fields
// in the existing trace and its spans are overwritten by the provided values,
// and any new fields provided are merged with the existing trace data. If the
// ID does not match, a new trace is created.
func (c *Client) PatchTraces(ctx context.Context, req *cloudtracepb.PatchTracesRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.client.PatchTraces(ctx, req)
		return err
	}, c.CallOptions.PatchTraces...)
	return err
}
// Acknowledge acknowledges the messages associated with the `ack_ids` in the
// `AcknowledgeRequest`. The Pub/Sub system can remove the relevant messages
// from the subscription.
//
// Acknowledging a message whose ack deadline has expired may succeed,
// but such a message may be redelivered later. Acknowledging a message more
// than once will not result in an error.
func (c *SubscriberClient) Acknowledge(ctx context.Context, req *pubsubpb.AcknowledgeRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.subscriberClient.Acknowledge(ctx, req)
		return err
	}, c.CallOptions.Acknowledge...)
	return err
}
// DeleteTopic deletes the topic with the given name. Returns `NOT_FOUND` if the topic
// does not exist. After a topic is deleted, a new topic may be created with
// the same name; this is an entirely new topic with none of the old
// configuration or subscriptions. Existing subscriptions to this topic are
// not deleted, but their `topic` field is set to `_deleted-topic_`.
func (c *PublisherClient) DeleteTopic(ctx context.Context, req *pubsubpb.DeleteTopicRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.publisherClient.DeleteTopic(ctx, req)
		return err
	}, c.CallOptions.DeleteTopic...)
	return err
}
// ModifyPushConfig modifies the `PushConfig` for a specified subscription.
//
// This may be used to change a push subscription to a pull one (signified by
// an empty `PushConfig`) or vice versa, or change the endpoint URL and other
// attributes of a push subscription. Messages will accumulate for delivery
// continuously through the call regardless of changes to the `PushConfig`.
func (c *SubscriberClient) ModifyPushConfig(ctx context.Context, req *pubsubpb.ModifyPushConfigRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.subscriberClient.ModifyPushConfig(ctx, req)
		return err
	}, c.CallOptions.ModifyPushConfig...)
	return err
}
Exemple #10
0
// CreateTimeSeries creates or adds data to one or more time series.
// The response is empty if all time series in the request were written.
// If any time series could not be written, a corresponding failure message is
// included in the error response.
func (c *MetricClient) CreateTimeSeries(ctx context.Context, req *monitoringpb.CreateTimeSeriesRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.metricClient.CreateTimeSeries(ctx, req)
		return err
	}, c.CallOptions.CreateTimeSeries...)
	return err
}
Exemple #11
0
// DeleteMetricDescriptor deletes a metric descriptor. Only user-created
// [custom metrics](/monitoring/custom-metrics) can be deleted.
func (c *MetricClient) DeleteMetricDescriptor(ctx context.Context, req *monitoringpb.DeleteMetricDescriptorRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.metricClient.DeleteMetricDescriptor(ctx, req)
		return err
	}, c.CallOptions.DeleteMetricDescriptor...)
	return err
}
Exemple #12
0
// DeleteLogMetric deletes a logs-based metric.
func (c *MetricsClient) DeleteLogMetric(ctx context.Context, req *loggingpb.DeleteLogMetricRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.metricsClient.DeleteLogMetric(ctx, req)
		return err
	}, c.CallOptions.DeleteLogMetric...)
	return err
}
Exemple #13
0
// DeleteServiceAccountKey deletes a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey].
func (c *IamClient) DeleteServiceAccountKey(ctx context.Context, req *adminpb.DeleteServiceAccountKeyRequest) error {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		_, err = c.iamClient.DeleteServiceAccountKey(ctx, req)
		return err
	}, c.CallOptions.DeleteServiceAccountKey...)
	return err
}
Exemple #14
0
// SetHeader sets the header metadata. This can be called multiple times.
// Server side only.
func (s *Stream) SetHeader(md metadata.MD) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.headerOk || s.state == streamDone {
		return ErrIllegalHeaderWrite
	}
	if md.Len() == 0 {
		return nil
	}
	s.header = metadata.Join(s.header, md)
	return nil
}
Exemple #15
0
// setIamPolicy sets the IAM access control policy for a
// [ServiceAccount][google.iam.admin.v1.ServiceAccount].
func (c *IamClient) setIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *iampb.Policy
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.iamClient.SetIamPolicy(ctx, req)
		return err
	}, c.CallOptions.SetIamPolicy...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
// StreamingPull (EXPERIMENTAL) StreamingPull is an experimental feature. This RPC will
// respond with UNIMPLEMENTED errors unless you have been invited to test
// this feature. Contact [email protected] with any questions.
//
// Establishes a stream with the server, which sends messages down to the
// client. The client streams acknowledgements and ack deadline modifications
// back to the server. The server will close the stream and return the status
// on any error. The server may close the stream with status `OK` to reassign
// server-side resources, in which case, the client should re-establish the
// stream. `UNAVAILABLE` may also be returned in the case of a transient error
// (e.g., a server restart). These should also be retried by the client. Flow
// control can be achieved by configuring the underlying RPC channel.
func (c *SubscriberClient) StreamingPull(ctx context.Context) (pubsubpb.Subscriber_StreamingPullClient, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp pubsubpb.Subscriber_StreamingPullClient
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.subscriberClient.StreamingPull(ctx)
		return err
	}, c.CallOptions.StreamingPull...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #17
0
// SyncRecognize perform synchronous speech-recognition: receive results after all audio
// has been sent and processed.
func (c *Client) SyncRecognize(ctx context.Context, req *speechpb.SyncRecognizeRequest) (*speechpb.SyncRecognizeResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *speechpb.SyncRecognizeResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.client.SyncRecognize(ctx, req)
		return err
	}, c.CallOptions.SyncRecognize...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #18
0
// StreamingRecognize perform bidirectional streaming speech-recognition: receive results while
// sending audio. This method is only available via the gRPC API (not REST).
func (c *Client) StreamingRecognize(ctx context.Context) (speechpb.Speech_StreamingRecognizeClient, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp speechpb.Speech_StreamingRecognizeClient
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.client.StreamingRecognize(ctx)
		return err
	}, c.CallOptions.StreamingRecognize...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
// Pull pulls messages from the server. Returns an empty list if there are no
// messages available in the backlog. The server may return `UNAVAILABLE` if
// there are too many concurrent pull requests pending for the given
// subscription.
func (c *SubscriberClient) Pull(ctx context.Context, req *pubsubpb.PullRequest) (*pubsubpb.PullResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *pubsubpb.PullResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.subscriberClient.Pull(ctx, req)
		return err
	}, c.CallOptions.Pull...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
// CreateSubscription creates a subscription to a given topic.
// If the subscription already exists, returns `ALREADY_EXISTS`.
// If the corresponding topic doesn't exist, returns `NOT_FOUND`.
//
// If the name is not provided in the request, the server will assign a random
// name for this subscription on the same project as the topic, conforming
// to the
// [resource name format](https://cloud.google.com/pubsub/docs/overview#names).
// The generated name is populated in the returned Subscription object.
// Note that for REST API requests, you must specify a name in the request.
func (c *SubscriberClient) CreateSubscription(ctx context.Context, req *pubsubpb.Subscription) (*pubsubpb.Subscription, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *pubsubpb.Subscription
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.subscriberClient.CreateSubscription(ctx, req)
		return err
	}, c.CallOptions.CreateSubscription...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #21
0
// WriteLogEntries writes log entries to Stackdriver Logging.  All log entries are
// written by this method.
func (c *Client) WriteLogEntries(ctx context.Context, req *loggingpb.WriteLogEntriesRequest) (*loggingpb.WriteLogEntriesResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *loggingpb.WriteLogEntriesResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.client.WriteLogEntries(ctx, req)
		return err
	}, c.CallOptions.WriteLogEntries...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #22
0
// TestIamPermissions tests the specified permissions against the IAM access control policy
// for a [ServiceAccount][google.iam.admin.v1.ServiceAccount].
func (c *IamClient) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *iampb.TestIamPermissionsResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.iamClient.TestIamPermissions(ctx, req)
		return err
	}, c.CallOptions.TestIamPermissions...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #23
0
// QueryGrantableRoles queries roles that can be granted on a particular resource.
// A role is grantable if it can be used as the role in a binding for a policy
// for that resource.
func (c *IamClient) QueryGrantableRoles(ctx context.Context, req *adminpb.QueryGrantableRolesRequest) (*adminpb.QueryGrantableRolesResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *adminpb.QueryGrantableRolesResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.iamClient.QueryGrantableRoles(ctx, req)
		return err
	}, c.CallOptions.QueryGrantableRoles...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #24
0
// CreateMetricDescriptor creates a new metric descriptor.
// User-created metric descriptors define
// [custom metrics](/monitoring/custom-metrics).
func (c *MetricClient) CreateMetricDescriptor(ctx context.Context, req *monitoringpb.CreateMetricDescriptorRequest) (*metricpb.MetricDescriptor, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *metricpb.MetricDescriptor
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.metricClient.CreateMetricDescriptor(ctx, req)
		return err
	}, c.CallOptions.CreateMetricDescriptor...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
// ListDebuggees lists all the debuggees that the user can set breakpoints to.
func (c *Debugger2Client) ListDebuggees(ctx context.Context, req *clouddebuggerpb.ListDebuggeesRequest) (*clouddebuggerpb.ListDebuggeesResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *clouddebuggerpb.ListDebuggeesResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.debugger2Client.ListDebuggees(ctx, req)
		return err
	}, c.CallOptions.ListDebuggees...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #26
0
// CreateServiceAccountKey creates a [ServiceAccountKey][google.iam.admin.v1.ServiceAccountKey]
// and returns it.
func (c *IamClient) CreateServiceAccountKey(ctx context.Context, req *adminpb.CreateServiceAccountKeyRequest) (*adminpb.ServiceAccountKey, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *adminpb.ServiceAccountKey
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.iamClient.CreateServiceAccountKey(ctx, req)
		return err
	}, c.CallOptions.CreateServiceAccountKey...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
Exemple #27
0
// UpdateLogMetric creates or updates a logs-based metric.
func (c *MetricsClient) UpdateLogMetric(ctx context.Context, req *loggingpb.UpdateLogMetricRequest) (*loggingpb.LogMetric, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *loggingpb.LogMetric
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.metricsClient.UpdateLogMetric(ctx, req)
		return err
	}, c.CallOptions.UpdateLogMetric...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
// ReportErrorEvent report an individual error event.
//
// This endpoint accepts <strong>either</strong> an OAuth token,
// <strong>or</strong> an
// <a href="https://support.google.com/cloud/answer/6158862">API key</a>
// for authentication. To use an API key, append it to the URL as the value of
// a `key` parameter. For example:
// <pre>POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456</pre>
func (c *ReportErrorsClient) ReportErrorEvent(ctx context.Context, req *clouderrorreportingpb.ReportErrorEventRequest) (*clouderrorreportingpb.ReportErrorEventResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *clouderrorreportingpb.ReportErrorEventResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.reportErrorsClient.ReportErrorEvent(ctx, req)
		return err
	}, c.CallOptions.ReportErrorEvent...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
// UpdateActiveBreakpoint updates the breakpoint state or mutable fields.
// The entire Breakpoint message must be sent back to the controller
// service.
//
// Updates to active breakpoint fields are only allowed if the new value
// does not change the breakpoint specification. Updates to the `location`,
// `condition` and `expression` fields should not alter the breakpoint
// semantics. These may only make changes such as canonicalizing a value
// or snapping the location to the correct line of code.
func (c *Controller2Client) UpdateActiveBreakpoint(ctx context.Context, req *clouddebuggerpb.UpdateActiveBreakpointRequest) (*clouddebuggerpb.UpdateActiveBreakpointResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *clouddebuggerpb.UpdateActiveBreakpointResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.controller2Client.UpdateActiveBreakpoint(ctx, req)
		return err
	}, c.CallOptions.UpdateActiveBreakpoint...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
// BatchAnnotateImages run image detection and annotation for a batch of images.
func (c *ImageAnnotatorClient) BatchAnnotateImages(ctx context.Context, req *visionpb.BatchAnnotateImagesRequest) (*visionpb.BatchAnnotateImagesResponse, error) {
	md, _ := metadata.FromContext(ctx)
	ctx = metadata.NewContext(ctx, metadata.Join(md, c.metadata))
	var resp *visionpb.BatchAnnotateImagesResponse
	err := gax.Invoke(ctx, func(ctx context.Context) error {
		var err error
		resp, err = c.imageAnnotatorClient.BatchAnnotateImages(ctx, req)
		return err
	}, c.CallOptions.BatchAnnotateImages...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}