Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CXX-2138 Implement versioned API #792

Merged
merged 18 commits into from May 26, 2021
Merged

CXX-2138 Implement versioned API #792

merged 18 commits into from May 26, 2021

Conversation

benjirewis
Copy link
Contributor

@benjirewis benjirewis commented May 10, 2021

CXX-2138

Implements versioned API. First commit adds and updates spec tests files for versioned API. Remaining commits update unified test runner, create new server_api class, and allow setting of server_api_options through client. Beyond creating the class and allowing configuration through client, few changes were required apart from wrapping the C driver implementation.

Further CXX changes will be required to allow versioned API testing in Evergreen. This work will be done as part of CXX-2254.

Copy link
Contributor Author

@benjirewis benjirewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server_api class and its configuration through client is based off the auto_encryption class.

///
/// Enum representing the possible values for server API version.
///
enum class version { version_1 };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used the name version, as server_api_version would mean this is called options::server_api::server_api_version which seems redundant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling it version is fine, but the value needs to be k_version_1 to follow the constant naming used elsewhere in the driver.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also potentially not make it an enum class? Is it harmful if the constants exist at class scope? It might even be clearer: options::server_api_version::version_1 still duplicates version, but options::server_api::k_version_1 reads pretty well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to k_version_1, but I kept it as an enum. It would probably be good for users to be able to switch on a version and have their IDE catch any un-handled server API versions.

src/mongocxx/test/spec/util.hh Show resolved Hide resolved
@benjirewis benjirewis marked this pull request as ready for review May 10, 2021 16:41
@codecov-commenter
Copy link

codecov-commenter commented May 10, 2021

Codecov Report

Merging #792 (f465d5f) into master (908f0e6) will decrease coverage by 4.40%.
The diff coverage is 86.31%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #792      +/-   ##
==========================================
- Coverage   90.76%   86.36%   -4.41%     
==========================================
  Files         377      380       +3     
  Lines       21757    21860     +103     
==========================================
- Hits        19748    18879     -869     
- Misses       2009     2981     +972     
Impacted Files Coverage Δ
src/mongocxx/options/client.hpp 100.00% <ø> (ø)
src/mongocxx/pool.cpp 56.86% <14.28%> (-11.32%) ⬇️
src/mongocxx/options/private/server_api.hh 80.00% <80.00%> (ø)
src/mongocxx/client.cpp 85.71% <85.71%> (ø)
src/mongocxx/options/server_api.cpp 86.95% <86.95%> (ø)
src/mongocxx/events/server_description.cpp 100.00% <100.00%> (ø)
src/mongocxx/options/client.cpp 83.33% <100.00%> (+4.38%) ⬆️
src/mongocxx/options/server_api.hpp 100.00% <100.00%> (ø)
src/mongocxx/private/index_view.hh 95.14% <100.00%> (ø)
src/mongocxx/private/libmongoc_symbols.hh 100.00% <100.00%> (ø)
... and 42 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 908f0e6...f465d5f. Read the comment docs.

src/mongocxx/client.cpp Outdated Show resolved Hide resolved
src/mongocxx/client.cpp Outdated Show resolved Hide resolved
src/mongocxx/options/client.hpp Outdated Show resolved Hide resolved
src/mongocxx/options/server_api.hpp Show resolved Hide resolved
src/mongocxx/options/server_api.hpp Outdated Show resolved Hide resolved
// See the License for the specific language governing permissions and
// limitations under the License.

#include <mongocxx/config/private/prelude.hh>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs are wrong, but prelude.hh should come after all the driver headers. I will file a ticket to fix the docs and hopefully get it bulk corrected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, thanks for filing the docs ticket. I will say that my version of clang (11.1.0) disagrees, and will try to place it on top. Done.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll use CXX-2258 to change the .clang-format file and re-format the whole codebase to make sure preludes come last. For now, server_api.cpp and server_api.hpp will just follow the rest of the codebase.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, ignore my comment above about ordering then.

src/mongocxx/options/server_api.cpp Outdated Show resolved Hide resolved

#pragma once

#include <mongocxx/config/prelude.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to after driver headers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .clang-format has a macro enforcing prelude.hpp appears before other headers:

- Regex: 'prelude\.(hpp|hh)' # preludes

I vote we revert this so the lint task passes for now, and fix them all, with the .clang-format file, as part of CXX-2258.

src/mongocxx/test/CMakeLists.txt Show resolved Hide resolved
@benjirewis benjirewis requested a review from acmorrow May 11, 2021 17:02
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good!

Can you investigate the test failure for: estimatedDocumentCount appends declared API version

if (!version.compare("1")) {
return server_api::version::k_version_1;
}
throw std::logic_error{"invalid server API version"};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: append the version to the error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


auto mongoc_server_api_opts = libmongoc::server_api_new(mongoc_api_version);
if (!mongoc_server_api_opts) {
throw std::logic_error{"could not get object from libmongoc"};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C++ driver hides details about libmongoc/libbson from users from the public API. We should probably avoid mentioning it in error messages:

Suggested change
throw std::logic_error{"could not get object from libmongoc"};
throw std::logic_error{"could not create server API"};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know. Done.

src/mongocxx/client.cpp Outdated Show resolved Hide resolved
/// The enum value to convert to a string.
///
/// @return
/// The string value of the given enum value.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Note that these methods can throw with @throws mongocxx::logic_error on an invalid argument

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added here and on version_from_string.

///
/// The specified API version will be sent to the server. This will cause
/// the server to behave in a manner compatible with that API version.
/// It also causes the driver to behave in a manner compatible with the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

driver to behave in a manner compatible with the driver's behavior as of the release when the driver

Reads a little strange to me. It looks like this is close to the Background, perhaps it could use that directly:

The driver will behave in a manner compatible with a server configured with that API version, regardless of the server's actual release version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm good point; used that documentation instead.

FAIL("must specify a version when using serverApi");
}

REQUIRE(sav.type() == type::k_string);
auto version =
options::server_api::version_from_string(string::to_string(sav.get_string().value));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Now that version_from_string takes a string_view I think this can be simplified:

Suggested change
options::server_api::version_from_string(string::to_string(sav.get_string().value));
options::server_api::version_from_string(sav.get_string().value);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


#pragma once

#include <mongocxx/config/prelude.hpp>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .clang-format has a macro enforcing prelude.hpp appears before other headers:

- Regex: 'prelude\.(hpp|hh)' # preludes

I vote we revert this so the lint task passes for now, and fix them all, with the .clang-format file, as part of CXX-2258.

Copy link
Contributor

@acmorrow acmorrow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small things only. I took a more or less cursory run through the tests, because I don't think I'm a particularly useful reviewer for that part. But, overall, this looks good with a few small things I called out. I don't particularly think any of them need another round of review.

LGTM

src/mongocxx/options/private/server_api.hh Outdated Show resolved Hide resolved
src/mongocxx/options/private/server_api.hh Show resolved Hide resolved
using unique_server_api =
std::unique_ptr<mongoc_server_api_t, decltype(libmongoc::server_api_destroy)>;

static unique_server_api make_server_api(const server_api& opts) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to include-what-you-use for mongocxx::server_api.

// See the License for the specific language governing permissions and
// limitations under the License.

#include <mongocxx/config/private/prelude.hh>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, ignore my comment above about ordering then.

///
/// Enum representing the possible values for server API version.
///
enum class version { k_version_1 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose, if you wanted to, that you could replace k_version_1 here with k_1, since you have kept it as an enum class, and version is already in the name. Totally up to you. At three characters, k_1 is getting awfully short and potentially into the "what if it conflicts with some crazy system macro" territory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah server_api::version::k_version_1 reads a little clearer to me even if redundant. Unless @kevinAlbs has a strong opinion, I'll probably keep it as k_version_1.

/// @param version
/// The server api version to send to the server.
///
server_api(version version);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but you can still move it up a good deal. Please do before commit, but no need to post an update for that.

/// @return
/// The version enum value specifying the declared server api version.
///
version api_version() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. Let's call it get_version then. No need to post an update for that.

Copy link
Contributor Author

@benjirewis benjirewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ubuntu1804-power8 tasks are failing because their server version is outdated; looking into that.

Some more tasks will start to fail until getMore + transaction-continuing commands append API version (CDRIVER-3974).

src/mongocxx/options/private/server_api.hh Outdated Show resolved Hide resolved
src/mongocxx/options/private/server_api.hh Show resolved Hide resolved
///
/// Enum representing the possible values for server API version.
///
enum class version { k_version_1 };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah server_api::version::k_version_1 reads a little clearer to me even if redundant. Unless @kevinAlbs has a strong opinion, I'll probably keep it as k_version_1.

/// @param version
/// The server api version to send to the server.
///
server_api(version version);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to directly after enum declaration.

/// @return
/// The version enum value specifying the declared server api version.
///
version api_version() const;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to get_version.

@benjirewis benjirewis requested a review from kevinAlbs May 20, 2021 16:24
@@ -277,7 +277,7 @@ MONGOCXX_LIBMONGOC_SYMBOL(server_api_get_strict)
MONGOCXX_LIBMONGOC_SYMBOL(server_api_get_version)
MONGOCXX_LIBMONGOC_SYMBOL(server_description_host)
MONGOCXX_LIBMONGOC_SYMBOL(server_description_id)
MONGOCXX_LIBMONGOC_SYMBOL(server_description_ismaster)
MONGOCXX_LIBMONGOC_SYMBOL(server_description_hello_response)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

server_description_ismaster is now deprecated (CDRIVER-3947) and will cause build failures, so I've updated usages to server_description_hello_response.

@acmorrow
Copy link
Contributor

LGTM still


auto mongoc_server_api_opts = libmongoc::server_api_new(mongoc_api_version);
if (!mongoc_server_api_opts) {
throw std::logic_error{"could not get object create server API"};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: This reads a little strange.

Suggested change
throw std::logic_error{"could not get object create server API"};
throw std::logic_error{"could create server API"};

src/mongocxx/options/private/server_api.hh Show resolved Hide resolved
src/mongocxx/pool.cpp Show resolved Hide resolved
]
},
{
"description": "find command with declared API version appends to the command, but getMore does not",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be out of date and need to be resynced to get tests passing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resynced all tests one more time!

@benjirewis benjirewis requested a review from kevinAlbs May 24, 2021 15:14
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest changes LGTM.

The mongohouse failure looks related to the server's handling of batch size and getMore and unrelated to these changes.

@benjirewis benjirewis merged commit c585e14 into mongodb:master May 26, 2021
@benjirewis benjirewis deleted the versionedAPI.2138 branch May 26, 2021 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants