12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/commit.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "sync/engine/commit_contribution.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sync/engine/commit_processor.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/engine/commit_util.h" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "sync/engine/syncer.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/syncer_proto_util.h" 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "sync/internal_api/public/events/commit_request_event.h" 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "sync/internal_api/public/events/commit_response_event.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/sessions/sync_session.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Commit::Commit( 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::map<ModelType, CommitContribution*>& contributions, 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::ClientToServerMessage& message, 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionsActivity::Records extensions_activity_buffer) 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : contributions_(contributions), 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) deleter_(&contributions_), 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) message_(message), 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extensions_activity_buffer_(extensions_activity_buffer), 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cleaned_up_(false) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Commit::~Commit() { 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(cleaned_up_); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Commit* Commit::Init( 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ModelTypeSet requested_types, 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ModelTypeSet enabled_types, 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t max_entries, 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& account_name, 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& cache_guid, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CommitProcessor* commit_processor, 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionsActivity* extensions_activity) { 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Gather per-type contributions. 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ContributionMap contributions; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) commit_processor->GatherCommitContributions( 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requested_types, 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) max_entries, 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &contributions); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Give up if no one had anything to commit. 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (contributions.empty()) 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::ClientToServerMessage message; 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) message.set_message_contents(sync_pb::ClientToServerMessage::COMMIT); 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) message.set_share(account_name); 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::CommitMessage* commit_message = message.mutable_commit(); 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) commit_message->set_cache_guid(cache_guid); 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Set extensions activity if bookmark commits are present. 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionsActivity::Records extensions_activity_buffer; 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ContributionMap::iterator it = contributions.find(syncer::BOOKMARKS); 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (it != contributions.end() && it->second->GetNumEntries() != 0) { 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) commit_util::AddExtensionsActivityToMessage( 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extensions_activity, 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &extensions_activity_buffer, 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) commit_message); 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Set the client config params. 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) commit_util::AddClientConfigParamsToMessage( 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enabled_types, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) commit_message); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Finally, serialize all our contributions. 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (std::map<ModelType, CommitContribution*>::iterator it = 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contributions.begin(); it != contributions.end(); ++it) { 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second->AddToCommitMessage(&message); 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If we made it this far, then we've successfully prepared a commit message. 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new Commit(contributions, message, extensions_activity_buffer); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SyncerError Commit::PostAndProcessResponse( 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sessions::SyncSession* session, 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sessions::StatusController* status, 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ExtensionsActivity* extensions_activity) { 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ModelTypeSet request_types; 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (ContributionMap::const_iterator it = contributions_.begin(); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it != contributions_.end(); ++it) { 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) request_types.Put(it->first); 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session->mutable_status_controller()->set_commit_request_types(request_types); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (session->context()->debug_info_getter()) { 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sync_pb::DebugInfo* debug_info = message_.mutable_debug_info(); 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) session->context()->debug_info_getter()->GetDebugInfo(debug_info); 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Sending commit message."; 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CommitRequestEvent request_event( 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Time::Now(), 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch message_.commit().entries_size(), 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch request_types, 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch message_); 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch session->SendProtocolEvent(request_event); 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TRACE_EVENT_BEGIN0("sync", "PostCommit"); 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncerError post_result = SyncerProtoUtil::PostClientToServerMessage( 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &message_, &response_, session); 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TRACE_EVENT_END0("sync", "PostCommit"); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(rlarocque): Use result that includes errors captured later? 116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch CommitResponseEvent response_event( 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Time::Now(), 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch post_result, 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch response_); 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch session->SendProtocolEvent(response_event); 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (post_result != SYNCER_OK) { 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << "Post commit failed"; 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return post_result; 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!response_.has_commit()) { 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << "Commit response has no commit body!"; 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return SERVER_RESPONSE_VALIDATION_FAILED; 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t message_entries = message_.commit().entries_size(); 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t response_entries = response_.commit().entryresponse_size(); 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (message_entries != response_entries) { 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(ERROR) 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "Commit response has wrong number of entries! " 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "Expected: " << message_entries << ", " 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "Got: " << response_entries; 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return SERVER_RESPONSE_VALIDATION_FAILED; 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (session->context()->debug_info_getter()) { 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Clear debug info now that we have successfully sent it to the server. 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Clearing client debug info."; 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) session->context()->debug_info_getter()->ClearDebugInfo(); 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Let the contributors process the responses to each of their requests. 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncerError processing_result = SYNCER_OK; 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (std::map<ModelType, CommitContribution*>::iterator it = 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contributions_.begin(); it != contributions_.end(); ++it) { 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TRACE_EVENT1("sync", "ProcessCommitResponse", 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "type", ModelTypeToString(it->first)); 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncerError type_result = 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second->ProcessCommitResponse(response_, status); 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (processing_result == SYNCER_OK && type_result != SYNCER_OK) { 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) processing_result = type_result; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Handle bookmarks' special extensions activity stats. 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (session->status_controller(). 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) model_neutral_state().num_successful_bookmark_commits == 0) { 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) extensions_activity->PutRecords(extensions_activity_buffer_); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return processing_result; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Commit::CleanUp() { 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (ContributionMap::iterator it = contributions_.begin(); 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it != contributions_.end(); ++it) { 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second->CleanUp(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cleaned_up_ = true; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace syncer 179