Home | History | Annotate | Download | only in engine
      1 // Copyright 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef SYNC_ENGINE_SYNCER_PROTO_UTIL_H_
      6 #define SYNC_ENGINE_SYNCER_PROTO_UTIL_H_
      7 
      8 #include <string>
      9 
     10 #include "base/gtest_prod_util.h"
     11 #include "base/time/time.h"
     12 #include "sync/base/sync_export.h"
     13 #include "sync/internal_api/public/base/model_type.h"
     14 #include "sync/internal_api/public/util/syncer_error.h"
     15 #include "sync/sessions/sync_session.h"
     16 #include "sync/syncable/blob.h"
     17 
     18 namespace sync_pb {
     19 class ClientToServerMessage;
     20 class ClientToServerResponse;
     21 class ClientToServerResponse_Error;
     22 class CommitResponse_EntryResponse;
     23 class EntitySpecifics;
     24 class SyncEntity;
     25 }
     26 
     27 namespace syncer {
     28 
     29 class ServerConnectionManager;
     30 
     31 namespace sessions {
     32 class SyncProtocolError;
     33 class SyncSessionContext;
     34 }
     35 
     36 namespace syncable {
     37 class Directory;
     38 class Entry;
     39 }
     40 
     41 // Returns the types to migrate from the data in |response|.
     42 SYNC_EXPORT_PRIVATE ModelTypeSet GetTypesToMigrate(
     43     const sync_pb::ClientToServerResponse& response);
     44 
     45 // Builds a SyncProtocolError from the data in |error|.
     46 SYNC_EXPORT_PRIVATE SyncProtocolError ConvertErrorPBToLocalType(
     47     const sync_pb::ClientToServerResponse_Error& error);
     48 
     49 class SYNC_EXPORT_PRIVATE SyncerProtoUtil {
     50  public:
     51   // Posts the given message and fills the buffer with the returned value.
     52   // Returns true on success.  Also handles store birthday verification: will
     53   // produce a SyncError if the birthday is incorrect.
     54   // NOTE: This will add all fields that must be sent on every request, which
     55   // includes store birthday, protocol version, client chips, api keys, etc.
     56   static SyncerError PostClientToServerMessage(
     57       sync_pb::ClientToServerMessage* msg,
     58       sync_pb::ClientToServerResponse* response,
     59       sessions::SyncSession* session);
     60 
     61   // Compares a syncable Entry to SyncEntity, returns true iff the data is
     62   // identical.
     63   //
     64   // TODO(sync): The places where this function is used are arguable big causes
     65   // of the fragility, because there's a tendency to freak out the moment the
     66   // local and server values diverge. However, this almost always indicates a
     67   // sync bug somewhere earlier in the sync cycle.
     68   static bool Compare(const syncable::Entry& local_entry,
     69                       const sync_pb::SyncEntity& server_entry);
     70 
     71   static bool ShouldMaintainPosition(const sync_pb::SyncEntity& sync_entity);
     72 
     73   // Utility methods for converting between syncable::Blobs and protobuf byte
     74   // fields.
     75   static void CopyProtoBytesIntoBlob(const std::string& proto_bytes,
     76                                      syncable::Blob* blob);
     77   static bool ProtoBytesEqualsBlob(const std::string& proto_bytes,
     78                                    const syncable::Blob& blob);
     79   static void CopyBlobIntoProtoBytes(const syncable::Blob& blob,
     80                                      std::string* proto_bytes);
     81 
     82   // Extract the name field from a sync entity.
     83   static const std::string& NameFromSyncEntity(
     84       const sync_pb::SyncEntity& entry);
     85 
     86   // Extract the name field from a commit entry response.
     87   static const std::string& NameFromCommitEntryResponse(
     88       const sync_pb::CommitResponse_EntryResponse& entry);
     89 
     90   // Persist the bag of chips if it is present in the response.
     91   static void PersistBagOfChips(
     92       syncable::Directory* dir,
     93       const sync_pb::ClientToServerResponse& response);
     94 
     95   // EntitySpecifics is used as a filter for the GetUpdates message to tell
     96   // the server which datatypes to send back.  This adds a datatype so that
     97   // it's included in the filter.
     98   static void AddToEntitySpecificDatatypesFilter(ModelType datatype,
     99       sync_pb::EntitySpecifics* filter);
    100 
    101   // Get a debug string representation of the client to server response.
    102   static std::string ClientToServerResponseDebugString(
    103       const sync_pb::ClientToServerResponse& response);
    104 
    105   // Get update contents as a string. Intended for logging, and intended
    106   // to have a smaller footprint than the protobuf's built-in pretty printer.
    107   static std::string SyncEntityDebugString(const sync_pb::SyncEntity& entry);
    108 
    109   // Pull the birthday from the dir and put it into the msg.
    110   static void AddRequestBirthday(syncable::Directory* dir,
    111                                  sync_pb::ClientToServerMessage* msg);
    112 
    113   // Pull the bag of chips from the dir and put it into the msg.
    114   static void AddBagOfChips(syncable::Directory* dir,
    115                             sync_pb::ClientToServerMessage* msg);
    116 
    117 
    118   // Set the protocol version field in the outgoing message.
    119   static void SetProtocolVersion(sync_pb::ClientToServerMessage* msg);
    120 
    121  private:
    122   SyncerProtoUtil() {}
    123 
    124   // Helper functions for PostClientToServerMessage.
    125 
    126   // Verifies the store birthday, alerting/resetting as appropriate if there's a
    127   // mismatch. Return false if the syncer should be stuck.
    128   static bool VerifyResponseBirthday(
    129       const sync_pb::ClientToServerResponse& response,
    130       syncable::Directory* dir);
    131 
    132   // Returns true if sync is disabled by admin for a dasher account.
    133   static bool IsSyncDisabledByAdmin(
    134       const sync_pb::ClientToServerResponse& response);
    135 
    136   // Post the message using the scm, and do some processing on the returned
    137   // headers. Decode the server response.
    138   static bool PostAndProcessHeaders(ServerConnectionManager* scm,
    139                                     sessions::SyncSession* session,
    140                                     const sync_pb::ClientToServerMessage& msg,
    141                                     sync_pb::ClientToServerResponse* response);
    142 
    143   static base::TimeDelta GetThrottleDelay(
    144       const sync_pb::ClientToServerResponse& response);
    145 
    146   friend class SyncerProtoUtilTest;
    147   FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, AddRequestBirthday);
    148   FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, PostAndProcessHeaders);
    149   FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, VerifyDisabledByAdmin);
    150   FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, VerifyResponseBirthday);
    151   FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, HandleThrottlingNoDatatypes);
    152   FRIEND_TEST_ALL_PREFIXES(SyncerProtoUtilTest, HandleThrottlingWithDatatypes);
    153 
    154   DISALLOW_COPY_AND_ASSIGN(SyncerProtoUtil);
    155 };
    156 
    157 }  // namespace syncer
    158 
    159 #endif  // SYNC_ENGINE_SYNCER_PROTO_UTIL_H_
    160