// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
//
// Test protocol for kudu RPC.
package kudu.rpc_test;

import "kudu/rpc/rpc_header.proto";
import "kudu/rpc/rtest_diff_package.proto";

message AddRequestPB {
  required uint32 x = 1;
  required uint32 y = 2;
}

// Used by tests to simulate an old client which is missing
// a newly added required field.
message AddRequestPartialPB {
  required uint32 x = 1;
}

message AddResponsePB {
  required uint32 result = 1;
}

message SleepRequestPB {
  required uint32 sleep_micros = 1;

  // Used in rpc_stub-test: if this is true, it will respond from a different
  // thread than the one that receives the request.
  optional bool deferred = 2 [ default = false ];

  // If set, returns a CalculatorError response.
  optional bool return_app_error = 3 [ default = false ];

  // Used in rpc-test: if this is set to true and no client timeout is set,
  // the service will respond to the client with an error.
  optional bool client_timeout_defined = 4 [ default = false ];
}

message SleepResponsePB {
}

message SendTwoStringsRequestPB {
  required uint32 random_seed = 1;
  required uint64 size1 = 2;
  required uint64 size2 = 3;
}

message SendTwoStringsResponsePB {
  required uint32 sidecar1 = 1;
  required uint32 sidecar2 = 2;
}

message EchoRequestPB {
  required string data = 1;
}
message EchoResponsePB {
  required string data = 1;
}

message WhoAmIRequestPB {
}
message WhoAmIResponsePB {
  required kudu.rpc.UserInformationPB credentials = 1;
  required string address = 2;
}

message CalculatorError {
  extend kudu.rpc.ErrorStatusPB {
    optional CalculatorError app_error_ext = 101;
  }

  required string extra_error_data = 1;
}

message PanicRequestPB {}
message PanicResponsePB {}

enum FeatureFlags {
  UNKNOWN=0;
  FOO=1;
}

service CalculatorService {
  rpc Add(AddRequestPB) returns(AddResponsePB);
  rpc Sleep(SleepRequestPB) returns(SleepResponsePB);
  rpc Echo(EchoRequestPB) returns(EchoResponsePB);
  rpc WhoAmI(WhoAmIRequestPB) returns (WhoAmIResponsePB);
  rpc TestArgumentsInDiffPackage(kudu.rpc_test_diff_package.ReqDiffPackagePB)
    returns(kudu.rpc_test_diff_package.RespDiffPackagePB);
  rpc Panic(PanicRequestPB) returns (PanicResponsePB);
}
