summaryrefslogtreecommitdiff
path: root/src/mongo/rpc
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2021-02-10 12:33:29 +0100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-10 12:11:44 +0000
commit0dc7dd13c6b5d99d6c22d44f7ef96750f3540e50 (patch)
tree9de22c8a63b9aae80d0c32316e7249d983a35e08 /src/mongo/rpc
parenteab7770928e86e0e70a035da87aa3fa616b9cc42 (diff)
downloadmongo-0dc7dd13c6b5d99d6c22d44f7ef96750f3540e50.tar.gz
Revert "SERVER-53150 Specify input/output to hello command"
This reverts commit 92dfc822d41714b47bc20e260aafb54884909acc.
Diffstat (limited to 'src/mongo/rpc')
-rw-r--r--src/mongo/rpc/SConscript1
-rw-r--r--src/mongo/rpc/metadata/client_metadata.cpp109
-rw-r--r--src/mongo/rpc/metadata/client_metadata.h20
-rw-r--r--src/mongo/rpc/metadata/client_metadata.idl44
4 files changed, 79 insertions, 95 deletions
diff --git a/src/mongo/rpc/SConscript b/src/mongo/rpc/SConscript
index 257e556da03..957647e5721 100644
--- a/src/mongo/rpc/SConscript
+++ b/src/mongo/rpc/SConscript
@@ -135,7 +135,6 @@ env.Library(
target='client_metadata',
source=[
'metadata/client_metadata.cpp',
- 'metadata/client_metadata.idl',
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
diff --git a/src/mongo/rpc/metadata/client_metadata.cpp b/src/mongo/rpc/metadata/client_metadata.cpp
index 6ea09b44b02..a4a8767aadc 100644
--- a/src/mongo/rpc/metadata/client_metadata.cpp
+++ b/src/mongo/rpc/metadata/client_metadata.cpp
@@ -84,7 +84,7 @@ const auto getOperationState = OperationContext::declareDecoration<ClientMetadat
} // namespace
-StatusWith<boost::optional<ClientMetadata>> ClientMetadata::parse(const BSONElement& element) try {
+StatusWith<boost::optional<ClientMetadata>> ClientMetadata::parse(const BSONElement& element) {
if (element.eoo()) {
return {boost::none};
}
@@ -93,50 +93,84 @@ StatusWith<boost::optional<ClientMetadata>> ClientMetadata::parse(const BSONElem
return Status(ErrorCodes::TypeMismatch, "The client metadata document must be a document");
}
- return boost::make_optional(parseFromBSON(element.Obj()));
-} catch (const DBException& ex) {
- return ex.toStatus();
+ ClientMetadata clientMetadata;
+ Status s = clientMetadata.parseClientMetadataDocument(element.Obj());
+ if (!s.isOK()) {
+ return s;
+ }
+
+ return {std::move(clientMetadata)};
}
-ClientMetadata::ClientMetadata(BSONObj doc) {
+Status ClientMetadata::parseClientMetadataDocument(const BSONObj& doc) {
uint32_t maxLength = kMaxMongoDMetadataDocumentByteLength;
if (isMongos()) {
maxLength = kMaxMongoSMetadataDocumentByteLength;
}
- uassert(ErrorCodes::ClientMetadataDocumentTooLarge,
- str::stream() << "The client metadata document must be less then or equal to "
- << maxLength << "bytes",
- static_cast<uint32_t>(doc.objsize()) <= maxLength);
-
- const auto isobj = [](StringData name, const BSONElement& e) {
- uassert(ErrorCodes::TypeMismatch,
- str::stream()
- << "The '" << name
- << "' field is required to be a BSON document in the client metadata document",
- e.isABSONObj());
- };
+ if (static_cast<uint32_t>(doc.objsize()) > maxLength) {
+ return Status(ErrorCodes::ClientMetadataDocumentTooLarge,
+ str::stream() << "The client metadata document must be less then or equal to "
+ << maxLength << "bytes");
+ }
// Get a copy so that we can take a stable reference to the app name inside
- _document = doc.getOwned();
+ BSONObj docOwned = doc.getOwned();
+ StringData appName;
bool foundDriver = false;
bool foundOperatingSystem = false;
- for (const auto& e : _document) {
- auto name = e.fieldNameStringData();
+
+ BSONObjIterator i(docOwned);
+ while (i.more()) {
+ BSONElement e = i.next();
+ StringData name = e.fieldNameStringData();
if (name == kApplication) {
// Application is an optional sub-document, but we require it to be a document if
// specified.
- isobj(kApplication, e);
- _appName = uassertStatusOK(parseApplicationDocument(e.Obj()));
+ if (!e.isABSONObj()) {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << "The '" << kApplication
+ << "' field is required to be a BSON document in the "
+ "client metadata document");
+ }
+
+ auto swAppName = parseApplicationDocument(e.Obj());
+ if (!swAppName.getStatus().isOK()) {
+ return swAppName.getStatus();
+ }
+
+ appName = swAppName.getValue();
+
} else if (name == kDriver) {
- isobj(kDriver, e);
- uassertStatusOK(validateDriverDocument(e.Obj()));
+ if (!e.isABSONObj()) {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << "The '" << kDriver
+ << "' field is required to be a "
+ "BSON document in the client "
+ "metadata document");
+ }
+
+ Status s = validateDriverDocument(e.Obj());
+ if (!s.isOK()) {
+ return s;
+ }
+
foundDriver = true;
} else if (name == kOperatingSystem) {
- isobj(kOperatingSystem, e);
- uassertStatusOK(validateOperatingSystemDocument(e.Obj()));
+ if (!e.isABSONObj()) {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << "The '" << kOperatingSystem
+ << "' field is required to be a BSON document in the "
+ "client metadata document");
+ }
+
+ Status s = validateOperatingSystemDocument(e.Obj());
+ if (!s.isOK()) {
+ return s;
+ }
+
foundOperatingSystem = true;
}
@@ -144,16 +178,23 @@ ClientMetadata::ClientMetadata(BSONObj doc) {
}
// Driver is a required sub document.
- uassert(ErrorCodes::ClientMetadataMissingField,
- str::stream() << "Missing required sub-document '" << kDriver
- << "' in the client metadata document",
- foundDriver);
+ if (!foundDriver) {
+ return Status(ErrorCodes::ClientMetadataMissingField,
+ str::stream() << "Missing required sub-document '" << kDriver
+ << "' in the client metadata document");
+ }
// OS is a required sub document.
- uassert(ErrorCodes::ClientMetadataMissingField,
- str::stream() << "Missing required sub-document '" << kOperatingSystem
- << "' in the client metadata document",
- foundOperatingSystem);
+ if (!foundOperatingSystem) {
+ return Status(ErrorCodes::ClientMetadataMissingField,
+ str::stream() << "Missing required sub-document '" << kOperatingSystem
+ << "' in the client metadata document");
+ }
+
+ _document = std::move(docOwned);
+ _appName = std::move(appName);
+
+ return Status::OK();
}
StatusWith<StringData> ClientMetadata::parseApplicationDocument(const BSONObj& doc) {
diff --git a/src/mongo/rpc/metadata/client_metadata.h b/src/mongo/rpc/metadata/client_metadata.h
index 309eb5668e0..cc3d870a4f0 100644
--- a/src/mongo/rpc/metadata/client_metadata.h
+++ b/src/mongo/rpc/metadata/client_metadata.h
@@ -80,16 +80,10 @@ constexpr auto kMetadataDocumentName = "client"_sd;
* See Driver Specification: "MongoDB Handshake" for more information.
*/
class ClientMetadata {
-public:
- explicit ClientMetadata(BSONObj obj);
-
- ClientMetadata(const ClientMetadata& src) : ClientMetadata(src._document) {}
- ClientMetadata& operator=(const ClientMetadata& src) {
- ClientMetadata copy(src._document);
- *this = std::move(copy);
- return *this;
- }
+ ClientMetadata(const ClientMetadata&) = delete;
+ ClientMetadata& operator=(const ClientMetadata&) = delete;
+public:
ClientMetadata(ClientMetadata&&) = default;
ClientMetadata& operator=(ClientMetadata&&) = default;
@@ -151,13 +145,6 @@ public:
static StatusWith<boost::optional<ClientMetadata>> parse(const BSONElement& element);
/**
- * Wrapper for BSONObj constructor used by IDL parsers.
- */
- static ClientMetadata parseFromBSON(BSONObj obj) {
- return ClientMetadata(obj);
- }
-
- /**
* Create a new client metadata document with os information from the ProcessInfo class.
*
* This method outputs the "client" field, and client metadata sub-document in the
@@ -324,6 +311,7 @@ public:
private:
ClientMetadata() = default;
+ Status parseClientMetadataDocument(const BSONObj& doc);
static Status validateDriverDocument(const BSONObj& doc);
static Status validateOperatingSystemDocument(const BSONObj& doc);
static StatusWith<StringData> parseApplicationDocument(const BSONObj& doc);
diff --git a/src/mongo/rpc/metadata/client_metadata.idl b/src/mongo/rpc/metadata/client_metadata.idl
deleted file mode 100644
index d1726153d98..00000000000
--- a/src/mongo/rpc/metadata/client_metadata.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2021-present MongoDB, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the Server Side Public License, version 1,
-# as published by MongoDB, Inc.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# Server Side Public License for more details.
-#
-# You should have received a copy of the Server Side Public License
-# along with this program. If not, see
-# <http://www.mongodb.com/licensing/server-side-public-license>.
-#
-# As a special exception, the copyright holders give permission to link the
-# code of portions of this program with the OpenSSL library under certain
-# conditions as described in each individual source file and distribute
-# linked combinations including the program with the OpenSSL library. You
-# must comply with the Server Side Public License in all respects for
-# all of the code used other than as permitted herein. If you modify file(s)
-# with this exception, you may extend this exception to your version of the
-# file(s), but you are not obligated to do so. If you do not wish to do so,
-# delete this exception statement from your version. If you delete this
-# exception statement from all source files in the program, then also delete
-# it in the license file.
-#
-
-global:
- cpp_namespace: "mongo"
- cpp_includes:
- - "mongo/rpc/metadata/client_metadata.h"
-
-imports:
- - "mongo/idl/basic_types.idl"
-
-types:
- ClientMetadata:
- description: "Client metadata document"
- bson_serialization_type: object
- cpp_type: ClientMetadata
- serializer: "mongo::ClientMetadata::getDocument"
- deserializer: "mongo::ClientMetadata::parseFromBSON"
-