1// Copyright 2017 Google Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15syntax = "proto3"; 16 17package google.watcher.v1; 18 19import "google/api/annotations.proto"; 20import "google/protobuf/any.proto"; 21import "google/protobuf/empty.proto"; 22 23option go_package = "google.golang.org/genproto/googleapis/watcher/v1;watcher"; 24option java_multiple_files = true; 25option java_outer_classname = "WatchProto"; 26option java_package = "com.google.watcher.v1"; 27 28// ## API Overview 29// 30// [Watcher][] lets a client watch for updates to a named entity, such as a 31// directory or database table. For each watched entity, the client receives a 32// reliable stream of watch events, without re-ordering. 33// 34// Watching is done by sending an RPC to a service that implements the API. The 35// argument to the RPC contains the name of the entity. The result stream 36// consists of a sequence of Change messages that the service continues to 37// send until the call fails or is cancelled. 38// 39// ## Data model 40// 41// This API assumes that each *entity* has a name and a 42// set of *elements*, where each element has a name and a value. The 43// entity's name must be a unique identifier within the service, such as 44// a resource name. What constitutes an entity or element is 45// implementation-specific: for example, a file system implementation 46// might define an entity as either a directory or a file, and elements would be 47// child files or directories of that entity. 48// 49// The Watch API allows a client to watch an entity E's immediate 50// elements or the whole tree rooted at E. Elements are organized into 51// a hierarchy ("" at the top; the rest follows the natural hierarchy of the 52// namespace of elements that is being watched). For example, when 53// recursively watching a filesystem namespace, X is an ancestor of 54// X/Y and X/Y/Z). 55// 56// ## Watch request 57// 58// When a client makes a request to watch an entity, it can indicate 59// whether it wants to receive the initial state of the entity, just 60// new changes to the entity, or resume watching from a particular 61// point in a previous watch stream, specified with a `resume_marker` value. 62// It can also indicate whether it wants to watch only one entity or all 63// entities in the subtree rooted at a particular entity's name. 64// 65// On receiving a watch request for an entity, the server sends one or more 66// messages to the client. The first message informs the client that the server 67// has registered the client's request: the instant of time when the 68// client receives the event is referred to as the client's "watch 69// point" for that entity. 70// 71// ## Atomic delivery 72// 73// The response stream consists of a sequence of Change messages. Each 74// message contains an `continued` bit. A sub-sequence of Change messages with 75// `continued=true` followed by a Change message with `continued=false` forms an 76// *atomic group*. Systems that support multi-element atomic updates may 77// guarantee that all changes resulting from a single atomic 78// update are delivered in the same atomic group. It is up to the 79// documentation of a particular system that implements the Watch API to 80// document whether or not it supports such grouping. We expect that most 81// callers will ignore the notion of atomic delivery and the `continued` bit, 82// i.e., they will just process each Change message as it is received. 83// 84// ## Batching 85// 86// Multiple Change messages may be grouped into a single ChangeBatch message 87// to reduce message transfer overhead. A single ChangeBatch may contain many 88// atomic groups, or a single atomic group may be split across many 89// ChangeBatch messages. 90// 91// ## Initial State 92// 93// The first atomic group delivered by a watch call is special. It is 94// delivered as soon as possible and contains the initial state of the 95// entity being watched. The client should consider itself caught up 96// after processing this first atomic group. 97// 98// The messages in the first atomic group will either refer to the 99// entity itself (`Change.element` == "") or to elements inside the 100// entity (`Change.element` != ""). Here are the cases to consider: 101// 102// 1. `resume_marker` is "" or not specified: For every element P 103// (including the entity itself) that exists, there will be at least 104// one message delivered with element == P and the last such message 105// will contain the current state of P. For every element Q 106// (including the entity itself) that does not exist, either no 107// message will be delivered, or the last message for Q will have 108// state == DOES_NOT_EXIST. At least one message for element="" will 109// be delivered. 110// 111// 2. `resume_marker` == "now": there will be exactly one message with 112// element = "" and state INITIAL_STATE_SKIPPED. The client cannot 113// assume whether or not the entity exists after receiving this 114// message. 115// 116// 3. `resume_marker` has a value R from a preceding watch call on this 117// entity: The same messages as described in (1) will be delivered to 118// the client, except that any information implied by messages received 119// on the preceding call up to and including R may not be 120// delivered. The expectation is that the client will start with state 121// it had built up from the preceding watch call, apply the changes 122// received from this call, and build an up-to-date view of the entity 123// without having to fetch a potentially large amount of information 124// that has not changed. Note that some information that had already 125// been delivered by the preceding call might be delivered again. 126// 127// ## Ordering and Reliability 128// 129// The Change messages that apply to a particular element of the entity are 130// delivered eventually in order without loss for the duration of the RPC. Note 131// however that if multiple Changes apply to the same element, the 132// implementation is free to suppress them and deliver just the last one. The 133// underlying system must provide the guarantee that any relevant update 134// received for an entity E after a client's watch point for E MUST be delivered 135// to that client. 136// 137// These tight guarantees allow for the following simplifications in the client: 138// 139// 1. The client does not need to have a separate polling loop to make up for 140// missed updates. 141// 142// 2. The client does not need to manage timestamps/versions manually; the 143// last update delivered corresponds to the eventual state of the entity. 144// 145// Example: a calendar entry may have elements named { "starttime", "endtime", 146// "attendees" } with corresponding values or it may have a single element name 147// "entry" with a serialized proto for the calendar entry. 148// 149// ## Ordering constraints for parents/descendants 150// 151// The Watch API provides guarantees regarding the order in which 152// messages for a parent and its descendants are delivered: 153// 154// 1. The creation of an ancestor (i.e., the first EXISTS message for 155// the ancestor) is reported before the creation of any of its 156// descendants. 157// 158// 2. The deletion of an ancestor (via a DOES_NOT_EXIST message) 159// implies the deletion of all its descendants. The service will 160// not deliver any messages for the descendants until the parent 161// has been recreated. 162 163// The service that a client uses to connect to the watcher system. 164// The errors returned by the service are in the canonical error space, 165// see [google.rpc.Code][]. 166service Watcher { 167 // Start a streaming RPC to get watch information from the server. 168 rpc Watch(Request) returns (stream ChangeBatch) { 169 option (google.api.http) = { 170 get: "/v1/watch" 171 }; 172 } 173} 174 175// The message used by the client to register interest in an entity. 176message Request { 177 // The `target` value **must** be a valid URL path pointing to an entity 178 // to watch. Note that the service name **must** be 179 // removed from the target field (e.g., the target field must say 180 // "/foo/bar", not "myservice.googleapis.com/foo/bar"). A client is 181 // also allowed to pass system-specific parameters in the URL that 182 // are only obeyed by some implementations. Some parameters will be 183 // implementation-specific. However, some have predefined meaning 184 // and are listed here: 185 // 186 // * recursive = true|false [default=false] 187 // If set to true, indicates that the client wants to watch all elements 188 // of entities in the subtree rooted at the entity's name in `target`. For 189 // descendants that are not the immediate children of the target, the 190 // `Change.element` will contain slashes. 191 // 192 // Note that some namespaces and entities will not support recursive 193 // watching. When watching such an entity, a client must not set recursive 194 // to true. Otherwise, it will receive an `UNIMPLEMENTED` error. 195 // 196 // Normal URL encoding must be used inside `target`. For example, if a query 197 // parameter name or value, or the non-query parameter portion of `target` 198 // contains a special character, it must be %-encoded. We recommend that 199 // clients and servers use their runtime's URL library to produce and consume 200 // target values. 201 string target = 1; 202 203 // The `resume_marker` specifies how much of the existing underlying state is 204 // delivered to the client when the watch request is received by the 205 // system. The client can set this marker in one of the following ways to get 206 // different semantics: 207 // 208 // * Parameter is not specified or has the value "". 209 // Semantics: Fetch initial state. 210 // The client wants the entity's initial state to be delivered. See the 211 // description in "Initial State". 212 // 213 // * Parameter is set to the string "now" (UTF-8 encoding). 214 // Semantics: Fetch new changes only. 215 // The client just wants to get the changes received by the system after 216 // the watch point. The system may deliver changes from before the watch 217 // point as well. 218 // 219 // * Parameter is set to a value received in an earlier 220 // `Change.resume_marker` field while watching the same entity. 221 // Semantics: Resume from a specific point. 222 // The client wants to receive the changes from a specific point; this 223 // value must correspond to a value received in the `Change.resume_marker` 224 // field. The system may deliver changes from before the `resume_marker` 225 // as well. If the system cannot resume the stream from this point (e.g., 226 // if it is too far behind in the stream), it can raise the 227 // `FAILED_PRECONDITION` error. 228 // 229 // An implementation MUST support an unspecified parameter and the 230 // empty string "" marker (initial state fetching) and the "now" marker. 231 // It need not support resuming from a specific point. 232 bytes resume_marker = 2; 233} 234 235// A batch of Change messages. 236message ChangeBatch { 237 // A list of Change messages. 238 repeated Change changes = 1; 239} 240 241// A Change indicates the most recent state of an element. 242message Change { 243 // A reported value can be in one of the following states: 244 enum State { 245 // The element exists and its full value is included in data. 246 EXISTS = 0; 247 248 // The element does not exist. 249 DOES_NOT_EXIST = 1; 250 251 // Element may or may not exist. Used only for initial state delivery when 252 // the client is not interested in fetching the initial state. See the 253 // "Initial State" section above. 254 INITIAL_STATE_SKIPPED = 2; 255 256 // The element may exist, but some error has occurred. More information is 257 // available in the data field - the value is a serialized Status 258 // proto (from [google.rpc.Status][]) 259 ERROR = 3; 260 } 261 262 // Name of the element, interpreted relative to the entity's actual 263 // name. "" refers to the entity itself. The element name is a valid 264 // UTF-8 string. 265 string element = 1; 266 267 // The state of the `element`. 268 State state = 2; 269 270 // The actual change data. This field is present only when `state() == EXISTS` 271 // or `state() == ERROR`. Please see 272 // [google.protobuf.Any][google.protobuf.Any] about how to use the Any type. 273 google.protobuf.Any data = 6; 274 275 // If present, provides a compact representation of all the messages that have 276 // been received by the caller for the given entity, e.g., it could be a 277 // sequence number or a multi-part timestamp/version vector. This marker can 278 // be provided in the Request message, allowing the caller to resume the 279 // stream watching at a specific point without fetching the initial state. 280 bytes resume_marker = 4; 281 282 // If true, this Change is followed by more Changes that are in the same group 283 // as this Change. 284 bool continued = 5; 285} 286