Skip to content

Commit

Permalink
Fix usage of baas admin API (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
leemaguire authored Nov 21, 2023
1 parent b6937cb commit 19e3720
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 74 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
X.Y.Z Release notes (YYYY-MM-DD)
=============================================================

### Fixed
* None

### Enhancements
* None

### Breaking Changes
* None

### Compatibility
* Fileformat: Generates files with format v23. Reads and automatically upgrade from fileformat v5.

### Internals
* Upgraded to Core v13.23.4

----------------------------------------------

0.4.0 Release notes (2022-10-17)
=============================================================

Expand Down
2 changes: 1 addition & 1 deletion realm-core
Submodule realm-core updated 132 files
133 changes: 69 additions & 64 deletions tests/admin_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,71 +492,38 @@ std::string Admin::Session::create_app(bson::BsonArray queryable_fields, std::st
}));
std::string mongodb_service_id(mongodb_service_response["_id"]);

bson::BsonDocument service_config = {
{"flexible_sync", bson::BsonDocument {
{"type", "flexible"},
{"state", "enabled"},
{"database_name", "test_data"},
{"queryable_fields_names", queryable_fields},
{"asymmetric_tables", bson::BsonArray({"AllTypesAsymmetricObject"})},
{"permissions", bson::BsonDocument{
{"rules", bson::BsonDocument()},
{"defaultRoles", bson::BsonArray{bson::BsonDocument{
{"name", "all"},
{"applyWhen", bson::BsonDocument()},
{"read", true},
{"write", true}
}}}
}}
}}
};

// The cluster linking must be separated from enabling sync because Atlas
// takes a few seconds to provision a user for BaaS, meaning enabling sync
// will fail if we attempt to do it with the same request. It's nondeterministic
// how long it'll take, so we must retry for a while.
constexpr int max_attempts = 120;
for (int attempt = 0; attempt <= max_attempts; attempt++) {
try {
app["services"][mongodb_service_id]["config"].patch(std::move(service_config));
break;
} catch(std::exception&) {
if (attempt == max_attempts) {
REALM_TERMINATE("Could not link Atlas cluster");
} else {
util::format(std::cerr, "Could not update MongoDB service after %1 seconds. Will keep retrying.\n", (attempt + 1) * 5);
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
}

auto config = app["sync"]["config"];
config.put({{"is_recovery_mode_disabled", true}});
app["custom_user_data"].patch(bson::BsonDocument {
{"mongo_service_id", mongodb_service_id},
{"enabled", true},
{"database_name", "test_data"},
{"collection_name", "UserData"},
{"user_id_field", "user_id"},
});

bson::BsonDocument user_data_rule = {
{"database", "test_data"},
{"collection", "UserData"},
{"roles", bson::BsonArray {
bson::BsonDocument {{"name", "default"},
{"apply_when", {}},
{"insert", true},
{"delete", true},
{"additional_fields", {}},
{"document_filters", bson::BsonDocument({{"read", true}, {"write", true}})},
{"read", true},
{"write", true},
{"insert", true},
{"delete", true}
{"database", "test_data"},
{"collection", "UserData"},
{"roles", bson::BsonArray {
bson::BsonDocument {{"name", "default"},
{"apply_when", {}},
{"insert", true},
{"delete", true},
{"additional_fields", {}},
{"document_filters", bson::BsonDocument({{"read", true}, {"write", true}})},
{"read", true},
{"write", true},
{"insert", true},
{"delete", true}
}
}
}
}
}
};

bson::BsonDocument asymmetric_object_rule = {
{"database", app_name},
{"collection", "AllTypesAsymmetricObject"},
{"roles", bson::BsonArray {
bson::BsonDocument{{"name", "default"},
bson::BsonDocument{{"name", "default"},
{"apply_when", {}},
{"insert", true},
{"delete", true},
Expand All @@ -566,20 +533,58 @@ std::string Admin::Session::create_app(bson::BsonArray queryable_fields, std::st
{"write", true},
{"insert", true},
{"delete", true}}
}
}
}
};

static_cast<void>(app["services"][static_cast<std::string>(mongodb_service_id)]["rules"].post(user_data_rule));
static_cast<void>(app["services"][static_cast<std::string>(mongodb_service_id)]["rules"].post(asymmetric_object_rule));

app["custom_user_data"].patch(bson::BsonDocument {
{"mongo_service_id", mongodb_service_id},
{"enabled", true},
{"database_name", "test_data"},
{"collection_name", "UserData"},
{"user_id_field", "user_id"},
});
bson::BsonDocument service_config = {
{"flexible_sync", bson::BsonDocument {
{"type", "flexible"},
{"state", "enabled"},
{"database_name", "test_data"},
{"enabled", true},
{"is_recovery_mode_disabled", true},
{"queryable_fields_names", queryable_fields},
{"asymmetric_tables", bson::BsonArray({"AllTypesAsymmetricObject"})}

}}
};

bson::BsonDocument default_rule = {{"roles", bson::BsonArray ({bson::BsonDocument({
{"name", "all"},
{"apply_when", {}},
{"document_filters", bson::BsonDocument({{"read", true}, {"write", true} }) },
{"write", true},
{"read", true},
{"insert", true},
{"delete", true}
})
})}};

static_cast<void>(app["services"][mongodb_service_id]["default_rule"].post(default_rule));

// The cluster linking must be separated from enabling sync because Atlas
// takes a few seconds to provision a user for BaaS, meaning enabling sync
// will fail if we attempt to do it with the same request. It's nondeterministic
// how long it'll take, so we must retry for a while.
constexpr int max_attempts = 120;
for (int attempt = 0; attempt <= max_attempts; attempt++) {
try {
app["services"][mongodb_service_id]["config"].patch(std::move(service_config));
break;
} catch(std::exception&) {
if (attempt == max_attempts) {
REALM_TERMINATE("Could not link Atlas cluster");
} else {
util::format(std::cerr, "Could not update MongoDB service after %1 seconds. Will keep retrying.\n", (attempt + 1) * 5);
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
}

app["sync"]["config"].put({{"development_mode_enabled", true}});

return *static_cast<std::optional<std::string>>(info["client_app_id"]);
Expand Down
19 changes: 10 additions & 9 deletions tests/experimental/sync/flexible_sync_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ TEST_CASE("flexible_sync_beta", "[sync]") {

auto update_success = synced_realm.subscriptions().update([](realm::mutable_sync_subscription_set &subs) {
subs.clear();
})
.get();
}).get();
CHECK(update_success == true);
CHECK(synced_realm.subscriptions().size() == 0);

Expand Down Expand Up @@ -123,22 +122,24 @@ TEST_CASE("set collection sync", "[set]") {
CHECK(realm.subscriptions().size() == 0);

update_success = realm.subscriptions().update([](realm::mutable_sync_subscription_set &subs) {
subs.add<experimental::AllTypesObject>("foo-strings", [](auto &obj) {
return obj.str_col == "foo";
});
subs.add<experimental::AllTypesObject>("foo-strings", [](auto& obj) {
return obj._id == 123;
});
subs.add<experimental::AllTypesObjectLink>("foo-link");
}).get();
CHECK(update_success == true);
CHECK(realm.subscriptions().size() == 2);

auto obj = realm::experimental::AllTypesObject();
obj._id = 123;

auto managed_obj = realm.write([&]() {
return realm.add(std::move(obj));
});

auto scenario = [&](auto &p, auto &values, size_t expected_count) {
realm.write([&]() {
p->clear();
for (auto v: values) {
p->insert(v);
}
Expand All @@ -152,14 +153,14 @@ TEST_CASE("set collection sync", "[set]") {
test_set(&managed_obj.set_str_col, scenario, {"42", "42", "24", "-1"});
test_set(&managed_obj.set_uuid_col, scenario, {realm::uuid("18de7916-7f84-11ec-a8a3-0242ac120000"), realm::uuid("18de7916-7f84-11ec-a8a3-0242ac120000"), realm::uuid("18de7916-7f84-11ec-a8a3-0242ac120001"), realm::uuid("18de7916-7f84-11ec-a8a3-0242ac120002")});
auto obj_id = realm::object_id::generate();
test_set(&managed_obj.set_object_id_col, scenario, {obj_id, obj_id, realm::object_id::generate(), realm::object_id::generate()});
test_set(&managed_obj.set_object_id_col, scenario, {obj_id, obj_id, realm::object_id::generate(), realm::object_id::generate()}); // here

auto bin_data = std::vector<uint8_t>({1, 2, 3, 4});
test_set(&managed_obj.set_binary_col, scenario, {bin_data, bin_data, std::vector<uint8_t>({1, 3, 4}), std::vector<uint8_t>({1})});

auto time = std::chrono::system_clock::now();
auto time2 = time + time.time_since_epoch();
test_set(&managed_obj.set_date_col, scenario, {time, time, time2, std::chrono::time_point<std::chrono::system_clock>()});
test_set(&managed_obj.set_date_col, scenario, {time, time, time2, std::chrono::time_point<std::chrono::system_clock>()}); // here
test_set(&managed_obj.set_mixed_col, scenario, {realm::mixed((int64_t)42), realm::mixed((int64_t)42), realm::mixed("24"), realm::mixed(realm::uuid("18de7916-7f84-11ec-a8a3-0242ac120002"))});

test::wait_for_sync_uploads(user).get();
Expand All @@ -170,8 +171,8 @@ TEST_CASE("set collection sync", "[set]") {

auto realm2 = realm::experimental::db(user2.flexible_sync_configuration());
auto update_success2 = realm2.subscriptions().update([](realm::mutable_sync_subscription_set &subs) {
subs.add<experimental::AllTypesObject>("foo-strings", [](auto &obj) {
return obj.str_col == "foo";
subs.add<experimental::AllTypesObject>("foo-strings", [](auto& obj) {
return obj._id == 123;
});
subs.add<experimental::AllTypesObjectLink>("foo-link");
}).get();
Expand Down

0 comments on commit 19e3720

Please sign in to comment.