syntax = "proto3";

package twitch.video.usher;
option go_package = "code.justin.tv/video/usherapi/rpc/usher";

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/struct.proto";

message NodeListRequest {
    // rep_type filters based on the replication type of the node.
    // example: "hls"
    google.protobuf.StringValue rep_type = 1;


    // ClusterFields is a sub-message containing fields
    // that correspond to database columns in usher's clusters table.
    // For example, the query parameter 'clusters.local=true' means that
    // the cluster which a node belongs to must have local=true.
    message ClusterFields {
        // local filters for nodes whose cluster is local
        google.protobuf.BoolValue local = 1;
    }
    ClusterFields clusters = 2;
}

message NodeShowRequest {
    // name is the node name in usherdb, which includes the pop name
    string name = 1;
}

message NodeEnableRequest {
    // id is the node id in usherdb
    int64 id = 1;
}

message NodeDisableRequest {
    // id is the node id in usherdb
    int64 id = 1;
}

message NodeListEdgeRequest {
}

message ListOf_Node {
  repeated Node nodes = 1;
}

// Node is a representation of a single host in the replication tree which can
// provide replication or edge functionality. It is not currently (7/10/18)
// used to represent ingest nodes in the video system.
message Node {
  // id is the node id in usherdb
  int64 id = 1 [json_name = "id"];

  // name is the node name in usherdb, which includes the pop name
  //
  // Example:
  //   "video-edge-8c7908.phx01"
  string name = 2 [json_name = "name"];

  // addr is the fqdn or ip address at which this node can be reached
  //
  // Example:
  //   "video-edge-8c7908.phx01.justin.tv"
  string addr = 3 [json_name = "ip"];

  // version needs documentation
  // TODO: document me
  string version = 4 [json_name = "version"];

  // rep_type will be "hls_replication" or "hls", with "old" and "ingest" being
  // deprecated. "hls_replication" indicates this node is a protected replication
  // node, "hls" indicates this node is a video edge node.
  string rep_type = 5 [json_name = "rep_type"];

  // killed indicates this node is about to be removed from usher
  bool killed = 6 [json_name = "killed"];

  // origin_only indicates this field should not be used for replication or
  // viewer traffic. it's unclear whether this field is correct so it should not
  // be used for new work
  bool origin_only = 7 [json_name = "origin_only"];

  // cluster_id is the id in the clusters table that this nodes cluster
  // corresponds to
  int64 cluster_id = 8 [json_name = "cluster_id"];

  // cluster_name is the name property of the clusters row for this node's
  // cluster. it may not always be set.
  string cluster_name = 9 [json_name = "cluster_name"];

  // create_time is the time at which this node entry was created
  google.protobuf.Timestamp create_time = 20 [json_name = "up_time_rfc3339"];

  // create_time_ansic_or_seconds should not be used and create_time should be
  // used instead
  google.protobuf.Value create_time_ansic_or_seconds = 21 [json_name = "up_time"];

  // update_time is the time this node was last updated
  google.protobuf.Timestamp update_time = 22 [json_name = "updated_on_rfc3339"];

  // update_time_ansic_or_seconds should not be used, update_time should be used
  // instead
  google.protobuf.Value update_time_ansic_or_seconds = 23 [json_name = "updated_on"];

  // disable_time is the time at which this node was disabled
  google.protobuf.Timestamp disable_time = 24 [json_name = "disabled_on_rfc3339"];

  // disable_time_seconds should not be used, disable_time should be used instead
  // as this field will be parsed into disable_time by the client
  int64 disable_time_seconds = 25 [json_name = "disabled_on"];

  // enabled indicates this node receive traffic
  bool enabled = 30 [json_name = "enabled"];

  // play_enabled indicates this node should receive viewer playback traffic
  bool play_enabled = 32 [json_name = "play_enabled"];

  // replication_enabled indicates this node should receive replication traffic
  bool replication_enabled = 33 [json_name = "replication_enabled"];

  // https_enabled indicates this node should receive https viewer traffic
  bool https_enabled = 34 [json_name = "https_enabled"];

  // auto_restart_enabled is no longer used but has some odd dependencies. do
  // not use for new work.
  bool auto_restart_enabled = 35 [json_name = "auto_restart_enabled", deprecated = true];

  // rps is the number of requests completed per second by this node
  double rps = 40 [json_name = "rps"];

  // load_nic represents the current load state of this node as calculated by
  // (mbps_out_nic/max_mbps_out_nic)
  double load_nic = 60 [json_name = "load_nic"];

  // mbps_in_nic is the measured network input bandwidth in megabits/s
  double mbps_in_nic = 61 [json_name = "mbps_in_nic"];

  // mbps_out_nic is the measured network output bandwidth in megabits/s
  double mbps_out_nic = 62 [json_name = "mbps_out_nic"];

  // max_mbps_out_nic sets a bandwidth limit (in megabits/s) beyond which no
  // more users should be assigned to this node
  double max_mbps_out_nic = 63 [json_name = "max_mbps_out_nic"];

  // max_mbps_in_nic sets a bandwidth limit (in megabits/s) beyond which no more
  // users should be assigned to this node
  double max_mbps_in_nic = 64 [json_name = "max_mbps_in_nic"];

  // https_rps is the requests-per-second measure of https traffic on this node
  double https_rps = 65 [json_name = "https_rps"];

  // https_mbps_out indicates how much outbound https traffic this node has in
  // megabits/s
  double https_mbps_out = 66 [json_name = "https_mbps_out"];

  // experiment_metrics_raw should not be used, experiment_metrics should be used
  // instead
  string experiment_metrics_raw = 67 [json_name = "experiment_metrics"];

  // experiment_metrics holds experiment metric data collected by video/statmon.
  // this field was initially used to experiment with the collection of
  // connection count data from nodes.
  map<string, double> experiment_metrics = 68 [json_name = "experiment_metrics_obj"];

  // cpu_usage_percent is this node's current cpu usage percentage [0.0,100.0]
  double cpu_usage_percent = 69 [json_name = "cpu_usage"];

  // cpu_max_percent specifies the maximum cpu percentage [0.0,100.0] above
  // which no more traffic will be assigned to this node
  double cpu_max_percent = 70 [json_name = "cpu_max"];

  // current_connections_count is the number of active tcp connections on this node
  int64 current_connection_count = 71 [json_name = "cur_conn"];

  // max_connections_count is the max number of active tcp connections on this node
  int64 max_connection_count = 72 [json_name = "max_conn"];
}

//
// Example node from usher
//
// {
//   "load": 0,
//   "rps": 120.43,
//   "cpu_usage": 3.11,
//   "rep_type": "hls",
//   "play_enabled": true,
//   "ip": "video-edge-8c7908.phx01.justin.tv",
//   "https_rps": 60,
//   "max_mbps_in_nic": 18000,
//   "type": "node",
//   "origin_only": false,
//   "load_nic": 0.0259238888888889,
//   "id": 613489152,
//   "mbps_out_nic": 466.63,
//   "publish_enabled": false,
//   "max_conn": 4000,
//   "cluster_name": "phx01",
//   "version": "hls.1",
//   "max_mbps_out_nic": 18000,
//   "replication_enabled": true,
//   "max_mbps_in": 1,
//   "https_handshake": 0,
//   "up_time": "Tue Jul 26 10:56:00 2016",
//   "cpu_max": 100,
//   "flows": "/node/flows/video-edge-8c7908.phx01.json",
//   "latency_strikes": 0,
//   "cur_conn": 99,
//   "mbps_in_nic": 229.55,
//   "experiment_metrics": "{}",
//   "https_enabled": true,
//   "max_mbps": 1,
//   "iphone_free": false,
//   "name": "video-edge-8c7908.phx01",
//   "killed": false,
//   "enabled": false,
//   "https_mbps_out": 416.85,
//   "auto_restart_enabled": false,
//   "streams": "/node/streams/video-edge-8c7908.phx01.json",
//   "restarting": false,
//   "internal_latency": 0,
//   "updated_on": "Mon Jul  2 10:49:02 2018"
// }
