diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2015-05-19 22:30:54 -0400 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2015-05-21 13:30:12 -0400 |
commit | 70c7cba06315b14a92a4d46bf2244b990cda902b (patch) | |
tree | a012c25e07007518c0a0cfb9d1d3f1e7e1d163e7 /src/mongo/client/connection_string.cpp | |
parent | 87509640447fd785e0fbeb33c7fa87cf824f4c5f (diff) | |
download | mongo-70c7cba06315b14a92a4d46bf2244b990cda902b.tar.gz |
SERVER-18567 Implement ConnectionString::parse which returns StatusWith
Diffstat (limited to 'src/mongo/client/connection_string.cpp')
-rw-r--r-- | src/mongo/client/connection_string.cpp | 148 |
1 files changed, 112 insertions, 36 deletions
diff --git a/src/mongo/client/connection_string.cpp b/src/mongo/client/connection_string.cpp index d365a6fb50f..08c601b1e9f 100644 --- a/src/mongo/client/connection_string.cpp +++ b/src/mongo/client/connection_string.cpp @@ -1,4 +1,5 @@ -/* Copyright 2009 10gen Inc. +/** + * Copyright (C) 2009-2015 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, @@ -16,13 +17,13 @@ * 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. + * 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::kNetwork @@ -31,10 +32,55 @@ #include "mongo/client/connection_string.h" +#include "mongo/base/status_with.h" #include "mongo/util/mongoutils/str.h" namespace mongo { + ConnectionString::ConnectionString(const HostAndPort& server) : _type(MASTER) { + _servers.push_back(server); + _finishInit(); + } + + ConnectionString::ConnectionString(ConnectionType type, + const std::string& s, + const std::string& setName) { + _type = type; + _setName = setName; + _fillServers(s); + + switch (_type) { + case MASTER: + verify(_servers.size() == 1); + break; + case SET: + verify(_setName.size()); + verify(_servers.size() >= 1); // 1 is ok since we can derive + break; + default: + verify(_servers.size() > 0); + } + + _finishInit(); + } + + ConnectionString::ConnectionString(const std::string& s, ConnectionType favoredMultipleType) { + _fillServers(s); + + if (_type != INVALID) { + // set already + } + else if (_servers.size() == 1) { + _type = MASTER; + } + else { + _type = favoredMultipleType; + verify(_type == SET || _type == SYNC); + } + + _finishInit(); + } + void ConnectionString::_fillServers( std::string s ) { // @@ -64,31 +110,37 @@ namespace mongo { } void ConnectionString::_finishInit() { - // Needed here as well b/c the parsing logic isn't used in all constructors // TODO: Refactor so that the parsing logic *is* used in all constructors - if ( _type == MASTER && _servers.size() > 0 ){ - if( _servers[0].host().find( '$' ) == 0 ){ + if (_type == MASTER && _servers.size() > 0) { + if (_servers[0].host().find('$') == 0) { _type = CUSTOM; } } std::stringstream ss; - if ( _type == SET ) + + if (_type == SET) { ss << _setName << "/"; - for ( unsigned i=0; i<_servers.size(); i++ ) { - if ( i > 0 ) + } + + for (unsigned i = 0; i < _servers.size(); i++) { + if (i > 0) { ss << ","; + } + ss << _servers[i].toString(); } + _string = ss.str(); } - bool ConnectionString::sameLogicalEndpoint( const ConnectionString& other ) const { - if ( _type != other._type ) + bool ConnectionString::sameLogicalEndpoint(const ConnectionString& other) const { + if (_type != other._type) { return false; + } - switch ( _type ) { + switch (_type) { case INVALID: return true; case MASTER: @@ -97,44 +149,68 @@ namespace mongo { return _setName == other._setName; case SYNC: // The servers all have to be the same in each, but not in the same order. - if ( _servers.size() != other._servers.size() ) + if (_servers.size() != other._servers.size()) { return false; - for ( unsigned i = 0; i < _servers.size(); i++ ) { + } + + for (unsigned i = 0; i < _servers.size(); i++) { bool found = false; - for ( unsigned j = 0; j < other._servers.size(); j++ ) { - if ( _servers[i] == other._servers[j] ) { + for (unsigned j = 0; j < other._servers.size(); j++) { + if (_servers[i] == other._servers[j]) { found = true; break; } } - if ( ! found ) - return false; + + if (!found) return false; } + return true; case CUSTOM: return _string == other._string; } - verify( false ); + + MONGO_UNREACHABLE; + } + + ConnectionString ConnectionString::parse(const std::string& url, std::string& errmsg) { + auto status = parse(url); + if (status.isOK()) { + errmsg = ""; + return status.getValue(); + } + + errmsg = status.getStatus().toString(); + return ConnectionString(); } - ConnectionString ConnectionString::parse( const std::string& host , std::string& errmsg ) { + StatusWith<ConnectionString> ConnectionString::parse(const std::string& url) { + const std::string::size_type i = url.find('/'); - std::string::size_type i = host.find( '/' ); - if ( i != std::string::npos && i != 0) { - // replica set - return ConnectionString( SET , host.substr( i + 1 ) , host.substr( 0 , i ) ); + // Replica set + if (i != std::string::npos && i != 0) { + return ConnectionString(SET, url.substr(i + 1), url.substr(0, i)); } - int numCommas = str::count( host , ',' ); + const int numCommas = str::count(url, ','); - if( numCommas == 0 ) - return ConnectionString( HostAndPort( host ) ); + // Single host + if (numCommas == 0) { + HostAndPort singleHost; + Status status = singleHost.initialize(url); + if (!status.isOK()) { + return status; + } + + return ConnectionString(singleHost); + } - if ( numCommas == 2 ) - return ConnectionString( SYNC , host ); + // Sharding config server + if (numCommas == 2) { + return ConnectionString(SYNC, url, ""); + } - errmsg = (std::string)"invalid hostname [" + host + "]"; - return ConnectionString(); // INVALID + return Status(ErrorCodes::FailedToParse, str::stream() << "invalid url [" << url << "]"); } std::string ConnectionString::typeToString(ConnectionType type) { |