/*
Copyright 2021 The Dapr 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.
*/

syntax = "proto3";

package dapr.proto.internals.v1;

import "dapr/proto/common/v1/common.proto";
import "dapr/proto/internals/v1/apiversion.proto";
import "dapr/proto/internals/v1/status.proto";

option go_package = "github.com/dapr/dapr/pkg/proto/internals/v1;internals";

// ServiceInvocation service is used to exchange the data between 
// caller dapr runtime and callee dapr runtime.
//
// The request message includes caller's HTTP/gRPC request
// and deliver callee's response including status code.
// The response status of rpc methods represents of internal gRPC
// connection status, not callee's response status.
//
// Thus, ServiceInvocation gRPC response returns OK in most cases
// regardless of callee's response.
service ServiceInvocation {
  // Invokes a method of the specific actor.
  rpc CallActor (InternalInvokeRequest) returns (InternalInvokeResponse) {}

  // Invokes a method of the specific service.
  rpc CallLocal (InternalInvokeRequest) returns (InternalInvokeResponse) {}

  // Invokes a method of the specific service using a stream of data.
  // Although this uses a bi-directional stream, it behaves as a "simple RPC" in which the caller sends the full request (chunked in multiple messages in the stream), then reads the full response (chunked in the stream). 
  // Each message in the stream contains a `InternalInvokeRequestStream` (for caller) or `InternalInvokeResponseStream` (for callee):
  // - The first message in the stream MUST contain a `request` (caller) or `response` (callee) message with all required properties present.
  // - The first message in the stream MAY contain a `payload`, which is not required and may be empty.
  // - Subsequent messages (any message except the first one in the stream) MUST contain a `payload` and MUST NOT contain any other property (like `request` or `response`).
  // - Each message with a `payload` MUST contain a sequence number in `seq`, which is a counter that starts from 0 and MUST be incremented by 1 in each chunk. The `seq` counter MUST NOT be included if the message does not have a `payload`.
  // - When the sender has completed sending the data, it MUST call `CloseSend` on the stream.
  // The caller and callee must send at least one message in the stream. If only 1 message is sent in each direction, that message must contain both a `request`/`response` (the `payload` may be empty).
  rpc CallLocalStream (stream InternalInvokeRequestStream) returns (stream InternalInvokeResponseStream) {}
}

// Actor represents actor using actor_type and actor_id
message Actor {
  // Required. The type of actor.
  string actor_type = 1;

  // Required. The ID of actor type (actor_type)
  string actor_id = 2;
}

// InternalInvokeRequest is the message to transfer caller's data to callee
// for service invocation. This includes callee's app id and caller's request data.
message InternalInvokeRequest {
  // Required. The version of Dapr runtime API.
  APIVersion ver = 1;

  // Required. metadata holds caller's HTTP headers or gRPC metadata.
  map<string, ListStringValue> metadata = 2;

  // Required. message including caller's invocation request.
  common.v1.InvokeRequest message = 3;

  // Actor type and id. This field is used only for
  // actor service invocation.
  Actor actor = 4;
}

// InternalInvokeResponse is the message to transfer callee's response to caller
// for service invocation.
message InternalInvokeResponse {
  // Required. HTTP/gRPC status.
  Status status = 1;

  // Required. The app callback response headers.
  map<string, ListStringValue> headers = 2;

  // App callback response trailers.
  // This will be used only for gRPC app callback
  map<string, ListStringValue> trailers = 3;

  // Callee's invocation response message.
  common.v1.InvokeResponse message = 4;
}

// InternalInvokeRequestStream is a variant of InternalInvokeRequest used in streaming RPCs.
message InternalInvokeRequestStream {
  // Request details.
  // This does not contain any data in message.data.
  InternalInvokeRequest request = 1;

  // Chunk of data.
  common.v1.StreamPayload payload = 2;
}

// InternalInvokeResponseStream is a variant of InternalInvokeResponse used in streaming RPCs.
message InternalInvokeResponseStream {
  // Response details.
  // This does not contain any data in message.data.
  InternalInvokeResponse response = 1;

  // Chunk of data.
  common.v1.StreamPayload payload = 2;
}

// ListStringValue represents string value array
message ListStringValue {
  // The array of string.
  repeated string values = 1;
}
