mirror of
https://github.com/pocoproject/poco.git
synced 2025-12-09 16:36:51 +01:00
enh(MongoDB): Add parsing of mongodb replica set URI.
This commit is contained in:
@@ -116,8 +116,18 @@ public:
|
||||
explicit ReplicaSet(const std::string& uri);
|
||||
/// Creates a ReplicaSet from a MongoDB URI.
|
||||
/// Format: mongodb://host1:port1,host2:port2,...?options
|
||||
///
|
||||
/// Supported URI options:
|
||||
/// - replicaSet=name - Replica set name
|
||||
/// - readPreference=mode - primary|primaryPreferred|secondary|secondaryPreferred|nearest
|
||||
/// - connectTimeoutMS=ms - Connection timeout in milliseconds
|
||||
/// - socketTimeoutMS=ms - Socket timeout in milliseconds
|
||||
/// - heartbeatFrequencyMS=ms - Heartbeat frequency in milliseconds
|
||||
///
|
||||
/// Example: mongodb://mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0&readPreference=primaryPreferred
|
||||
///
|
||||
/// Throws Poco::SyntaxException if URI is invalid.
|
||||
/// NOTE: This is a placeholder for future URI support.
|
||||
/// Throws Poco::UnknownURISchemeException if scheme is not "mongodb".
|
||||
|
||||
virtual ~ReplicaSet();
|
||||
/// Destroys the ReplicaSet and stops background monitoring.
|
||||
@@ -186,7 +196,8 @@ private:
|
||||
/// Queries all known servers and updates topology.
|
||||
|
||||
void parseURI(const std::string& uri);
|
||||
/// Parses a MongoDB URI into configuration (future implementation).
|
||||
/// Parses a MongoDB URI into configuration.
|
||||
/// Extracts hosts and query parameters into _config.
|
||||
|
||||
Config _config;
|
||||
TopologyDescription _topology;
|
||||
|
||||
@@ -9,3 +9,9 @@ set(MONITOR_NAME "ReplicaSetMonitor")
|
||||
set(MONITOR_SRCS src/ReplicaSetMonitor.cpp)
|
||||
add_executable(${MONITOR_NAME} ${MONITOR_SRCS})
|
||||
target_link_libraries(${MONITOR_NAME} Poco::MongoDB Poco::Net Poco::Foundation)
|
||||
|
||||
# URIExample sample - demonstrates URI parsing
|
||||
set(URI_NAME "URIExample")
|
||||
set(URI_SRCS src/URIExample.cpp)
|
||||
add_executable(${URI_NAME} ${URI_SRCS})
|
||||
target_link_libraries(${URI_NAME} Poco::MongoDB Poco::Net Poco::Foundation)
|
||||
|
||||
@@ -20,7 +20,10 @@ A continuous monitoring tool that performs regular read/write operations and dis
|
||||
# Basic usage with defaults
|
||||
./ReplicaSetMonitor
|
||||
|
||||
# Specify replica set and hosts
|
||||
# Using MongoDB URI (recommended)
|
||||
./ReplicaSetMonitor -u 'mongodb://mongo1:27017,mongo2:27017/?replicaSet=rs0'
|
||||
|
||||
# Specify replica set and hosts (traditional method)
|
||||
./ReplicaSetMonitor -s rs0 -H mongo1:27017,mongo2:27017,mongo3:27017
|
||||
|
||||
# Run with 10-second intervals for 100 iterations
|
||||
@@ -29,7 +32,15 @@ A continuous monitoring tool that performs regular read/write operations and dis
|
||||
# Verbose mode for detailed operation output
|
||||
./ReplicaSetMonitor -v
|
||||
|
||||
# Full example
|
||||
# Full example with URI
|
||||
./ReplicaSetMonitor \
|
||||
--uri 'mongodb://mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0&readPreference=primaryPreferred' \
|
||||
--interval 5 \
|
||||
--database test \
|
||||
--collection health_check \
|
||||
--verbose
|
||||
|
||||
# Full example with traditional options
|
||||
./ReplicaSetMonitor \
|
||||
--set rs0 \
|
||||
--hosts mongo1:27017,mongo2:27017,mongo3:27017 \
|
||||
@@ -44,6 +55,7 @@ A continuous monitoring tool that performs regular read/write operations and dis
|
||||
| Option | Description | Default |
|
||||
|--------|-------------|---------|
|
||||
| `-h, --help` | Show help message | - |
|
||||
| `-u, --uri URI` | MongoDB connection URI (takes precedence) | - |
|
||||
| `-s, --set NAME` | Replica set name | `rs0` |
|
||||
| `-H, --hosts HOSTS` | Comma-separated host:port list | `localhost:27017,localhost:27018,localhost:27019` |
|
||||
| `-i, --interval SECONDS` | Check interval in seconds | `5` |
|
||||
@@ -52,8 +64,11 @@ A continuous monitoring tool that performs regular read/write operations and dis
|
||||
| `-v, --verbose` | Verbose output | `false` |
|
||||
| `-n, --iterations N` | Number of iterations | unlimited |
|
||||
|
||||
**Note:** The `--uri` option takes precedence over `--set` and `--hosts` options.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
- `MONGODB_URI`: MongoDB connection URI (takes precedence)
|
||||
- `MONGODB_REPLICA_SET`: Replica set name
|
||||
- `MONGODB_HOSTS`: Comma-separated host:port list
|
||||
|
||||
@@ -228,6 +243,84 @@ Demonstrates various replica set features with multiple commands.
|
||||
|
||||
---
|
||||
|
||||
## URIExample - URI Parsing Demonstration
|
||||
|
||||
Demonstrates MongoDB URI parsing and connection to replica sets.
|
||||
|
||||
### Features
|
||||
|
||||
- Parse MongoDB connection URIs
|
||||
- Display parsed configuration (hosts, replica set name, read preference, timeouts)
|
||||
- Connect to replica set and show topology
|
||||
- Query server information
|
||||
- Validate URI format
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
./URIExample <uri>
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Basic replica set URI
|
||||
./URIExample 'mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0'
|
||||
|
||||
# With read preference
|
||||
./URIExample 'mongodb://mongo1:27017,mongo2:27017/?replicaSet=rs0&readPreference=primaryPreferred'
|
||||
|
||||
# With custom timeouts and heartbeat
|
||||
./URIExample 'mongodb://host1:27017,host2:27017/?replicaSet=rs0&connectTimeoutMS=5000&socketTimeoutMS=30000&heartbeatFrequencyMS=5000'
|
||||
```
|
||||
|
||||
### Supported URI Options
|
||||
|
||||
- `replicaSet=name` - Replica set name
|
||||
- `readPreference=mode` - Read preference (primary|primaryPreferred|secondary|secondaryPreferred|nearest)
|
||||
- `connectTimeoutMS=ms` - Connection timeout in milliseconds
|
||||
- `socketTimeoutMS=ms` - Socket timeout in milliseconds
|
||||
- `heartbeatFrequencyMS=ms` - Heartbeat frequency in milliseconds
|
||||
|
||||
### Example Output
|
||||
|
||||
```
|
||||
Parsing MongoDB Replica Set URI
|
||||
================================================================================
|
||||
URI: mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0
|
||||
|
||||
✓ URI parsed successfully!
|
||||
|
||||
Configuration:
|
||||
--------------------------------------------------------------------------------
|
||||
Replica Set Name: rs0
|
||||
Read Preference: primary
|
||||
Seed Servers: localhost:27017, localhost:27018, localhost:27019
|
||||
Monitoring: Active
|
||||
|
||||
Connecting to replica set...
|
||||
✓ Connected to primary: localhost:27017
|
||||
|
||||
Server Information:
|
||||
--------------------------------------------------------------------------------
|
||||
MongoDB Version: 7.0.5
|
||||
Git Version: 7809d71e84e314b497f282ea52598668b08b84dd
|
||||
|
||||
Replica Set Topology:
|
||||
--------------------------------------------------------------------------------
|
||||
Set Name: rs0
|
||||
Has Primary: Yes
|
||||
Servers: 3
|
||||
|
||||
localhost:27017 [PRIMARY] RTT: 2.34 ms
|
||||
localhost:27018 [SECONDARY] RTT: 3.12 ms
|
||||
localhost:27019 [SECONDARY] RTT: 2.89 ms
|
||||
|
||||
✓ Success!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Building the Examples
|
||||
|
||||
### With CMake
|
||||
@@ -238,10 +331,12 @@ mkdir build && cd build
|
||||
cmake .. -DENABLE_MONGODB=ON -DENABLE_SAMPLES=ON
|
||||
cmake --build . --target ReplicaSetMonitor
|
||||
cmake --build . --target ReplicaSet
|
||||
cmake --build . --target URIExample
|
||||
|
||||
# Executables are in bin/
|
||||
./bin/ReplicaSetMonitor --help
|
||||
./bin/ReplicaSet basic
|
||||
./bin/URIExample 'mongodb://localhost:27017/?replicaSet=rs0'
|
||||
```
|
||||
|
||||
### With Make
|
||||
|
||||
@@ -86,7 +86,7 @@ void basicExample()
|
||||
ReplicaSet::Config config;
|
||||
config.setName = setName;
|
||||
config.seeds = parseHosts(hostsStr);
|
||||
config.readPreference = ReadPreference::Primary;
|
||||
config.readPreference = ReadPreference(ReadPreference::Primary);
|
||||
config.enableMonitoring = true;
|
||||
|
||||
// Create replica set
|
||||
@@ -164,7 +164,7 @@ void readPreferenceExample()
|
||||
|
||||
// Primary read preference
|
||||
std::cout << "1. Primary read preference:" << std::endl;
|
||||
Connection::Ptr primaryConn = rs.getConnection(ReadPreference::Primary);
|
||||
Connection::Ptr primaryConn = rs.getConnection(ReadPreference(ReadPreference::Primary));
|
||||
if (!primaryConn.isNull())
|
||||
{
|
||||
std::cout << " Connected to: " << primaryConn->address().toString() << std::endl;
|
||||
@@ -173,7 +173,7 @@ void readPreferenceExample()
|
||||
|
||||
// Secondary read preference
|
||||
std::cout << "2. Secondary read preference:" << std::endl;
|
||||
Connection::Ptr secondaryConn = rs.getConnection(ReadPreference::Secondary);
|
||||
Connection::Ptr secondaryConn = rs.getConnection(ReadPreference(ReadPreference::Secondary));
|
||||
if (!secondaryConn.isNull())
|
||||
{
|
||||
std::cout << " Connected to: " << secondaryConn->address().toString() << std::endl;
|
||||
@@ -186,7 +186,7 @@ void readPreferenceExample()
|
||||
|
||||
// PrimaryPreferred read preference
|
||||
std::cout << "3. PrimaryPreferred read preference:" << std::endl;
|
||||
Connection::Ptr prefConn = rs.getConnection(ReadPreference::PrimaryPreferred);
|
||||
Connection::Ptr prefConn = rs.getConnection(ReadPreference(ReadPreference::PrimaryPreferred));
|
||||
if (!prefConn.isNull())
|
||||
{
|
||||
std::cout << " Connected to: " << prefConn->address().toString() << std::endl;
|
||||
@@ -195,7 +195,7 @@ void readPreferenceExample()
|
||||
|
||||
// Nearest read preference (lowest latency)
|
||||
std::cout << "4. Nearest read preference (lowest latency):" << std::endl;
|
||||
Connection::Ptr nearestConn = rs.getConnection(ReadPreference::Nearest);
|
||||
Connection::Ptr nearestConn = rs.getConnection(ReadPreference(ReadPreference::Nearest));
|
||||
if (!nearestConn.isNull())
|
||||
{
|
||||
std::cout << " Connected to: " << nearestConn->address().toString() << std::endl;
|
||||
@@ -222,11 +222,11 @@ void failoverExample()
|
||||
ReplicaSet::Config config;
|
||||
config.setName = setName;
|
||||
config.seeds = parseHosts(hostsStr);
|
||||
config.readPreference = ReadPreference::PrimaryPreferred;
|
||||
config.readPreference = ReadPreference(ReadPreference::PrimaryPreferred);
|
||||
ReplicaSet rs(config);
|
||||
|
||||
// Create a replica set connection with automatic failover
|
||||
ReplicaSetConnection::Ptr rsConn = new ReplicaSetConnection(rs, ReadPreference::PrimaryPreferred);
|
||||
ReplicaSetConnection::Ptr rsConn = new ReplicaSetConnection(rs, ReadPreference(ReadPreference::PrimaryPreferred));
|
||||
|
||||
std::cout << "Using ReplicaSetConnection for automatic failover" << std::endl;
|
||||
std::cout << "Initial connection: " << rsConn->address().toString() << std::endl;
|
||||
@@ -302,7 +302,7 @@ void poolExample()
|
||||
std::cout << std::endl;
|
||||
|
||||
// Create connection pool
|
||||
PoolableObjectFactory<ReplicaSetConnection, ReplicaSetConnection::Ptr> factory(*rs, ReadPreference::PrimaryPreferred);
|
||||
PoolableObjectFactory<ReplicaSetConnection, ReplicaSetConnection::Ptr> factory(*rs, ReadPreference(ReadPreference::PrimaryPreferred));
|
||||
ObjectPool<ReplicaSetConnection, ReplicaSetConnection::Ptr> pool(factory, 5, 10);
|
||||
|
||||
// Use pooled connections
|
||||
|
||||
@@ -42,6 +42,7 @@ using namespace Poco;
|
||||
|
||||
struct MonitorConfig
|
||||
{
|
||||
std::string uri;
|
||||
std::string setName;
|
||||
std::vector<Net::SocketAddress> seeds;
|
||||
int intervalSeconds;
|
||||
@@ -51,6 +52,7 @@ struct MonitorConfig
|
||||
int maxIterations;
|
||||
|
||||
MonitorConfig():
|
||||
uri(),
|
||||
setName("rs0"),
|
||||
intervalSeconds(5),
|
||||
database("test"),
|
||||
@@ -88,6 +90,8 @@ void printUsage()
|
||||
std::cout << std::endl;
|
||||
std::cout << "Options:" << std::endl;
|
||||
std::cout << " -h, --help Show this help message" << std::endl;
|
||||
std::cout << " -u, --uri URI MongoDB connection URI" << std::endl;
|
||||
std::cout << " (e.g., mongodb://host1:27017,host2:27017/?replicaSet=rs0)" << std::endl;
|
||||
std::cout << " -s, --set NAME Replica set name (default: rs0)" << std::endl;
|
||||
std::cout << " -H, --hosts HOSTS Comma-separated host:port list" << std::endl;
|
||||
std::cout << " (default: localhost:27017,localhost:27018,localhost:27019)" << std::endl;
|
||||
@@ -97,11 +101,18 @@ void printUsage()
|
||||
std::cout << " -v, --verbose Verbose output" << std::endl;
|
||||
std::cout << " -n, --iterations N Number of iterations (default: unlimited)" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Note: --uri takes precedence over --set and --hosts options." << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Environment variables:" << std::endl;
|
||||
std::cout << " MONGODB_URI MongoDB connection URI" << std::endl;
|
||||
std::cout << " MONGODB_REPLICA_SET Replica set name" << std::endl;
|
||||
std::cout << " MONGODB_HOSTS Comma-separated host:port list" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Example:" << std::endl;
|
||||
std::cout << "Examples:" << std::endl;
|
||||
std::cout << " # Using URI" << std::endl;
|
||||
std::cout << " ReplicaSetMonitor -u 'mongodb://mongo1:27017,mongo2:27017/?replicaSet=rs0'" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << " # Using separate options" << std::endl;
|
||||
std::cout << " ReplicaSetMonitor -s rs0 -H mongo1:27017,mongo2:27017,mongo3:27017 -i 10" << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -314,37 +325,53 @@ void runMonitor(const MonitorConfig& config)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Configure replica set
|
||||
ReplicaSet::Config rsConfig;
|
||||
rsConfig.setName = config.setName;
|
||||
rsConfig.seeds = config.seeds;
|
||||
rsConfig.readPreference = ReadPreference(ReadPreference::PrimaryPreferred);
|
||||
rsConfig.enableMonitoring = true;
|
||||
rsConfig.heartbeatFrequency = Poco::Timespan(5, 0); // 5 seconds
|
||||
// Create replica set - use URI if provided, otherwise use Config
|
||||
SharedPtr<ReplicaSet> rs;
|
||||
|
||||
std::cout << "Connecting to replica set: " << config.setName << std::endl;
|
||||
std::cout << "Seed servers: ";
|
||||
for (size_t i = 0; i < config.seeds.size(); ++i)
|
||||
if (!config.uri.empty())
|
||||
{
|
||||
if (i > 0) std::cout << ", ";
|
||||
std::cout << config.seeds[i].toString();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << "Check interval: " << config.intervalSeconds << " seconds" << std::endl;
|
||||
std::cout << std::endl;
|
||||
// Use URI constructor
|
||||
std::cout << "Connecting to replica set via URI" << std::endl;
|
||||
std::cout << "URI: " << config.uri << std::endl;
|
||||
std::cout << "Check interval: " << config.intervalSeconds << " seconds" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
ReplicaSet rs(rsConfig);
|
||||
rs = new ReplicaSet(config.uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use Config constructor
|
||||
ReplicaSet::Config rsConfig;
|
||||
rsConfig.setName = config.setName;
|
||||
rsConfig.seeds = config.seeds;
|
||||
rsConfig.readPreference = ReadPreference(ReadPreference::PrimaryPreferred);
|
||||
rsConfig.enableMonitoring = true;
|
||||
rsConfig.heartbeatFrequency = Poco::Timespan(5, 0); // 5 seconds
|
||||
|
||||
std::cout << "Connecting to replica set: " << config.setName << std::endl;
|
||||
std::cout << "Seed servers: ";
|
||||
for (size_t i = 0; i < config.seeds.size(); ++i)
|
||||
{
|
||||
if (i > 0) std::cout << ", ";
|
||||
std::cout << config.seeds[i].toString();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << "Check interval: " << config.intervalSeconds << " seconds" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
rs = new ReplicaSet(rsConfig);
|
||||
}
|
||||
|
||||
std::cout << "Replica set connected successfully!" << std::endl;
|
||||
std::cout << "Background monitoring active." << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// Print initial topology
|
||||
printTopology(rs.topology(), config.verbose);
|
||||
printTopology(rs->topology(), config.verbose);
|
||||
|
||||
// Create replica set connections for reads and writes
|
||||
ReplicaSetConnection::Ptr writeConn = new ReplicaSetConnection(rs, ReadPreference(ReadPreference::Primary));
|
||||
ReplicaSetConnection::Ptr readConn = new ReplicaSetConnection(rs, ReadPreference(ReadPreference::PrimaryPreferred));
|
||||
ReplicaSetConnection::Ptr writeConn = new ReplicaSetConnection(*rs, ReadPreference(ReadPreference::Primary));
|
||||
ReplicaSetConnection::Ptr readConn = new ReplicaSetConnection(*rs, ReadPreference(ReadPreference::PrimaryPreferred));
|
||||
|
||||
// Monitoring loop
|
||||
int iteration = 0;
|
||||
@@ -410,7 +437,7 @@ void runMonitor(const MonitorConfig& config)
|
||||
if (iteration % 10 == 0 || iteration == 1)
|
||||
{
|
||||
std::cout << std::endl;
|
||||
printTopology(rs.topology(), config.verbose);
|
||||
printTopology(rs->topology(), config.verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -447,6 +474,12 @@ int main(int argc, char** argv)
|
||||
MonitorConfig config;
|
||||
|
||||
// Parse environment variables
|
||||
const char* envUri = std::getenv("MONGODB_URI");
|
||||
if (envUri)
|
||||
{
|
||||
config.uri = envUri;
|
||||
}
|
||||
|
||||
const char* envSet = std::getenv("MONGODB_REPLICA_SET");
|
||||
if (envSet)
|
||||
{
|
||||
@@ -469,6 +502,10 @@ int main(int argc, char** argv)
|
||||
printUsage();
|
||||
return 0;
|
||||
}
|
||||
else if ((arg == "-u" || arg == "--uri") && i + 1 < argc)
|
||||
{
|
||||
config.uri = argv[++i];
|
||||
}
|
||||
else if ((arg == "-s" || arg == "--set") && i + 1 < argc)
|
||||
{
|
||||
config.setName = argv[++i];
|
||||
@@ -506,8 +543,8 @@ int main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
// Use defaults if not configured
|
||||
if (config.seeds.empty())
|
||||
// Use defaults if not configured and no URI provided
|
||||
if (config.uri.empty() && config.seeds.empty())
|
||||
{
|
||||
config.seeds = parseHosts("localhost:27017,localhost:27018,localhost:27019");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Random.h"
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include <chrono>
|
||||
|
||||
|
||||
@@ -483,10 +485,122 @@ void ReplicaSet::updateTopologyFromAllServers()
|
||||
|
||||
void ReplicaSet::parseURI(const std::string& uri)
|
||||
{
|
||||
// Placeholder for URI parsing implementation
|
||||
// This would parse mongodb://host1:port1,host2:port2,...?options
|
||||
// For now, throw NotImplementedException
|
||||
throw Poco::NotImplementedException("URI parsing not yet implemented. Use Config constructor instead.");
|
||||
// Parse MongoDB URI: mongodb://[user:pass@]host1:port1,host2:port2[,hostN:portN]/[database][?options]
|
||||
Poco::URI theURI(uri);
|
||||
|
||||
if (theURI.getScheme() != "mongodb")
|
||||
{
|
||||
throw Poco::UnknownURISchemeException("Replica set URI must use 'mongodb' scheme");
|
||||
}
|
||||
|
||||
// Parse authority to extract multiple hosts
|
||||
// The authority in MongoDB URIs can be: host1:port1,host2:port2,host3:port3
|
||||
// Poco::URI will give us the full authority string, we need to parse it manually
|
||||
std::string authority = theURI.getAuthority();
|
||||
|
||||
// Remove userinfo if present (username:password@)
|
||||
std::string::size_type atPos = authority.find('@');
|
||||
std::string hostsStr;
|
||||
if (atPos != std::string::npos)
|
||||
{
|
||||
hostsStr = authority.substr(atPos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
hostsStr = authority;
|
||||
}
|
||||
|
||||
// Parse comma-separated hosts
|
||||
_config.seeds.clear();
|
||||
std::string::size_type start = 0;
|
||||
std::string::size_type end;
|
||||
|
||||
while ((end = hostsStr.find(',', start)) != std::string::npos)
|
||||
{
|
||||
std::string hostPort = hostsStr.substr(start, end - start);
|
||||
if (!hostPort.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
_config.seeds.push_back(Net::SocketAddress(hostPort));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Skip invalid host addresses
|
||||
}
|
||||
}
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
// Parse last host
|
||||
std::string lastHost = hostsStr.substr(start);
|
||||
if (!lastHost.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
_config.seeds.push_back(Net::SocketAddress(lastHost));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Skip invalid host address
|
||||
}
|
||||
}
|
||||
|
||||
if (_config.seeds.empty())
|
||||
{
|
||||
throw Poco::SyntaxException("No valid hosts found in replica set URI");
|
||||
}
|
||||
|
||||
// Parse query parameters
|
||||
Poco::URI::QueryParameters params = theURI.getQueryParameters();
|
||||
for (const auto& param : params)
|
||||
{
|
||||
if (param.first == "replicaSet")
|
||||
{
|
||||
_config.setName = param.second;
|
||||
}
|
||||
else if (param.first == "readPreference")
|
||||
{
|
||||
// Parse read preference mode
|
||||
if (param.second == "primary")
|
||||
{
|
||||
_config.readPreference = ReadPreference(ReadPreference::Primary);
|
||||
}
|
||||
else if (param.second == "primaryPreferred")
|
||||
{
|
||||
_config.readPreference = ReadPreference(ReadPreference::PrimaryPreferred);
|
||||
}
|
||||
else if (param.second == "secondary")
|
||||
{
|
||||
_config.readPreference = ReadPreference(ReadPreference::Secondary);
|
||||
}
|
||||
else if (param.second == "secondaryPreferred")
|
||||
{
|
||||
_config.readPreference = ReadPreference(ReadPreference::SecondaryPreferred);
|
||||
}
|
||||
else if (param.second == "nearest")
|
||||
{
|
||||
_config.readPreference = ReadPreference(ReadPreference::Nearest);
|
||||
}
|
||||
}
|
||||
else if (param.first == "connectTimeoutMS")
|
||||
{
|
||||
Poco::Int64 timeoutMs = Poco::NumberParser::parse64(param.second);
|
||||
_config.connectTimeout = Poco::Timespan(timeoutMs * 1000); // Convert ms to microseconds
|
||||
}
|
||||
else if (param.first == "socketTimeoutMS")
|
||||
{
|
||||
Poco::Int64 timeoutMs = Poco::NumberParser::parse64(param.second);
|
||||
_config.socketTimeout = Poco::Timespan(timeoutMs * 1000); // Convert ms to microseconds
|
||||
}
|
||||
else if (param.first == "heartbeatFrequencyMS")
|
||||
{
|
||||
Poco::Int64 freqMs = Poco::NumberParser::parse64(param.second);
|
||||
_config.heartbeatFrequency = Poco::Timespan(freqMs * 1000); // Convert ms to microseconds
|
||||
}
|
||||
// Note: readPreferenceTags and maxStalenessSeconds would require more complex parsing
|
||||
// and are not commonly used, so we skip them for now
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user