diff options
author | Kevin Pulo <kevin.pulo@mongodb.com> | 2019-09-26 19:53:04 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-09-26 19:53:04 +0000 |
commit | ae006f4586f21e294bdb14709d2610af681c592a (patch) | |
tree | bdeb6a9f7991cf9f779a9c4e7580a11ef98e4793 /src/mongo/db | |
parent | 68d5310c76cb589ad4ab1ea1775fa861277b0615 (diff) | |
download | mongo-ae006f4586f21e294bdb14709d2610af681c592a.tar.gz |
SERVER-43120 SERVER-43121 SERVER-43122 ReadWriteConcernDefaults component, setDefaultRWConcern and getDefaultRWConcern commands, check RWC default suitability
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/SConscript | 13 | ||||
-rw-r--r-- | src/mongo/db/commands/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/commands/rwc_defaults_commands.cpp | 126 | ||||
-rw-r--r-- | src/mongo/db/commands/rwc_defaults_commands.idl | 54 | ||||
-rw-r--r-- | src/mongo/db/read_write_concern_defaults.cpp | 158 | ||||
-rw-r--r-- | src/mongo/db/read_write_concern_defaults.h | 102 | ||||
-rw-r--r-- | src/mongo/db/repl/read_concern_args.cpp | 33 | ||||
-rw-r--r-- | src/mongo/db/repl/read_concern_args.h | 23 | ||||
-rw-r--r-- | src/mongo/db/repl/read_concern_args.idl | 44 | ||||
-rw-r--r-- | src/mongo/db/rw_concern_default.idl | 61 | ||||
-rw-r--r-- | src/mongo/db/write_concern_options.cpp | 31 | ||||
-rw-r--r-- | src/mongo/db/write_concern_options.idl | 44 |
12 files changed, 658 insertions, 33 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 08aa289e870..3546d8ca650 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -59,6 +59,7 @@ env.Library( '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/index_names', '$BUILD_DIR/mongo/db/write_concern_options', + '$BUILD_DIR/mongo/db/read_write_concern_defaults', ] ) @@ -370,6 +371,18 @@ env.Library( ) env.Library( + target="read_write_concern_defaults", + source=[ + "read_write_concern_defaults.cpp", + env.Idlc('rw_concern_default.idl')[0], + ], + LIBDEPS=[ + 'write_concern_options', + 'repl/read_concern_args', + ], +) + +env.Library( target='service_context', source=[ 'baton.cpp', diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index c46add8de57..34ab19d0b46 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -142,9 +142,11 @@ env.Library( 'logical_session_server_status_section.cpp', 'mr_common.cpp', 'reap_logical_session_cache_now.cpp', + 'rwc_defaults_commands.cpp', 'traffic_recording_cmds.cpp', 'user_management_commands_common.cpp', env.Idlc('drop_connections.idl')[0], + env.Idlc('rwc_defaults_commands.idl')[0], ], LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/client/clientdriver_minimal', diff --git a/src/mongo/db/commands/rwc_defaults_commands.cpp b/src/mongo/db/commands/rwc_defaults_commands.cpp new file mode 100644 index 00000000000..d3b0a9d072d --- /dev/null +++ b/src/mongo/db/commands/rwc_defaults_commands.cpp @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2019-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/platform/basic.h" + +#include "mongo/db/commands.h" +#include "mongo/db/commands/rwc_defaults_commands_gen.h" +#include "mongo/db/read_write_concern_defaults.h" + +namespace mongo { +namespace { + +class SetDefaultRWConcernCommand : public TypedCommand<SetDefaultRWConcernCommand> { +public: + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kNever; + } + bool adminOnly() const override { + return true; + } + std::string help() const override { + return "set the current read/write concern defaults (cluster-wide)"; + } + +public: + using Request = SetDefaultRWConcern; + + class Invocation final : public InvocationBase { + public: + using InvocationBase::InvocationBase; + + auto typedRun(OperationContext* opCtx) { + auto rc = request().getDefaultReadConcern(); + auto wc = request().getDefaultWriteConcern(); + uassert(ErrorCodes::BadValue, + str::stream() << "At least one of the \"" + << SetDefaultRWConcern::kDefaultReadConcernFieldName << "\" or \"" + << SetDefaultRWConcern::kDefaultWriteConcernFieldName + << "\" fields must be present", + rc || wc); + + auto& rwcDefaults = ReadWriteConcernDefaults::get(opCtx->getServiceContext()); + return rwcDefaults.setConcerns(opCtx, rc, wc); + } + + private: + bool supportsWriteConcern() const override { + return true; + } + + void doCheckAuthorization(OperationContext*) const override { + // TODO: add and use privilege action + } + + NamespaceString ns() const override { + return NamespaceString(request().getDbName(), ""); + } + }; +} setDefaultRWConcernCommand; + +class GetDefaultRWConcernCommand : public TypedCommand<GetDefaultRWConcernCommand> { +public: + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kAlways; + } + bool adminOnly() const override { + return true; + } + std::string help() const override { + return "get the current read/write concern defaults being applied by this node"; + } + +public: + using Request = GetDefaultRWConcern; + + class Invocation final : public InvocationBase { + public: + using InvocationBase::InvocationBase; + + auto typedRun(OperationContext* opCtx) { + auto& rwcDefaults = ReadWriteConcernDefaults::get(opCtx->getServiceContext()); + return rwcDefaults.getDefault(); + } + + private: + bool supportsWriteConcern() const override { + return false; + } + + void doCheckAuthorization(OperationContext*) const override { + // TODO: add and use privilege action + } + + NamespaceString ns() const override { + return NamespaceString(request().getDbName(), ""); + } + }; +} getDefaultRWConcernCommand; +} // namespace +} // namespace mongo diff --git a/src/mongo/db/commands/rwc_defaults_commands.idl b/src/mongo/db/commands/rwc_defaults_commands.idl new file mode 100644 index 00000000000..e4f2c2bb1b5 --- /dev/null +++ b/src/mongo/db/commands/rwc_defaults_commands.idl @@ -0,0 +1,54 @@ +# Copyright (C) 2019-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" + + +imports: + - "mongo/idl/basic_types.idl" + - "mongo/db/repl/read_concern_args.idl" + - "mongo/db/write_concern_options.idl" + + +commands: + setDefaultRWConcern: + description: "set the current read/write concern defaults (cluster-wide)" + namespace: ignored + fields: + defaultReadConcern: + description: "The new default read concern" + type: ReadConcern + optional: true + defaultWriteConcern: + description: "The new default write concern" + type: WriteConcern + optional: true + + getDefaultRWConcern: + description: "get the current read/write concern defaults being applied by this node" + namespace: ignored diff --git a/src/mongo/db/read_write_concern_defaults.cpp b/src/mongo/db/read_write_concern_defaults.cpp new file mode 100644 index 00000000000..828160e2e41 --- /dev/null +++ b/src/mongo/db/read_write_concern_defaults.cpp @@ -0,0 +1,158 @@ +/** + * Copyright (C) 2019-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/platform/basic.h" + +#include "mongo/db/read_write_concern_defaults.h" + +#include "mongo/db/logical_clock.h" + +namespace mongo { + +void ReadWriteConcernDefaults::checkSuitabilityAsDefault(const ReadConcern& rc) { + uassert(ErrorCodes::BadValue, + str::stream() << "level: '" << ReadConcern::kSnapshotReadConcernStr + << "' is not suitable for the default read concern", + rc.getLevel() != repl::ReadConcernLevel::kSnapshotReadConcern); + uassert(ErrorCodes::BadValue, + str::stream() << "level: '" << ReadConcern::kLinearizableReadConcernStr + << "' is not suitable for the default read concern", + rc.getLevel() != repl::ReadConcernLevel::kLinearizableReadConcern); + uassert(ErrorCodes::BadValue, + str::stream() << "'" << ReadConcern::kAfterOpTimeFieldName + << "' is not suitable for the default read concern", + !rc.getArgsOpTime()); + uassert(ErrorCodes::BadValue, + str::stream() << "'" << ReadConcern::kAfterClusterTimeFieldName + << "' is not suitable for the default read concern", + !rc.getArgsAfterClusterTime()); + uassert(ErrorCodes::BadValue, + str::stream() << "'" << ReadConcern::kAtClusterTimeFieldName + << "' is not suitable for the default read concern", + !rc.getArgsAtClusterTime()); +} + +void ReadWriteConcernDefaults::checkSuitabilityAsDefault(const WriteConcern& wc) { + uassert(ErrorCodes::BadValue, + "Unacknowledged write concern is not suitable for the default write concern", + !(wc.wMode.empty() && wc.wNumNodes < 1)); +} + +void ReadWriteConcernDefaults::_setDefault(WithLock, RWConcernDefault&& rwc) { + _defaults.erase(kReadWriteConcernEntry); + _defaults.emplace(kReadWriteConcernEntry, rwc); +} + +RWConcernDefault ReadWriteConcernDefaults::setConcerns(OperationContext* opCtx, + const boost::optional<ReadConcern>& rc, + const boost::optional<WriteConcern>& wc) { + invariant(rc || wc); + + if (rc) { + checkSuitabilityAsDefault(*rc); + } + if (wc) { + checkSuitabilityAsDefault(*wc); + } + + auto now = opCtx->getServiceContext()->getFastClockSource()->now(); + auto epoch = LogicalClock::get(opCtx->getServiceContext())->getClusterTime().asTimestamp(); + + RWConcernDefault rwc; + rwc.setDefaultReadConcern(rc); + rwc.setDefaultWriteConcern(wc); + rwc.setEpoch(epoch); + rwc.setSetTime(now); + rwc.setLocalSetTime(now); + + stdx::lock_guard<Latch> lk(_mutex); + + auto current = _getDefault(lk); + if (!rc && current) { + rwc.setDefaultReadConcern(current->getDefaultReadConcern()); + } + if (!wc && current) { + rwc.setDefaultWriteConcern(current->getDefaultWriteConcern()); + } + _setDefault(lk, std::move(rwc)); + return *_getDefault(lk); +} + +void ReadWriteConcernDefaults::invalidate() { + stdx::lock_guard<Latch> lk(_mutex); + _defaults.erase(kReadWriteConcernEntry); +} + +boost::optional<RWConcernDefault> ReadWriteConcernDefaults::_getDefault(WithLock) const { + if (_defaults.find(kReadWriteConcernEntry) == _defaults.end()) { + return boost::none; + } + return _defaults.at(kReadWriteConcernEntry); +} + +RWConcernDefault ReadWriteConcernDefaults::getDefault() const { + auto current = ([&]() { + stdx::lock_guard<Latch> lk(_mutex); + return _getDefault(lk); + })(); + if (!current) { + return RWConcernDefault{}; + } + return *current; +} + +boost::optional<ReadWriteConcernDefaults::ReadConcern> +ReadWriteConcernDefaults::getDefaultReadConcern() const { + auto current = getDefault(); + return current.getDefaultReadConcern(); +} + +boost::optional<ReadWriteConcernDefaults::WriteConcern> +ReadWriteConcernDefaults::getDefaultWriteConcern() const { + auto current = getDefault(); + return current.getDefaultWriteConcern(); +} + + +namespace { + +const auto getReadWriteConcernDefaults = + ServiceContext::declareDecoration<ReadWriteConcernDefaults>(); + +} // namespace + +ReadWriteConcernDefaults& ReadWriteConcernDefaults::get(ServiceContext* service) { + return getReadWriteConcernDefaults(service); +} + +ReadWriteConcernDefaults& ReadWriteConcernDefaults::get(ServiceContext& service) { + return getReadWriteConcernDefaults(service); +} + +} // namespace mongo diff --git a/src/mongo/db/read_write_concern_defaults.h b/src/mongo/db/read_write_concern_defaults.h new file mode 100644 index 00000000000..f7ce2f9bfee --- /dev/null +++ b/src/mongo/db/read_write_concern_defaults.h @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2019-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 <map> + +#include "mongo/db/operation_context.h" +#include "mongo/db/repl/read_concern_args.h" +#include "mongo/db/rw_concern_default_gen.h" +#include "mongo/db/service_context.h" +#include "mongo/db/write_concern_options.h" +#include "mongo/platform/mutex.h" +#include "mongo/util/concurrency/with_lock.h" + +namespace mongo { + +/** + * Class to manage Read Concern and Write Concern (RWC) defaults. + */ +class ReadWriteConcernDefaults { +public: + /** + * Consistent names for the classes that define a ReadConcern and a WriteConcern. + */ + using ReadConcern = repl::ReadConcernArgs; + using WriteConcern = WriteConcernOptions; + + static constexpr StringData readConcernFieldName = ReadConcern::kReadConcernFieldName; + static constexpr StringData writeConcernFieldName = WriteConcern::kWriteConcernField; + + static ReadWriteConcernDefaults& get(ServiceContext* service); + static ReadWriteConcernDefaults& get(ServiceContext& service); + + ReadWriteConcernDefaults() = default; + ~ReadWriteConcernDefaults() = default; + + static void checkSuitabilityAsDefault(const ReadConcern& rc); + static void checkSuitabilityAsDefault(const WriteConcern& wc); + + /** + * Interface when an admin has run the command to change the defaults. + * At least one of the `rc` or `wc` params must be set. + * Will generate and use a new epoch and setTime for the updated defaults, which are returned. + */ + RWConcernDefault setConcerns(OperationContext* opCtx, + const boost::optional<ReadConcern>& rc, + const boost::optional<WriteConcern>& wc); + + /** + * Invalidates the cached RWC defaults, causing them to be refreshed. + * + * After this call returns, the read methods below (getDefault, getDefaultReadConcern, + * getDefaultWriteConcern) may continue returning the invalidated defaults, until they have been + * replaced by the refreshed values. This is to avoid stalling CRUD ops (and other ops that + * need RC/WC) during refresh. + */ + void invalidate(); + + RWConcernDefault getDefault() const; + boost::optional<ReadConcern> getDefaultReadConcern() const; + boost::optional<WriteConcern> getDefaultWriteConcern() const; + +private: + enum Type { kReadWriteConcernEntry }; + + void _setDefault(WithLock, RWConcernDefault&& rwc); + boost::optional<RWConcernDefault> _getDefault(WithLock) const; + + // Protects access to the private members below. + mutable Mutex _mutex = MONGO_MAKE_LATCH("ReadWriteConcernDefaults::_mutex"); + + std::map<Type, RWConcernDefault> _defaults; +}; + +} // namespace mongo diff --git a/src/mongo/db/repl/read_concern_args.cpp b/src/mongo/db/repl/read_concern_args.cpp index bb060b5a4dc..772ceeb76da 100644 --- a/src/mongo/db/repl/read_concern_args.cpp +++ b/src/mongo/db/repl/read_concern_args.cpp @@ -45,23 +45,6 @@ using std::string; namespace mongo { namespace repl { -namespace { - -constexpr StringData kLocalReadConcernStr = "local"_sd; -constexpr StringData kMajorityReadConcernStr = "majority"_sd; -constexpr StringData kLinearizableReadConcernStr = "linearizable"_sd; -constexpr StringData kAvailableReadConcernStr = "available"_sd; -constexpr StringData kSnapshotReadConcernStr = "snapshot"_sd; - -} // unnamed namespace - -const string ReadConcernArgs::kReadConcernFieldName("readConcern"); -const string ReadConcernArgs::kAfterOpTimeFieldName("afterOpTime"); -const string ReadConcernArgs::kAfterClusterTimeFieldName("afterClusterTime"); -const string ReadConcernArgs::kAtClusterTimeFieldName("atClusterTime"); - -const string ReadConcernArgs::kLevelFieldName("level"); - const OperationContext::Decoration<ReadConcernArgs> handle = OperationContext::declareDecoration<ReadConcernArgs>(); @@ -122,8 +105,6 @@ boost::optional<LogicalTime> ReadConcernArgs::getArgsAtClusterTime() const { } Status ReadConcernArgs::initialize(const BSONElement& readConcernElem) { - invariant(isEmpty()); // only legal to call on uninitialized object. - if (readConcernElem.eoo()) { return Status::OK(); } @@ -135,7 +116,11 @@ Status ReadConcernArgs::initialize(const BSONElement& readConcernElem) { str::stream() << kReadConcernFieldName << " field should be an object"); } - BSONObj readConcernObj = readConcernElem.Obj(); + return parse(readConcernElem.Obj()); +} + +Status ReadConcernArgs::parse(const BSONObj& readConcernObj) { + invariant(isEmpty()); // only legal to call on uninitialized object. for (auto&& field : readConcernObj) { auto fieldName = field.fieldNameStringData(); if (fieldName == kAfterOpTimeFieldName) { @@ -248,6 +233,12 @@ Status ReadConcernArgs::initialize(const BSONElement& readConcernElem) { return Status::OK(); } +ReadConcernArgs ReadConcernArgs::fromBSONThrows(const BSONObj& readConcernObj) { + ReadConcernArgs rc; + uassertStatusOK(rc.parse(readConcernObj)); + return rc; +} + void ReadConcernArgs::setMajorityReadMechanism(MajorityReadMechanism mechanism) { invariant(*_level == ReadConcernLevel::kMajorityReadConcern); _majorityReadMechanism = mechanism; @@ -297,7 +288,7 @@ void ReadConcernArgs::appendInfo(BSONObjBuilder* builder) const { } if (_opTime) { - _opTime->append(&rcBuilder, kAfterOpTimeFieldName); + _opTime->append(&rcBuilder, kAfterOpTimeFieldName.toString()); } if (_afterClusterTime) { diff --git a/src/mongo/db/repl/read_concern_args.h b/src/mongo/db/repl/read_concern_args.h index 775877f9b34..310cfc59432 100644 --- a/src/mongo/db/repl/read_concern_args.h +++ b/src/mongo/db/repl/read_concern_args.h @@ -48,11 +48,17 @@ namespace repl { class ReadConcernArgs { public: - static const std::string kReadConcernFieldName; - static const std::string kAfterOpTimeFieldName; - static const std::string kAfterClusterTimeFieldName; - static const std::string kAtClusterTimeFieldName; - static const std::string kLevelFieldName; + static constexpr StringData kReadConcernFieldName = "readConcern"_sd; + static constexpr StringData kAfterOpTimeFieldName = "afterOpTime"_sd; + static constexpr StringData kAfterClusterTimeFieldName = "afterClusterTime"_sd; + static constexpr StringData kAtClusterTimeFieldName = "atClusterTime"_sd; + static constexpr StringData kLevelFieldName = "level"_sd; + + static constexpr StringData kLocalReadConcernStr = "local"_sd; + static constexpr StringData kMajorityReadConcernStr = "majority"_sd; + static constexpr StringData kLinearizableReadConcernStr = "linearizable"_sd; + static constexpr StringData kAvailableReadConcernStr = "available"_sd; + static constexpr StringData kSnapshotReadConcernStr = "snapshot"_sd; /** * Represents the internal mechanism an operation uses to satisfy 'majority' read concern. @@ -104,6 +110,13 @@ public: Status initialize(const BSONElement& readConcernElem); /** + * Initializes the object by parsing the actual readConcern sub-object. + */ + Status parse(const BSONObj& readConcernObj); + + static ReadConcernArgs fromBSONThrows(const BSONObj& readConcernObj); + + /** * Sets the mechanism we should use to satisfy 'majority' reads. * * Invalid to call unless the read concern level is 'kMajorityReadConcern'. diff --git a/src/mongo/db/repl/read_concern_args.idl b/src/mongo/db/repl/read_concern_args.idl new file mode 100644 index 00000000000..1954f6dddf2 --- /dev/null +++ b/src/mongo/db/repl/read_concern_args.idl @@ -0,0 +1,44 @@ +# Copyright (C) 2019-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/db/repl/read_concern_args.h" + + +imports: + - "mongo/idl/basic_types.idl" + + +types: + ReadConcern: + description: "An object representing a read concern." + bson_serialization_type: object + cpp_type: "mongo::repl::ReadConcernArgs" + serializer: "mongo::repl::ReadConcernArgs::toBSON" + deserializer: "mongo::repl::ReadConcernArgs::fromBSONThrows" diff --git a/src/mongo/db/rw_concern_default.idl b/src/mongo/db/rw_concern_default.idl new file mode 100644 index 00000000000..396c12264c1 --- /dev/null +++ b/src/mongo/db/rw_concern_default.idl @@ -0,0 +1,61 @@ +# Copyright (C) 2019-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" + + +imports: + - "mongo/idl/basic_types.idl" + - "mongo/db/repl/read_concern_args.idl" + - "mongo/db/write_concern_options.idl" + + +structs: + RWConcernDefault: + description: "Represents a set of read/write concern defaults, and associated metadata" + fields: + defaultReadConcern: + description: "The default read concern" + type: ReadConcern + optional: true + defaultWriteConcern: + description: "The default write concern" + type: WriteConcern + optional: true + epoch: + description: "The epoch (unique generation id) of when the default read or write concern was last set" + type: timestamp + optional: true + setTime: + description: "The wallclock time when the default read or write concern was last set by an administrator" + type: date + optional: true + localSetTime: + description: "The wallclock time when this node updated its understanding of the default read or write concern" + type: date + optional: true diff --git a/src/mongo/db/write_concern_options.cpp b/src/mongo/db/write_concern_options.cpp index 055fa23a5ee..d92dbfed25c 100644 --- a/src/mongo/db/write_concern_options.cpp +++ b/src/mongo/db/write_concern_options.cpp @@ -159,20 +159,37 @@ Status WriteConcernOptions::parse(const BSONObj& obj) { return Status::OK(); } -WriteConcernOptions WriteConcernOptions::deserializerForIDL(const BSONObj& obj) { - WriteConcernOptions writeConcernOptions; - uassertStatusOK(writeConcernOptions.parse(obj)); - return writeConcernOptions; -} +namespace { -StatusWith<WriteConcernOptions> WriteConcernOptions::extractWCFromCommand( - const BSONObj& cmdObj, const WriteConcernOptions& defaultWC) { +/** + * Construct a WriteConcernOptions based on an optional default WC object, in preparation for + * parsing out of a command object or IDL. + */ +WriteConcernOptions constructWCFromDefault( + const WriteConcernOptions& defaultWC = WriteConcernOptions()) { WriteConcernOptions writeConcern = defaultWC; writeConcern.usedDefault = true; writeConcern.usedDefaultW = true; if (writeConcern.wNumNodes == 0 && writeConcern.wMode.empty()) { writeConcern.wNumNodes = 1; } + return writeConcern; +} + +} // namespace + + +WriteConcernOptions WriteConcernOptions::deserializerForIDL(const BSONObj& obj) { + WriteConcernOptions writeConcern = constructWCFromDefault(); + if (!obj.isEmpty()) { + uassertStatusOK(writeConcern.parse(obj)); + } + return writeConcern; +} + +StatusWith<WriteConcernOptions> WriteConcernOptions::extractWCFromCommand( + const BSONObj& cmdObj, const WriteConcernOptions& defaultWC) { + WriteConcernOptions writeConcern = constructWCFromDefault(defaultWC); // Return the default write concern if no write concern is provided. We check for the existence // of the write concern field up front in order to avoid the expense of constructing an error diff --git a/src/mongo/db/write_concern_options.idl b/src/mongo/db/write_concern_options.idl new file mode 100644 index 00000000000..07c3cdbffc4 --- /dev/null +++ b/src/mongo/db/write_concern_options.idl @@ -0,0 +1,44 @@ +# Copyright (C) 2019-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/db/write_concern_options.h" + + +imports: + - "mongo/idl/basic_types.idl" + + +types: + WriteConcern: + description: "An object representing a write concern." + bson_serialization_type: object + cpp_type: "mongo::WriteConcernOptions" + serializer: "mongo::WriteConcernOptions::toBSON" + deserializer: "mongo::WriteConcernOptions::deserializerForIDL" |