diff options
author | Henrik Edin <henrik.edin@mongodb.com> | 2018-04-10 16:20:53 -0400 |
---|---|---|
committer | Henrik Edin <henrik.edin@mongodb.com> | 2018-04-18 08:34:36 -0400 |
commit | da019f4197df2abfec336c5063e674980307ff93 (patch) | |
tree | 70d5504a95ea51710a92fe3cb210f6866fe4ae04 /src/mongo/client/embedded | |
parent | 980e650068c23c762c3662216277fad576a7e7f4 (diff) | |
download | mongo-da019f4197df2abfec336c5063e674980307ff93.tar.gz |
SERVER-29725 mongoe application
Embedded MongoDB in a standalone application. To be able to connect with the shell and perform testing on embedded.
Diffstat (limited to 'src/mongo/client/embedded')
-rw-r--r-- | src/mongo/client/embedded/SConscript | 28 | ||||
-rw-r--r-- | src/mongo/client/embedded/embedded.cpp | 5 | ||||
-rw-r--r-- | src/mongo/client/embedded/mongoe_main.cpp | 136 | ||||
-rw-r--r-- | src/mongo/client/embedded/replication_coordinator_embedded.cpp | 2 |
4 files changed, 170 insertions, 1 deletions
diff --git a/src/mongo/client/embedded/SConscript b/src/mongo/client/embedded/SConscript index 1130e37cdc6..3025372251d 100644 --- a/src/mongo/client/embedded/SConscript +++ b/src/mongo/client/embedded/SConscript @@ -109,8 +109,10 @@ env.Library( '$BUILD_DIR/mongo/db/commands/mongod_fcv', '$BUILD_DIR/mongo/db/op_observer_d', '$BUILD_DIR/mongo/db/repair_database_and_check_version', + '$BUILD_DIR/mongo/db/repl/repl_set_status_commands', '$BUILD_DIR/mongo/db/repl/storage_interface_impl', '$BUILD_DIR/mongo/db/storage/mobile/storage_mobile', + '$BUILD_DIR/mongo/db/storage/storage_init_d', '$BUILD_DIR/mongo/util/version_impl', 'embedded_commands', 'embedded_options', @@ -171,6 +173,32 @@ capiTest = capiTestEnv.Program( env.RegisterUnitTest(capiTest[0]) env.Alias('embedded_capi', capiTest) +mongoe_env = env.Clone() +mongoe_env.InjectThirdPartyIncludePaths(libraries=['yaml']) +mongoe = mongoe_env.Program( + target='mongoe', + source=[ + 'mongoe_main.cpp', + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/db/commands/shell_protocol', + '$BUILD_DIR/mongo/db/mongod_options', + '$BUILD_DIR/mongo/db/server_options', + '$BUILD_DIR/mongo/transport/transport_layer_manager', + '$BUILD_DIR/mongo/util/signal_handlers', + 'embedded', + ], + INSTALL_ALIAS=[ + 'mobile-test', + ], +) + +hygienic = get_option('install-mode') == 'hygienic' + +if not hygienic: + env.Install('#/', mongoe) + + if not env['MONGO_HAVE_LIBMONGOC']: Return() diff --git a/src/mongo/client/embedded/embedded.cpp b/src/mongo/client/embedded/embedded.cpp index 328217bd157..9f99b33d253 100644 --- a/src/mongo/client/embedded/embedded.cpp +++ b/src/mongo/client/embedded/embedded.cpp @@ -49,6 +49,7 @@ #include "mongo/db/global_settings.h" #include "mongo/db/index_rebuilder.h" #include "mongo/db/kill_sessions_local.h" +#include "mongo/db/logical_clock.h" #include "mongo/db/op_observer_impl.h" #include "mongo/db/op_observer_registry.h" #include "mongo/db/repair_database_and_check_version.h" @@ -104,6 +105,9 @@ GlobalInitializerRegisterer replicationManagerInitializer( auto serviceContext = context->serviceContext(); repl::StorageInterface::set(serviceContext, std::make_unique<repl::StorageInterfaceImpl>()); + auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext); + LogicalClock::set(serviceContext, std::move(logicalClock)); + auto replCoord = std::make_unique<ReplicationCoordinatorEmbedded>(serviceContext); repl::ReplicationCoordinator::set(serviceContext, std::move(replCoord)); repl::setOplogCollectionName(serviceContext); @@ -113,6 +117,7 @@ GlobalInitializerRegisterer replicationManagerInitializer( auto serviceContext = context->serviceContext(); repl::ReplicationCoordinator::set(serviceContext, nullptr); + LogicalClock::set(serviceContext, nullptr); repl::StorageInterface::set(serviceContext, nullptr); return Status::OK(); diff --git a/src/mongo/client/embedded/mongoe_main.cpp b/src/mongo/client/embedded/mongoe_main.cpp new file mode 100644 index 00000000000..3a7bcd9ec38 --- /dev/null +++ b/src/mongo/client/embedded/mongoe_main.cpp @@ -0,0 +1,136 @@ +/** +* Copyright (C) 2018 MongoDB Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* 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 +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* 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 GNU Affero General 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. +*/ + +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault + +#include "mongo/platform/basic.h" + +#include "mongo/base/init.h" +#include "mongo/client/embedded/embedded.h" +#include "mongo/db/mongod_options.h" +#include "mongo/db/service_context.h" +#include "mongo/transport/transport_layer.h" +#include "mongo/transport/transport_layer_manager.h" +#include "mongo/util/exit.h" +#include "mongo/util/log.h" +#include "mongo/util/options_parser/options_parser.h" +#include "mongo/util/options_parser/startup_options.h" +#include "mongo/util/signal_handlers.h" +#include "mongo/util/text.h" + +#include <yaml-cpp/yaml.h> + +namespace mongo { +namespace { + +MONGO_INITIALIZER_WITH_PREREQUISITES(SignalProcessingStartup, ("ThreadNameInitializer")) +(InitializerContext*) { + // Make sure we call this as soon as possible but before any other threads are started. Before + // embedded::initialize is too early and after is too late. So instead we hook in during the + // global initialization at the right place. + startSignalProcessingThread(); + return Status::OK(); +} + +int mongoeMain(int argc, char* argv[], char** envp) { + ServiceContext* serviceContext = nullptr; + + registerShutdownTask([&]() { + if (!serviceContext) + return; + + if (auto tl = serviceContext->getTransportLayer()) { + log(logger::LogComponent::kNetwork) << "shutdown: going to close listening sockets..."; + tl->shutdown(); + } + + embedded::shutdown(serviceContext); + }); + + setupSignalHandlers(); + + log() << "MongoDB embedded standalone application, for testing purposes only"; + + try { + optionenvironment::OptionSection startupOptions("Options"); + uassertStatusOK(addMongodOptions(&startupOptions)); + + // Manually run the code that's equivalent to the MONGO_INITIALIZERs for mongod. We can't do + // this in initializers because embedded uses a different options format. However as long as + // we store the options in the same place it will be valid for embedded too. Adding all + // options mongod we don't have to maintain a separate set for this executable, some will be + // unused but that's fine as this is just an executable for testing purposes anyway. + std::vector<std::string> args; + std::map<std::string, std::string> env; + + args.reserve(argc); + std::copy(argv, argv + argc, std::back_inserter(args)); + + optionenvironment::OptionsParser parser; + uassertStatusOK( + parser.run(startupOptions, args, env, &optionenvironment::startupOptionsParsed)); + uassertStatusOK(storeMongodOptions(optionenvironment::startupOptionsParsed)); + + // Add embedded specific options that's not available in mongod here. + YAML::Emitter yaml; + serviceContext = embedded::initialize(yaml.c_str()); + + auto tl = + transport::TransportLayerManager::createWithConfig(&serverGlobalParams, serviceContext); + uassertStatusOK(tl->setup()); + + serviceContext->setTransportLayer(std::move(tl)); + + uassertStatusOK(serviceContext->getServiceExecutor()->start()); + uassertStatusOK(serviceContext->getTransportLayer()->start()); + } catch (const std::exception& ex) { + error() << ex.what(); + return EXIT_BADOPTIONS; + } + + return waitForShutdown(); +} + +} // namespace +} // namespace mongo + +#if defined(_WIN32) +// In Windows, wmain() is an alternate entry point for main(), and receives the same parameters +// as main() but encoded in Windows Unicode (UTF-16); "wide" 16-bit wchar_t characters. The +// WindowsCommandLine object converts these wide character strings to a UTF-8 coded equivalent +// and makes them available through the argv() and envp() members. This enables mongoDbMain() +// to process UTF-8 encoded arguments and environment variables without regard to platform. +int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) { + mongo::WindowsCommandLine wcl(argc, argvW, envpW); + return mongo::mongoeMain(argc, wcl.argv(), wcl.envp()); +} +#else +int main(int argc, char* argv[], char** envp) { + return mongo::mongoeMain(argc, argv, envp); +} +#endif diff --git a/src/mongo/client/embedded/replication_coordinator_embedded.cpp b/src/mongo/client/embedded/replication_coordinator_embedded.cpp index e0dfc14ce22..85d272a6bb7 100644 --- a/src/mongo/client/embedded/replication_coordinator_embedded.cpp +++ b/src/mongo/client/embedded/replication_coordinator_embedded.cpp @@ -346,7 +346,7 @@ Status ReplicationCoordinatorEmbedded::checkIfWriteConcernCanBeSatisfied( } Status ReplicationCoordinatorEmbedded::checkReplEnabledForCommand(BSONObjBuilder*) { - UASSERT_NOT_IMPLEMENTED; + return Status(ErrorCodes::NoReplicationEnabled, "no replication on embedded"); } HostAndPort ReplicationCoordinatorEmbedded::chooseNewSyncSource(const OpTime&) { |