summaryrefslogtreecommitdiffstats
path: root/sync/engine/syncer_proto_util.h
blob: e8086b5502f220a7bbc6b84aba77f14121429e3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SYNC_ENGINE_SYNCER_PROTO_UTIL_H_
#define SYNC_ENGINE_SYNCER_PROTO_UTIL_H_
#pragma once

#include <string>

#include "base/gtest_prod_util.h"
#include "base/time.h"
#include "sync/sessions/sync_session.h"
#include "sync/syncable/blob.h"
#include "sync/syncable/model_type.h"
#include "sync/util/syncer_error.h"

namespace syncable {
class Directory;
class Entry;
}  // namespace syncable

namespace sync_pb {
class ClientToServerResponse;
class EntitySpecifics;
}  // namespace sync_pb

namespace browser_sync {

namespace sessions {
class SyncProtocolError;
class SyncSessionContext;
}

class ClientToServerMessage;
class ServerConnectionManager;
class SyncEntity;
class CommitResponse_EntryResponse;

class SyncerProtoUtil {
 public:
  // Posts the given message and fills the buffer with the returned value.
  // Returns true on success.  Also handles store birthday verification: will
  // produce a SyncError if the birthday is incorrect.
  static SyncerError PostClientToServerMessage(
      const ClientToServerMessage& msg,
      sync_pb::ClientToServerResponse* response,
      sessions::SyncSession* session);

  // Compares a syncable Entry to SyncEntity, returns true iff the data is
  // identical.
  //
  // TODO(sync): The places where this function is used are arguable big causes
  // of the fragility, because there's a tendency to freak out the moment the
  // local and server values diverge. However, this almost always indicates a
  // sync bug somewhere earlier in the sync cycle.
  static bool Compare(const syncable::Entry& local_entry,
                      const SyncEntity& server_entry);

  // Utility methods for converting between syncable::Blobs and protobuf byte
  // fields.
  static void CopyProtoBytesIntoBlob(const std::string& proto_bytes,
                                     syncable::Blob* blob);
  static bool ProtoBytesEqualsBlob(const std::string& proto_bytes,
                                   const syncable::Blob& blob);
  static void CopyBlobIntoProtoBytes(const syncable::Blob& blob,
                                     std::string* proto_bytes);

  // Extract the name field from a sync entity.
  static const std::string& NameFromSyncEntity(
      const sync_pb::SyncEntity& entry);

  // Extract the name field from a commit entry response.
  static const std::string& NameFromCommitEntryResponse(
      const CommitResponse_EntryResponse& entry);

  // EntitySpecifics is used as a filter for the GetUpdates message to tell
  // the server which datatypes to send back.  This adds a datatype so that
  // it's included in the filter.
  static void AddToEntitySpecificDatatypesFilter(syncable::ModelType datatype,
      sync_pb::EntitySpecifics* filter);

  // Get a debug string representation of the client to server response.
  static std::string ClientToServerResponseDebugString(
      const sync_pb::ClientToServerResponse& response);

  // Get update contents as a string. Intended for logging, and intended
  // to have a smaller footprint than the protobuf's built-in pretty printer.
  static std::string SyncEntityDebugString(const sync_pb::SyncEntity& entry);

  // Pull the birthday from the dir and put it into the msg.
  static void AddRequestBirthday(syncable::Directory* dir,
                                 ClientToServerMessage* msg);

 private:
  SyncerProtoUtil() {}

  // Helper functions for PostClientToServerMessage.

  // Verifies the store birthday, alerting/resetting as appropriate if there's a
  // mismatch. Return false if the syncer should be stuck.
  static bool VerifyResponseBirthday(syncable::Directory* dir,
      const sync_pb::ClientToServerResponse* response);

  // Builds and sends a SyncEngineEvent to begin migration for types (specified
  // in notification).
  static void HandleMigrationDoneResponse(
      const sync_pb::ClientToServerResponse* response,
      sessions::SyncSession* session);

  // Post the message using the scm, and do some processing on the returned
  // headers. Decode the server response.
  static bool PostAndProcessHeaders(browser_sync::ServerConnectionManager* scm,
                                    sessions::SyncSession* session,
                                    const ClientToServerMessage& msg,
                                    sync_pb::ClientToServerResponse* response);

  static base::TimeDelta GetThrottleDelay(
      const sync_pb::ClientToServerResponse& response);

  static void HandleThrottleError(const SyncProtocolError& error,
                                  const base::TimeTicks& throttled_until,
                                  sessions::SyncSessionContext* context,
                                  sessions::SyncSession::Delegate* delegate);

  friend class SyncerProtoUtilTest;
  FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, AddRequestBirthday);
  FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, PostAndProcessHeaders);
  FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, VerifyResponseBirthday);
  FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, HandleThrottlingNoDatatypes);
  FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, HandleThrottlingWithDatatypes);

  DISALLOW_COPY_AND_ASSIGN(SyncerProtoUtil);
};

}  // namespace browser_sync

#endif  // SYNC_ENGINE_SYNCER_PROTO_UTIL_H_