
// Copyright 2015-2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto3";

option java_multiple_files = true;

import "empty.proto";
import "messages.proto";

package grpc.testing;

// See https://github.com/grpc/grpc/blob/master/src/proto/grpc/testing/test.proto
// A simple service to test the various types of RPCs and experiment with
// performance with various types of payload.
service TestService {
  // One empty request followed by one empty response.
  rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);

  // One request followed by one response.
  rpc UnaryCall(SimpleRequest) returns (SimpleResponse);

  // One request followed by one response. Response has cache control
  // headers set such that a caching HTTP proxy (such as GFE) can
  // satisfy subsequent requests.
  rpc CacheableUnaryCall(SimpleRequest) returns (SimpleResponse);

  // One request followed by a sequence of responses (streamed download).
  // The server returns the payload with client desired type and sizes.
  rpc StreamingOutputCall(StreamingOutputCallRequest)
      returns (stream StreamingOutputCallResponse);

  // A sequence of requests followed by one response (streamed upload).
  // The server returns the aggregated size of client payload as the result.
  rpc StreamingInputCall(stream StreamingInputCallRequest)
      returns (StreamingInputCallResponse);

  // A sequence of requests with each request served by the server immediately.
  // As one request could lead to multiple responses, this interface
  // demonstrates the idea of full duplexing.
  rpc FullDuplexCall(stream StreamingOutputCallRequest)
      returns (stream StreamingOutputCallResponse);

  // A sequence of requests followed by a sequence of responses.
  // The server buffers all the client requests and then serves them in order. A
  // stream of responses are returned to the client when the server starts with
  // first request.
  rpc HalfDuplexCall(stream StreamingOutputCallRequest)
      returns (stream StreamingOutputCallResponse);

  // The test server will not implement this method. It will be used
  // to test the behavior when clients call unimplemented methods.
  rpc UnimplementedCall(grpc.testing.Empty) returns (grpc.testing.Empty);
}

// A simple service NOT implemented at servers so clients can test for
// that case.
service UnimplementedService {
  // A call that no server should implement
  rpc UnimplementedCall(grpc.testing.Empty) returns (grpc.testing.Empty);
}

// A service used to control reconnect server.
service ReconnectService {
  rpc Start(grpc.testing.ReconnectParams) returns (grpc.testing.Empty);
  rpc Stop(grpc.testing.Empty) returns (grpc.testing.ReconnectInfo);
}

// A service used to obtain stats for verifying LB behavior.
service LoadBalancerStatsService {
  // Gets the backend distribution for RPCs sent by a test client.
  rpc GetClientStats(LoadBalancerStatsRequest)
      returns (LoadBalancerStatsResponse) {}

  // Gets the accumulated stats for RPCs sent by a test client.
  rpc GetClientAccumulatedStats(LoadBalancerAccumulatedStatsRequest)
      returns (LoadBalancerAccumulatedStatsResponse) {}
}

// A service to remotely control health status of an xDS test server.
service XdsUpdateHealthService {
  rpc SetServing(grpc.testing.Empty) returns (grpc.testing.Empty);
  rpc SetNotServing(grpc.testing.Empty) returns (grpc.testing.Empty);
}

// A service to dynamically update the configuration of an xDS test client.
service XdsUpdateClientConfigureService {
  // Update the tes client's configuration.
  rpc Configure(ClientConfigureRequest) returns (ClientConfigureResponse);
}