Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: components/sync/engine_impl/loopback_server/loopback_server.cc

Issue 2969643002: Reland - Replace FakeServer's implementation with LoopbackServer invocations. (Closed)
Patch Set: Rebased on master. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/sync/engine_impl/loopback_server/loopback_server.h" 5 #include "components/sync/engine_impl/loopback_server/loopback_server.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 const ModelTypeToVersionMap request_version_map_; 127 const ModelTypeToVersionMap request_version_map_;
128 128
129 // The largest versions seen between client and server, ultimately used to 129 // The largest versions seen between client and server, ultimately used to
130 // send progress markers back to the client. 130 // send progress markers back to the client.
131 ModelTypeToVersionMap response_version_map_; 131 ModelTypeToVersionMap response_version_map_;
132 }; 132 };
133 133
134 } // namespace 134 } // namespace
135 135
136 LoopbackServer::LoopbackServer(const base::FilePath& persistent_file) 136 LoopbackServer::LoopbackServer(const base::FilePath& persistent_file)
137 : version_(0), store_birthday_(0), persistent_file_(persistent_file) { 137 : version_(0),
138 store_birthday_(0),
139 persistent_file_(persistent_file),
140 observer_for_tests_(NULL) {
138 Init(); 141 Init();
139 } 142 }
140 143
141 LoopbackServer::~LoopbackServer() {} 144 LoopbackServer::~LoopbackServer() {}
142 145
143 void LoopbackServer::Init() { 146 void LoopbackServer::Init() {
144 if (LoadStateFromFile(persistent_file_)) 147 if (LoadStateFromFile(persistent_file_))
145 return; 148 return;
146 149
147 keystore_keys_.push_back(GenerateNewKeystoreKey()); 150 keystore_keys_.push_back(GenerateNewKeystoreKey());
148 151
149 const bool create_result = CreateDefaultPermanentItems(); 152 const bool create_result = CreateDefaultPermanentItems();
150 DCHECK(create_result) << "Permanent items were not created successfully."; 153 DCHECK(create_result) << "Permanent items were not created successfully.";
151 } 154 }
152 155
153 std::string LoopbackServer::GenerateNewKeystoreKey() const { 156 std::string LoopbackServer::GenerateNewKeystoreKey() const {
154 // TODO(pastarmovj): Check if true random bytes is ok or alpha-nums is needed? 157 // TODO(pastarmovj): Check if true random bytes is ok or alpha-nums is needed?
155 return base::RandBytesAsString(kKeystoreKeyLenght); 158 return base::RandBytesAsString(kKeystoreKeyLenght);
156 } 159 }
157 160
158 bool LoopbackServer::CreatePermanentBookmarkFolder( 161 bool LoopbackServer::CreatePermanentBookmarkFolder(
159 const std::string& server_tag, 162 const std::string& server_tag,
160 const std::string& name) { 163 const std::string& name) {
161 DCHECK(thread_checker_.CalledOnValidThread()); 164 DCHECK(thread_checker_.CalledOnValidThread());
162 std::unique_ptr<LoopbackServerEntity> entity = 165 std::unique_ptr<LoopbackServerEntity> entity =
163 PersistentPermanentEntity::Create(syncer::BOOKMARKS, server_tag, name, 166 PersistentPermanentEntity::CreateNew(
164 ModelTypeToRootTag(syncer::BOOKMARKS)); 167 syncer::BOOKMARKS, server_tag, name,
168 ModelTypeToRootTag(syncer::BOOKMARKS));
165 if (!entity) 169 if (!entity)
166 return false; 170 return false;
167 171
168 SaveEntity(std::move(entity)); 172 SaveEntity(std::move(entity));
169 return true; 173 return true;
170 } 174 }
171 175
172 bool LoopbackServer::CreateDefaultPermanentItems() { 176 bool LoopbackServer::CreateDefaultPermanentItems() {
173 // Permanent folders are always required for Bookmarks (hierarchical 177 // Permanent folders are always required for Bookmarks (hierarchical
174 // structure) and Nigori (data stored in permanent root folder). 178 // structure) and Nigori (data stored in permanent root folder).
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 string LoopbackServer::CommitEntity( 320 string LoopbackServer::CommitEntity(
317 const sync_pb::SyncEntity& client_entity, 321 const sync_pb::SyncEntity& client_entity,
318 sync_pb::CommitResponse_EntryResponse* entry_response, 322 sync_pb::CommitResponse_EntryResponse* entry_response,
319 const string& client_guid, 323 const string& client_guid,
320 const string& parent_id) { 324 const string& parent_id) {
321 if (client_entity.version() == 0 && client_entity.deleted()) { 325 if (client_entity.version() == 0 && client_entity.deleted()) {
322 return string(); 326 return string();
323 } 327 }
324 328
325 std::unique_ptr<LoopbackServerEntity> entity; 329 std::unique_ptr<LoopbackServerEntity> entity;
330 syncer::ModelType type = GetModelType(client_entity);
326 if (client_entity.deleted()) { 331 if (client_entity.deleted()) {
327 entity = PersistentTombstoneEntity::Create(client_entity); 332 entity = PersistentTombstoneEntity::CreateFromEntity(client_entity);
328 DeleteChildren(client_entity.id_string()); 333 DeleteChildren(client_entity.id_string());
329 } else if (GetModelType(client_entity) == syncer::NIGORI) { 334 } else if (type == syncer::NIGORI) {
330 // NIGORI is the only permanent item type that should be updated by the 335 // NIGORI is the only permanent item type that should be updated by the
331 // client. 336 // client.
332 EntityMap::const_iterator iter = entities_.find(client_entity.id_string()); 337 EntityMap::const_iterator iter = entities_.find(client_entity.id_string());
333 CHECK(iter != entities_.end()); 338 CHECK(iter != entities_.end());
334 entity = PersistentPermanentEntity::CreateUpdatedNigoriEntity( 339 entity = PersistentPermanentEntity::CreateUpdatedNigoriEntity(
335 client_entity, *iter->second); 340 client_entity, *iter->second);
336 } else if (client_entity.has_client_defined_unique_tag()) { 341 } else if (type == syncer::BOOKMARKS) {
337 entity = PersistentUniqueClientEntity::Create(client_entity);
338 } else {
339 // TODO(pvalenzuela): Validate entity's parent ID. 342 // TODO(pvalenzuela): Validate entity's parent ID.
340 EntityMap::const_iterator iter = entities_.find(client_entity.id_string()); 343 EntityMap::const_iterator iter = entities_.find(client_entity.id_string());
341 if (iter != entities_.end()) { 344 if (iter != entities_.end()) {
342 entity = PersistentBookmarkEntity::CreateUpdatedVersion( 345 entity = PersistentBookmarkEntity::CreateUpdatedVersion(
343 client_entity, *iter->second, parent_id); 346 client_entity, *iter->second, parent_id);
344 } else { 347 } else {
345 entity = PersistentBookmarkEntity::CreateNew(client_entity, parent_id, 348 entity = PersistentBookmarkEntity::CreateNew(client_entity, parent_id,
346 client_guid); 349 client_guid);
347 } 350 }
348 } 351 } else {
349 352 entity = PersistentUniqueClientEntity::CreateFromEntity(client_entity);
350 if (!entity) {
351 LOG(ERROR) << "No server entity was created for client entity with type: "
352 << GetModelType(client_entity)
353 << " and ID: " << client_entity.id_string() << ".";
354 return string();
355 } 353 }
356 354
357 const std::string id = entity->GetId(); 355 const std::string id = entity->GetId();
358 SaveEntity(std::move(entity)); 356 SaveEntity(std::move(entity));
359 BuildEntryResponseForSuccessfulCommit(id, entry_response); 357 BuildEntryResponseForSuccessfulCommit(id, entry_response);
360 return id; 358 return id;
361 } 359 }
362 360
361 void LoopbackServer::OverrideResponseType(
362 ResponseTypeProvider response_type_override) {
363 response_type_override_ = std::move(response_type_override);
364 }
365
363 void LoopbackServer::BuildEntryResponseForSuccessfulCommit( 366 void LoopbackServer::BuildEntryResponseForSuccessfulCommit(
364 const std::string& entity_id, 367 const std::string& entity_id,
365 sync_pb::CommitResponse_EntryResponse* entry_response) { 368 sync_pb::CommitResponse_EntryResponse* entry_response) {
366 EntityMap::const_iterator iter = entities_.find(entity_id); 369 EntityMap::const_iterator iter = entities_.find(entity_id);
367 CHECK(iter != entities_.end()); 370 CHECK(iter != entities_.end());
368 const LoopbackServerEntity& entity = *iter->second; 371 const LoopbackServerEntity& entity = *iter->second;
369 entry_response->set_response_type(sync_pb::CommitResponse::SUCCESS); 372 entry_response->set_response_type(response_type_override_
373 ? response_type_override_.Run(entity)
374 : sync_pb::CommitResponse::SUCCESS);
370 entry_response->set_id_string(entity.GetId()); 375 entry_response->set_id_string(entity.GetId());
371 376
372 if (entity.IsDeleted()) { 377 if (entity.IsDeleted()) {
373 entry_response->set_version(entity.GetVersion() + 1); 378 entry_response->set_version(entity.GetVersion() + 1);
374 } else { 379 } else {
375 entry_response->set_version(entity.GetVersion()); 380 entry_response->set_version(entity.GetVersion());
376 entry_response->set_name(entity.GetName()); 381 entry_response->set_name(entity.GetName());
377 } 382 }
378 } 383 }
379 384
(...skipping 19 matching lines...) Expand all
399 // Find all the children of id. 404 // Find all the children of id.
400 for (auto& entity : entities_) { 405 for (auto& entity : entities_) {
401 if (IsChild(entity.first, id)) { 406 if (IsChild(entity.first, id)) {
402 sync_pb::SyncEntity proto; 407 sync_pb::SyncEntity proto;
403 entity.second->SerializeAsProto(&proto); 408 entity.second->SerializeAsProto(&proto);
404 tombstones.emplace_back(proto); 409 tombstones.emplace_back(proto);
405 } 410 }
406 } 411 }
407 412
408 for (auto& tombstone : tombstones) { 413 for (auto& tombstone : tombstones) {
409 SaveEntity(PersistentTombstoneEntity::Create(tombstone)); 414 SaveEntity(PersistentTombstoneEntity::CreateFromEntity(tombstone));
410 } 415 }
411 } 416 }
412 417
413 bool LoopbackServer::HandleCommitRequest( 418 bool LoopbackServer::HandleCommitRequest(
414 const sync_pb::CommitMessage& commit, 419 const sync_pb::CommitMessage& commit,
415 const std::string& invalidator_client_id, 420 const std::string& invalidator_client_id,
416 sync_pb::CommitResponse* response) { 421 sync_pb::CommitResponse* response) {
417 std::map<string, string> client_to_server_ids; 422 std::map<string, string> client_to_server_ids;
418 string guid = commit.cache_guid(); 423 string guid = commit.cache_guid();
419 ModelTypeSet committed_model_types; 424 ModelTypeSet committed_model_types;
(...skipping 19 matching lines...) Expand all
439 // Record the ID if it was renamed. 444 // Record the ID if it was renamed.
440 if (entity_id != client_entity.id_string()) { 445 if (entity_id != client_entity.id_string()) {
441 client_to_server_ids[client_entity.id_string()] = entity_id; 446 client_to_server_ids[client_entity.id_string()] = entity_id;
442 } 447 }
443 448
444 EntityMap::const_iterator iter = entities_.find(entity_id); 449 EntityMap::const_iterator iter = entities_.find(entity_id);
445 CHECK(iter != entities_.end()); 450 CHECK(iter != entities_.end());
446 committed_model_types.Put(iter->second->GetModelType()); 451 committed_model_types.Put(iter->second->GetModelType());
447 } 452 }
448 453
454 if (observer_for_tests_)
455 observer_for_tests_->OnCommit(invalidator_client_id, committed_model_types);
456
449 return true; 457 return true;
450 } 458 }
451 459
452 void LoopbackServer::ClearServerData() { 460 void LoopbackServer::ClearServerData() {
453 DCHECK(thread_checker_.CalledOnValidThread()); 461 DCHECK(thread_checker_.CalledOnValidThread());
454 entities_.clear(); 462 entities_.clear();
455 keystore_keys_.clear(); 463 keystore_keys_.clear();
456 ++store_birthday_; 464 ++store_birthday_;
465 base::DeleteFile(persistent_file_, false);
457 Init(); 466 Init();
458 } 467 }
459 468
460 std::string LoopbackServer::GetStoreBirthday() const { 469 std::string LoopbackServer::GetStoreBirthday() const {
461 DCHECK(thread_checker_.CalledOnValidThread()); 470 DCHECK(thread_checker_.CalledOnValidThread());
462 return base::Int64ToString(store_birthday_); 471 return base::Int64ToString(store_birthday_);
463 } 472 }
464 473
474 std::vector<sync_pb::SyncEntity> LoopbackServer::GetSyncEntitiesByModelType(
475 ModelType model_type) {
476 DCHECK(thread_checker_.CalledOnValidThread());
477 std::vector<sync_pb::SyncEntity> sync_entities;
478 for (EntityMap::const_iterator it = entities_.begin(); it != entities_.end();
479 ++it) {
480 const LoopbackServerEntity& entity = *it->second;
481 if (!(entity.IsDeleted() || entity.IsPermanent()) &&
482 entity.GetModelType() == model_type) {
483 sync_pb::SyncEntity sync_entity;
484 entity.SerializeAsProto(&sync_entity);
485 sync_entities.push_back(sync_entity);
486 }
487 }
488 return sync_entities;
489 }
490
491 std::unique_ptr<base::DictionaryValue>
492 LoopbackServer::GetEntitiesAsDictionaryValue() {
493 DCHECK(thread_checker_.CalledOnValidThread());
494 std::unique_ptr<base::DictionaryValue> dictionary(
495 new base::DictionaryValue());
496
497 // Initialize an empty ListValue for all ModelTypes.
498 ModelTypeSet all_types = ModelTypeSet::All();
499 for (ModelTypeSet::Iterator it = all_types.First(); it.Good(); it.Inc()) {
500 dictionary->Set(ModelTypeToString(it.Get()),
501 base::MakeUnique<base::ListValue>());
502 }
503
504 for (EntityMap::const_iterator it = entities_.begin(); it != entities_.end();
505 ++it) {
506 const LoopbackServerEntity& entity = *it->second;
507 if (entity.IsDeleted() || entity.IsPermanent()) {
508 // Tombstones are ignored as they don't represent current data. Folders
509 // are also ignored as current verification infrastructure does not
510 // consider them.
511 continue;
512 }
513 base::ListValue* list_value;
514 if (!dictionary->GetList(ModelTypeToString(entity.GetModelType()),
515 &list_value)) {
516 return std::unique_ptr<base::DictionaryValue>();
517 }
518 // TODO(pvalenzuela): Store more data for each entity so additional
519 // verification can be performed. One example of additional verification
520 // is checking the correctness of the bookmark hierarchy.
521 list_value->AppendString(entity.GetName());
522 }
523
524 return dictionary;
525 }
526
527 bool LoopbackServer::ModifyEntitySpecifics(
528 const std::string& id,
529 const sync_pb::EntitySpecifics& updated_specifics) {
530 EntityMap::const_iterator iter = entities_.find(id);
531 if (iter == entities_.end() ||
532 iter->second->GetModelType() !=
533 GetModelTypeFromSpecifics(updated_specifics)) {
534 return false;
535 }
536
537 LoopbackServerEntity* entity = iter->second.get();
538 entity->SetSpecifics(updated_specifics);
539 UpdateEntityVersion(entity);
540 return true;
541 }
542
543 bool LoopbackServer::ModifyBookmarkEntity(
544 const std::string& id,
545 const std::string& parent_id,
546 const sync_pb::EntitySpecifics& updated_specifics) {
547 EntityMap::const_iterator iter = entities_.find(id);
548 if (iter == entities_.end() ||
549 iter->second->GetModelType() != syncer::BOOKMARKS ||
550 GetModelTypeFromSpecifics(updated_specifics) != syncer::BOOKMARKS) {
551 return false;
552 }
553
554 PersistentBookmarkEntity* entity =
555 static_cast<PersistentBookmarkEntity*>(iter->second.get());
556
557 entity->SetParentId(parent_id);
558 entity->SetSpecifics(updated_specifics);
559 if (updated_specifics.has_bookmark()) {
560 entity->SetName(updated_specifics.bookmark().title());
561 }
562 UpdateEntityVersion(entity);
563 return true;
564 }
565
465 void LoopbackServer::SerializeState(sync_pb::LoopbackServerProto* proto) const { 566 void LoopbackServer::SerializeState(sync_pb::LoopbackServerProto* proto) const {
466 DCHECK(thread_checker_.CalledOnValidThread()); 567 DCHECK(thread_checker_.CalledOnValidThread());
467 568
468 proto->set_version(kCurrentLoopbackServerProtoVersion); 569 proto->set_version(kCurrentLoopbackServerProtoVersion);
469 proto->set_store_birthday(store_birthday_); 570 proto->set_store_birthday(store_birthday_);
470 proto->set_last_version_assigned(version_); 571 proto->set_last_version_assigned(version_);
471 for (const auto& key : keystore_keys_) 572 for (const auto& key : keystore_keys_)
472 proto->add_keystore_keys(key); 573 proto->add_keystore_keys(key);
473 for (const auto& entity : entities_) { 574 for (const auto& entity : entities_) {
474 auto* new_entity = proto->mutable_entities()->Add(); 575 auto* new_entity = proto->mutable_entities()->Add();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 // write. 629 // write.
529 LOG(ERROR) << "Loopback sync can not read the persistent state file."; 630 LOG(ERROR) << "Loopback sync can not read the persistent state file.";
530 return false; 631 return false;
531 } 632 }
532 } 633 }
533 LOG(WARNING) << "Loopback sync persistent state file does not exist."; 634 LOG(WARNING) << "Loopback sync persistent state file does not exist.";
534 return false; 635 return false;
535 } 636 }
536 637
537 } // namespace syncer 638 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698