blob: 17c20a74a231d7ba14280c08b2e2c39d4ae3ab07 [file] [log] [blame]
// 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.
//
// The wave client-server protocol.
// See http://www.waveprotocol.org/protocol/design-proposals/clientserver-protocol
//
// Author: anorth@google.com (Alex North)
syntax = "proto2";
import "org/waveprotocol/box/server/rpc/rpc.proto";
import "org/waveprotocol/wave/federation/federation.protodevel";
package concurrencycontrol;
option java_package = "org.waveprotocol.wave.concurrencycontrol";
option java_outer_classname = "ClientServer";
/*
*** Fetch service. ***
* Provides snapshots describing a client's view of a wave.
* As a bandwidth optimization, the client may specify that it already has
* snapshots of some wavelets at some version (such as from a previous fetch).
* If the server's current version matches the version the client provides
* then the snapshot is omitted from the response.
*/
service FetchService {
rpc Fetch(FetchWaveViewRequest) returns (FetchWaveViewResponse);
}
message FetchWaveViewRequest {
// Wave to open, URI path format.
required string waveId = 1;
// Wavelet versions the client already knows.
// At most one version per wavelet.
repeated WaveletVersion knownWavelet = 2;
}
message FetchWaveViewResponse {
required ResponseStatus status = 1;
message Wavelet {
// The wavelet in view, URI path format.
required string waveletId = 1;
// Snapshot of the wavelet; omitted if the client already knew it.
optional WaveletSnapshot snapshot = 2;
}
repeated Wavelet wavelet = 2;
}
/* A wavelet with a known hashed version of that wavelet. */
message WaveletVersion {
// Known wavelet, URI path format.
required string waveletId = 1;
// Known hashed version of the wavelet.
required federation.ProtocolHashedVersion version = 2;
}
/* A wavelet and associated metadata. */
message WaveletSnapshot {
// Wavelet's id, URI path format.
required string waveletId = 1;
// Participants of this wavelet.
repeated string participant = 2;
// Snapshots of all the documents in the wavelet.
repeated DocumentSnapshot document = 3;
//// Metadata ////
// Current version and modification timestamp of the wavelet.
required federation.ProtocolHashedVersion version = 4;
required int64 lastModifiedTime = 5;
// Participant and time of creation for the wavelet.
required string creator = 6;
required int64 creationTime = 7;
}
/* A document and associated metadata. */
message DocumentSnapshot {
// Id of the document.
required string documentId = 1;
// Operation that transforms an empty document the document state.
required federation.ProtocolDocumentOperation documentOperation = 2;
//// Metadata ////
// Participant who submitted the first operation to the document.
required string author = 3;
// All participants who have submitted operations to the document.
repeated string contributor = 4;
// Wavelet version and timestamp when the document was last modified.
required int64 lastModifiedVersion = 5;
required int64 lastModifiedTime = 6;
}
/*
*** Wavelet channel service. ***
* Provides a uni-directional stream of deltas for a single wavelet,
* beginning at the delta applying at a client-specified version.
* The stream continues until either the client requests the channel
* be closed or a terminating message is received. Deltas submitted
* with this channel's id are excluded from the stream. There is no
* ordering guarantee between this service and responses from the
* delta submission service.
*/
service WaveletChannelService {
rpc Open(OpenWaveletChannelRequest) returns (OpenWaveletChannelStream) {
option (rpc.is_streaming_rpc) = true;
};
rpc Close(CloseWaveletChannelRequest) returns (EmptyResponse);
}
message OpenWaveletChannelRequest {
// Wave id, URI path format.
required string waveId = 1;
// Wavelet id, URI path format.
required string waveletId = 2;
// Application version of first delta to return.
required federation.ProtocolHashedVersion beginVersion = 3;
}
/** Repeated message for a wavelet channel. */
message OpenWaveletChannelStream {
// Identifies the channel, provided only in the first message.
optional string channelId = 1;
// Second and subsequent messages contain either or both a delta
// and commitVersion.
optional WaveletUpdate delta = 2;
optional federation.ProtocolHashedVersion commitVersion = 3;
// Last message contains only a terminator.
optional WaveletChannelTerminator terminator = 4;
}
message CloseWaveletChannelRequest {
// Channel to close.
required string channelId = 1;
}
/** A delta applied to a wavelet. */
message WaveletUpdate {
// Transformed delta.
required federation.ProtocolWaveletDelta delta = 1;
// Wavelet hashed version after the delta.
required federation.ProtocolHashedVersion resultingVersion = 2;
// Timestamp of delta application.
required int64 applicationTimpstamp = 3;
}
/** Terminates a wavelet stream. */
message WaveletChannelTerminator {
required ResponseStatus status = 1;
}
/*
*** Delta submission service. ***
* Receives deltas submitted against wavelets.
* Deltas are submitted in association with a wavelet channel (see
* WaveletChannelService).
*/
service DeltaSubmissionService {
rpc Submit(SubmitDeltaRequest) returns (SubmitDeltaResponse);
}
message SubmitDeltaRequest {
// Wave to submit to, URI path format.
required string waveId = 1;
// Wavelet to submit to, URI path format.
required string waveletId = 2;
// Delta to submit.
required federation.ProtocolWaveletDelta delta = 3;
// Wavelet channel associated with submission.
required string channelId = 4;
}
message SubmitDeltaResponse {
required ResponseStatus status = 1;
// Number of ops applied from the delta.
required int32 operationsApplied = 2;
// Wavelet hashed version after the delta.
optional federation.ProtocolHashedVersion hashedVersionAfterApplication = 3;
// Timestamp of delta application.
optional int64 timestampAfterApplication = 4;
}
/*
*** Transport authentication service. ***
* Authenticates the underlying transport.
* This service is required only to work around a bug in some browsers'
* websocket implementations that fail to set cookies containing authentication
* tokens.
* If the client's authentication is invalid the server should close the
* transport.
* See: http://code.google.com/p/wave-protocol/issues/detail?id=119
*/
service TransportAuthenticationService {
rpc Authenticate (TransportAuthenticationRequest) returns (EmptyResponse);
}
message TransportAuthenticationRequest {
// Authentication token.
required string token = 1;
}
/*** An empty message for services which have no application-level result. ***/
message EmptyResponse {
}
/*** Response status for all services ***/
message ResponseStatus {
enum ResponseCode {
// All good.
OK = 0;
// Request was ill-formed.
BAD_REQUEST = 1;
// An unspecified internal error occurred.
INTERNAL_ERROR = 2;
// The request was not authorized.
NOT_AUTHORIZED = 3;
// Hashed version didn't match a point in history.
VERSION_ERROR = 4;
// A delta contained an invalid operation (before or after transformation).
INVALID_OPERATION = 5;
// An operation didn't preserve a document schema.
SCHEMA_VIOLATION = 6;
// A delta is too big or the resulting document count or size is too large.
SIZE_LIMIT_EXCEEDED = 7;
// An operation was rejected by a server policy.
POLICY_VIOLATION = 8;
// An object is unavailable because it has been quarantined.
QUARANTINED = 9;
// A request was made against a version older than the server was willing
// to satisfy. Transform and retry.
TOO_OLD = 10;
}
required ResponseCode status = 1;
// Reason must be provided if status != OK.
optional string failureReason = 2;
}