diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/client/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/client/client_deprecated.cpp | 216 | ||||
-rw-r--r-- | src/mongo/client/client_deprecated.h | 55 | ||||
-rw-r--r-- | src/mongo/client/dbclient_rs.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/commands/apply_ops_cmd.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/commands/oplog_application_checks.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/repl/apply_ops.cpp | 70 | ||||
-rw-r--r-- | src/mongo/db/repl/apply_ops.idl | 7 | ||||
-rw-r--r-- | src/mongo/db/repl/apply_ops_command_info.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/repl/apply_ops_command_info.h | 1 |
10 files changed, 11 insertions, 369 deletions
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript index 619594b97e5..296e0ec8b8f 100644 --- a/src/mongo/client/SConscript +++ b/src/mongo/client/SConscript @@ -172,7 +172,6 @@ clientDriverEnv.Library( target='clientdriver_minimal', source=[ 'client_api_version_parameters.idl', - 'client_deprecated.cpp', 'dbclient_base.cpp', 'dbclient_cursor.cpp', 'index_spec.cpp', diff --git a/src/mongo/client/client_deprecated.cpp b/src/mongo/client/client_deprecated.cpp deleted file mode 100644 index 2df1d1be3ac..00000000000 --- a/src/mongo/client/client_deprecated.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Copyright (C) 2018-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. - */ - -#include "mongo/client/client_deprecated.h" - -#include "mongo/base/status.h" -#include "mongo/base/status_with.h" -#include "mongo/bson/util/builder.h" -#include "mongo/db/query/query_request_helper.h" - -namespace mongo { -namespace client_deprecated { - -namespace { -bool isComplexQueryObj(const BSONObj& obj, bool* hasDollar) { - if (obj.hasElement("query")) { - if (hasDollar) - *hasDollar = false; - return true; - } - - if (obj.hasElement("$query")) { - if (hasDollar) - *hasDollar = true; - return true; - } - - return false; -} - -BSONObj filterFromOpQueryObj(const BSONObj& obj) { - bool hasDollar; - if (!isComplexQueryObj(obj, &hasDollar)) { - return obj; - } - - return obj.getObjectField(hasDollar ? "$query" : "query"); -} - -void initFindFromOptions(int options, FindCommandRequest* findCommand) { - bool tailable = (options & QueryOption_CursorTailable) != 0; - bool awaitData = (options & QueryOption_AwaitData) != 0; - if (awaitData) { - findCommand->setAwaitData(true); - } - if (tailable) { - findCommand->setTailable(true); - } - - if ((options & QueryOption_NoCursorTimeout) != 0) { - findCommand->setNoCursorTimeout(true); - } - if ((options & QueryOption_PartialResults) != 0) { - findCommand->setAllowPartialResults(true); - } -} - -/** - * Fills out the 'findCommand' output parameter based on the contents of 'querySettings'. Here, - * 'querySettings' has the same format as the "query" field of the no-longer-supported OP_QUERY wire - * protocol message. It can look something like this for example: - * - * {$query: ..., $hint: ..., $min: ..., $max: ...} - * - * Note that this does not set the filter itself on the 'FindCommandRequest' -- this function only - * deals with options that can be packed into the filter object. - * - * Although the OP_QUERY wire protocol message is no longer ever sent over the wire by the internal - * client, this supports old callers of that still specify the operation they want to perform using - * an OP_QUERY-inspired format. - */ -Status initFindFromOpQueryObj(const BSONObj& querySettings, FindCommandRequest* findCommand) { - for (auto&& e : querySettings) { - StringData name = e.fieldNameStringData(); - - if (name == "$orderby" || name == "orderby") { - if (Object == e.type()) { - findCommand->setSort(e.embeddedObject().getOwned()); - } else if (Array == e.type()) { - findCommand->setSort(e.embeddedObject()); - - // TODO: Is this ever used? I don't think so. - // Quote: - // This is for languages whose "objects" are not well ordered (JSON is well - // ordered). - // [ { a : ... } , { b : ... } ] -> { a : ..., b : ... } - // note: this is slow, but that is ok as order will have very few pieces - BSONObjBuilder b; - char p[2] = "0"; - - while (1) { - BSONObj j = findCommand->getSort().getObjectField(p); - if (j.isEmpty()) { - break; - } - BSONElement e = j.firstElement(); - if (e.eoo()) { - return Status(ErrorCodes::BadValue, "bad order array"); - } - if (!e.isNumber()) { - return Status(ErrorCodes::BadValue, "bad order array [2]"); - } - b.append(e); - (*p)++; - if (!(*p <= '9')) { - return Status(ErrorCodes::BadValue, "too many ordering elements"); - } - } - - findCommand->setSort(b.obj()); - } else { - return Status(ErrorCodes::BadValue, "sort must be object or array"); - } - } else if (name == "term") { - findCommand->setTerm(e.safeNumberLong()); - } else if (name == "readConcern") { - if (e.type() != BSONType::Object) { - return Status(ErrorCodes::BadValue, "readConcern must be an object"); - } - findCommand->setReadConcern(e.embeddedObject().getOwned()); - } else if (name.startsWith("$")) { - name = name.substr(1); // chop first char - if (name == "min") { - if (!e.isABSONObj()) { - return Status(ErrorCodes::BadValue, "$min must be a BSONObj"); - } - findCommand->setMin(e.embeddedObject().getOwned()); - } else if (name == "max") { - if (!e.isABSONObj()) { - return Status(ErrorCodes::BadValue, "$max must be a BSONObj"); - } - findCommand->setMax(e.embeddedObject().getOwned()); - } else if (name == "hint") { - if (e.isABSONObj()) { - findCommand->setHint(e.embeddedObject().getOwned()); - } else if (String == e.type()) { - findCommand->setHint(e.wrap()); - } else { - return Status(ErrorCodes::BadValue, - "$hint must be either a string or nested object"); - } - } else if (name == "returnKey") { - // Won't throw. - if (e.trueValue()) { - findCommand->setReturnKey(true); - } - } else if (name == "showDiskLoc") { - // Won't throw. - if (e.trueValue()) { - findCommand->setShowRecordId(true); - query_request_helper::addShowRecordIdMetaProj(findCommand); - } - } else if (name == "maxTimeMS") { - StatusWith<int> maxTimeMS = parseMaxTimeMS(e); - if (!maxTimeMS.isOK()) { - return maxTimeMS.getStatus(); - } - findCommand->setMaxTimeMS(maxTimeMS.getValue()); - } else if (name == "readOnce") { - if (e.booleanSafe()) { - findCommand->setReadOnce(true); - } - } else if (name == "_requestResumeToken") { - if (e.booleanSafe()) { - findCommand->setRequestResumeToken(true); - } - } else if (name == "_resumeAfter") { - findCommand->setResumeAfter(e.embeddedObjectUserCheck().getOwned()); - } - } - } - - return Status::OK(); -} - -} // namespace - -void initFindFromLegacyOptions(BSONObj bsonOptions, int options, FindCommandRequest* findCommand) { - invariant(findCommand); - BSONObj filter = filterFromOpQueryObj(bsonOptions); - if (!filter.isEmpty()) { - findCommand->setFilter(filter.getOwned()); - } - - uassertStatusOK(initFindFromOpQueryObj(bsonOptions, findCommand)); - initFindFromOptions(options, findCommand); -} - -} // namespace client_deprecated -} // namespace mongo diff --git a/src/mongo/client/client_deprecated.h b/src/mongo/client/client_deprecated.h deleted file mode 100644 index fa4509c62f8..00000000000 --- a/src/mongo/client/client_deprecated.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (C) 2018-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. - */ - -#pragma once - -#include "mongo/bson/json.h" -#include "mongo/client/read_preference.h" -#include "mongo/db/query/find_command_gen.h" -#include "mongo/rpc/message.h" - -namespace mongo { -/** - * WARNING: Do not add new uses of anything in this namespace! This exists only to support code - * paths that still use an OP_QUERY-derived query representation. Additional callers should not be - * added because OP_QUERY is no longer supported by the shell or server. - */ -namespace client_deprecated { -/** - * WARNING: This function exists only to support special code paths that use an OP_QUERY-style query - * representation (even though the OP_QUERY wire protocol message itself is no longer supported). Do - * not add new callers. - * - * Sets the relevant fields in 'findCommand' based on the 'bsonOptions' object and the 'options' bit - * vector. 'bsonOptions' is formatted like the query object of an OP_QUERY wire protocol message. - * Similarly, 'options' is a bit vector which is interpreted like the OP_QUERY flags field. - */ -void initFindFromLegacyOptions(BSONObj bsonOptions, int options, FindCommandRequest* findCommand); -} // namespace client_deprecated -} // namespace mongo diff --git a/src/mongo/client/dbclient_rs.cpp b/src/mongo/client/dbclient_rs.cpp index 6d86e41a936..82aa7cb43a1 100644 --- a/src/mongo/client/dbclient_rs.cpp +++ b/src/mongo/client/dbclient_rs.cpp @@ -33,7 +33,6 @@ #include <utility> #include "mongo/bson/util/builder.h" -#include "mongo/client/client_deprecated.h" #include "mongo/client/connpool.h" #include "mongo/client/dbclient_cursor.h" #include "mongo/client/global_conn_pool.h" diff --git a/src/mongo/db/commands/apply_ops_cmd.cpp b/src/mongo/db/commands/apply_ops_cmd.cpp index 56adcab2cb6..d074ecc3edb 100644 --- a/src/mongo/db/commands/apply_ops_cmd.cpp +++ b/src/mongo/db/commands/apply_ops_cmd.cpp @@ -199,8 +199,7 @@ public: } std::string help() const override { - return "internal (sharding)\n{ applyOps : [ ] , preCondition : [ { ns : ... , q : ... , " - "res : ... } ] }"; + return "internal command to apply oplog entries\n{ applyOps : [ ] }"; } Status checkAuthForOperation(OperationContext* opCtx, diff --git a/src/mongo/db/commands/oplog_application_checks.cpp b/src/mongo/db/commands/oplog_application_checks.cpp index 80e0e8720e3..02cc6e51366 100644 --- a/src/mongo/db/commands/oplog_application_checks.cpp +++ b/src/mongo/db/commands/oplog_application_checks.cpp @@ -258,21 +258,6 @@ Status OplogApplicationChecks::checkAuthForCommand(OperationContext* opCtx, } } - BSONElement preconditions = cmdObj["preCondition"]; - if (!preconditions.eoo()) { - for (const BSONElement& precondition : preconditions.Array()) { - checkBSONType(BSONType::Object, precondition); - BSONElement nsElem = precondition.Obj()["ns"]; - checkBSONType(BSONType::String, nsElem); - NamespaceString nss(nsElem.checkAndGetStringData()); - - if (!authSession->isAuthorizedForActionsOnResource( - ResourcePattern::forExactNamespace(nss), ActionType::find)) { - return Status(ErrorCodes::Unauthorized, "Unauthorized to check precondition"); - } - } - } - return Status::OK(); } diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp index c89a830b459..59512366b11 100644 --- a/src/mongo/db/repl/apply_ops.cpp +++ b/src/mongo/db/repl/apply_ops.cpp @@ -30,10 +30,8 @@ #include "mongo/db/repl/apply_ops.h" #include "mongo/bson/util/bson_extract.h" -#include "mongo/client/client_deprecated.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/database.h" -#include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/document_validation.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/exception_util.h" @@ -44,7 +42,6 @@ #include "mongo/db/dbdirectclient.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/index_builds_coordinator.h" -#include "mongo/db/matcher/matcher.h" #include "mongo/db/op_observer/op_observer.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/replication_coordinator.h" @@ -60,7 +57,6 @@ namespace mongo { namespace repl { -constexpr StringData ApplyOps::kPreconditionFieldName; constexpr StringData ApplyOps::kOplogApplicationModeFieldName; namespace { @@ -276,58 +272,6 @@ Status _applyOps(OperationContext* opCtx, return Status::OK(); } -Status _checkPrecondition(OperationContext* opCtx, - const std::vector<BSONObj>& preConditions, - BSONObjBuilder* result) { - invariant(opCtx->lockState()->isW()); - - for (const auto& preCondition : preConditions) { - if (preCondition["ns"].type() != BSONType::String) { - return {ErrorCodes::InvalidNamespace, - str::stream() << "ns in preCondition must be a string, but found type: " - << typeName(preCondition["ns"].type())}; - } - const NamespaceString nss(preCondition["ns"].valueStringData()); - if (!nss.isValid()) { - return {ErrorCodes::InvalidNamespace, "invalid ns: " + nss.ns()}; - } - - DBDirectClient db(opCtx); - // The preconditions come in "q: {{query: {...}, orderby: ..., etc.}}" format. This format - // is no longer used either internally or over the wire in other contexts. We are using a - // legacy API from 'client_deprecated' in order to parse this format and convert it into the - // corresponding find command. - FindCommandRequest findCmd{nss}; - client_deprecated::initFindFromLegacyOptions(preCondition["q"].Obj(), 0, &findCmd); - BSONObj realres = db.findOne(std::move(findCmd)); - - // Get collection default collation. - auto databaseHolder = DatabaseHolder::get(opCtx); - auto database = databaseHolder->getDb(opCtx, nss.dbName()); - if (!database) { - return {ErrorCodes::NamespaceNotFound, "database in ns does not exist: " + nss.ns()}; - } - CollectionPtr collection = - CollectionCatalog::get(opCtx)->lookupCollectionByNamespace(opCtx, nss); - if (!collection) { - return {ErrorCodes::NamespaceNotFound, "collection in ns does not exist: " + nss.ns()}; - } - const CollatorInterface* collator = collection->getDefaultCollator(); - - // applyOps does not allow any extensions, such as $text, $where, $geoNear, $near, - // $nearSphere, or $expr. - boost::intrusive_ptr<ExpressionContext> expCtx( - new ExpressionContext(opCtx, CollatorInterface::cloneCollator(collator), nss)); - Matcher matcher(preCondition["res"].Obj(), std::move(expCtx)); - if (!matcher.matches(realres)) { - result->append("got", realres); - result->append("whatFailed", preCondition); - return {ErrorCodes::BadValue, "preCondition failed"}; - } - } - - return Status::OK(); -} } // namespace Status applyApplyOpsOplogEntry(OperationContext* opCtx, @@ -359,9 +303,9 @@ Status applyOps(OperationContext* opCtx, uassert(31056, "applyOps command can't have 'partialTxn' field.", !info.getPartialTxn()); uassert(31240, "applyOps command can't have 'count' field.", !info.getCount()); - // There's one case where we are allowed to take the database lock instead of the global - // lock - no preconditions; only CRUD ops; and non-atomic mode. - if (!info.getPreCondition() && info.areOpsCrudOnly() && !info.getAllowAtomic()) { + // There's one case where we are allowed to take the database lock instead of the global lock -- + // only CRUD ops and non-atomic mode. + if (info.areOpsCrudOnly() && !info.getAllowAtomic()) { // TODO SERVER-62880 Once the dbName is of type DatabaseName, pass it directly to the DBlock DatabaseName databaseName(boost::none, dbName); dbWriteLock.emplace(opCtx, databaseName, MODE_IX); @@ -377,14 +321,6 @@ Status applyOps(OperationContext* opCtx, return Status(ErrorCodes::NotWritablePrimary, str::stream() << "Not primary while applying ops to database " << dbName); - if (auto preCondition = info.getPreCondition()) { - invariant(info.isAtomic()); - auto status = _checkPrecondition(opCtx, *preCondition, result); - if (!status.isOK()) { - return status; - } - } - LOGV2_DEBUG(5854600, 2, "applyOps command", diff --git a/src/mongo/db/repl/apply_ops.idl b/src/mongo/db/repl/apply_ops.idl index 792f6a63d1e..d9a1e17fb1f 100644 --- a/src/mongo/db/repl/apply_ops.idl +++ b/src/mongo/db/repl/apply_ops.idl @@ -64,9 +64,10 @@ structs: cpp_name: preCondition type: array<object> optional: true - description: "applyOps supports checking the documents of existing collections - before proceeding to execute the given operations. This flag is set to - true if the 'preCondition' option is provided." + description: "No longer supported, but kept here to improve the error message + returned to the client. In older versions, applyOps used to support + checking the documents of existing collections before proceeding to + execute the given operations." prepare: type: bool diff --git a/src/mongo/db/repl/apply_ops_command_info.cpp b/src/mongo/db/repl/apply_ops_command_info.cpp index 614d0e7c3c0..f8a78e9a555 100644 --- a/src/mongo/db/repl/apply_ops_command_info.cpp +++ b/src/mongo/db/repl/apply_ops_command_info.cpp @@ -96,14 +96,9 @@ ApplyOpsCommandInfo::ApplyOpsCommandInfo(const BSONObj& applyOpCmd) : _areOpsCrudOnly(_parseAreOpsCrudOnly(applyOpCmd)) { parseProtected(IDLParserContext("applyOps"), applyOpCmd); - if (getPreCondition()) { - uassert(ErrorCodes::InvalidOptions, - "Cannot use preCondition with {allowAtomic: false}", - getAllowAtomic()); - uassert(ErrorCodes::InvalidOptions, - "Cannot use preCondition when operations include commands.", - areOpsCrudOnly()); - } + uassert(6711600, + "applyOps command no longer supports the 'preCondition' option", + !getPreCondition()); } // static diff --git a/src/mongo/db/repl/apply_ops_command_info.h b/src/mongo/db/repl/apply_ops_command_info.h index 0773a25231a..d1c2a7648ac 100644 --- a/src/mongo/db/repl/apply_ops_command_info.h +++ b/src/mongo/db/repl/apply_ops_command_info.h @@ -43,7 +43,6 @@ class OperationContext; namespace repl { class ApplyOps { public: - static constexpr StringData kPreconditionFieldName = "preCondition"_sd; static constexpr StringData kOplogApplicationModeFieldName = "oplogApplicationMode"_sd; /** |