From a0c55b0db33e2a3ca23fe8c994ce1045677d6ca6 Mon Sep 17 00:00:00 2001 From: Mark Benvenuto Date: Fri, 29 May 2020 15:04:19 -0400 Subject: SERVER-48276 ReplSet Free Monitoring URLs inconsistent (cherry picked from commit 4ec400290afe55c470cb14fbafb79e9f649d7cb1) --- jstests/free_mon/free_mon_rs_register.js | 1 + jstests/free_mon/free_mon_rs_resend.js | 1 + jstests/free_mon/libs/free_mon.js | 19 +++++++++++++++ jstests/free_mon/libs/mock_http_server.py | 8 +++++-- src/mongo/db/free_mon/free_mon_controller.cpp | 2 +- src/mongo/db/free_mon/free_mon_message.h | 2 +- src/mongo/db/free_mon/free_mon_processor.cpp | 34 +++++++++++++++++---------- 7 files changed, 50 insertions(+), 17 deletions(-) diff --git a/jstests/free_mon/free_mon_rs_register.js b/jstests/free_mon/free_mon_rs_register.js index b08b2f85409..5c85dfe1c58 100644 --- a/jstests/free_mon/free_mon_rs_register.js +++ b/jstests/free_mon/free_mon_rs_register.js @@ -30,6 +30,7 @@ mock_web.waitRegisters(2); WaitForRegistration(rst.getPrimary()); WaitForRegistration(rst.getSecondary()); +ValidateFreeMonReplicaSet(rst); const last_register = mock_web.query("last_register"); print(tojson(last_register)); diff --git a/jstests/free_mon/free_mon_rs_resend.js b/jstests/free_mon/free_mon_rs_resend.js index 9c87cb5bfcb..bdf7602c871 100644 --- a/jstests/free_mon/free_mon_rs_resend.js +++ b/jstests/free_mon/free_mon_rs_resend.js @@ -41,6 +41,7 @@ mock_web_sec.waitRegisters(1); WaitForFreeMonServerStatusState(rst.getPrimary(), 'enabled'); WaitForFreeMonServerStatusState(rst.getSecondary(), 'enabled'); +ValidateFreeMonReplicaSet(rst); mock_web.waitRegisters(2); mock_web_sec.waitRegisters(2); diff --git a/jstests/free_mon/libs/free_mon.js b/jstests/free_mon/libs/free_mon.js index ee4eaff3ee0..1ff781cf0f1 100644 --- a/jstests/free_mon/libs/free_mon.js +++ b/jstests/free_mon/libs/free_mon.js @@ -308,3 +308,22 @@ function WaitForFreeMonServerStatusState(conn, state) { "', actual: " + tojson(FreeMonGetServerStatus(conn)), 20 * 1000); } + +/** + * Validate Free Monitoring Replica Set consistency + * WARNING: Not valid if secondary is started with enableFreeMonitoring since it registers before it + * joins the replica set. + * + * @param {object} rst + */ +function ValidateFreeMonReplicaSet(rst) { + 'use strict'; + + const primary_status = FreeMonGetStatus(rst.getPrimary()); + const primary_url = primary_status.url; + const secondary_status = FreeMonGetStatus(rst.getSecondary()); + const secondary_url = secondary_status.url; + assert.eq(primary_url, + secondary_url, + `DUMP ${tojson(primary_status)} == ${tojson(secondary_status)}`); +} diff --git a/jstests/free_mon/libs/mock_http_server.py b/jstests/free_mon/libs/mock_http_server.py index c5609c8fe35..5245677b33d 100644 --- a/jstests/free_mon/libs/mock_http_server.py +++ b/jstests/free_mon/libs/mock_http_server.py @@ -125,15 +125,19 @@ class FreeMonHandler(http.server.BaseHTTPRequestHandler): 'reportingInterval': bson.int64.Int64(1), }) else: + reg_id = 'mock123_' + str(stats.register_calls) + if 'id' in decoded_doc: + reg_id = decoded_doc['id'] + data = bson.BSON.encode({ 'version': bson.int64.Int64(1), 'haltMetricsUploading': False, 'id': - 'mock123', + reg_id, 'informationalURL': - 'http://www.example.com/123', + 'http://www.example.com/' + reg_id, 'message': 'Welcome to the Mock Free Monitoring Endpoint', 'reportingInterval': diff --git a/src/mongo/db/free_mon/free_mon_controller.cpp b/src/mongo/db/free_mon/free_mon_controller.cpp index 3c3de8236cb..f5b4b912637 100644 --- a/src/mongo/db/free_mon/free_mon_controller.cpp +++ b/src/mongo/db/free_mon/free_mon_controller.cpp @@ -84,7 +84,7 @@ void FreeMonController::registerServerStartup(RegistrationType registrationType, } boost::optional FreeMonController::registerServerCommand(Milliseconds timeout) { - auto msg = FreeMonRegisterCommandMessage::createNow(std::vector()); + auto msg = FreeMonRegisterCommandMessage::createNow({std::vector(), boost::none}); _enqueue(msg); if (timeout > Milliseconds::min()) { diff --git a/src/mongo/db/free_mon/free_mon_message.h b/src/mongo/db/free_mon/free_mon_message.h index 9b7fc83a05b..2f8bab042c6 100644 --- a/src/mongo/db/free_mon/free_mon_message.h +++ b/src/mongo/db/free_mon/free_mon_message.h @@ -342,7 +342,7 @@ struct FreeMonWaitablePayloadForMessage { template <> struct FreeMonWaitablePayloadForMessage { - using payload_type = std::vector; + using payload_type = std::pair, boost::optional>; }; template <> diff --git a/src/mongo/db/free_mon/free_mon_processor.cpp b/src/mongo/db/free_mon/free_mon_processor.cpp index 28c64dbd818..ddf5110b27c 100644 --- a/src/mongo/db/free_mon/free_mon_processor.cpp +++ b/src/mongo/db/free_mon/free_mon_processor.cpp @@ -330,7 +330,7 @@ void FreeMonProcessor::doServerRegister( // If we are asked to register now, then kick off a registration request const auto regType = msg->getPayload().first; if (regType == RegistrationType::RegisterOnStart) { - enqueue(FreeMonRegisterCommandMessage::createNow(msg->getPayload().second)); + enqueue(FreeMonRegisterCommandMessage::createNow({msg->getPayload().second, boost::none})); } else { invariant((regType == RegistrationType::RegisterAfterOnTransitionToPrimary) || (regType == RegistrationType::RegisterAfterOnTransitionToPrimaryIfEnabled)); @@ -355,7 +355,8 @@ void FreeMonProcessor::doServerRegister( // We are standalone or secondary, if we have a registration id, then send a // registration notification, else wait for the user to register us. if (state.get().getState() == StorageStateEnum::enabled) { - enqueue(FreeMonRegisterCommandMessage::createNow(msg->getPayload().second)); + enqueue(FreeMonRegisterCommandMessage::createNow( + {msg->getPayload().second, boost::none})); } } @@ -418,22 +419,26 @@ void FreeMonProcessor::doCommandRegister(Client* client, FreeMonRegistrationRequest req; - auto regid = _state->getRegistrationId(); - if (!regid.empty()) { - req.setId(regid); + if (msg->getPayload().second) { + req.setId(StringData(msg->getPayload().second.get())); + } else { + auto regid = _state->getRegistrationId(); + if (!regid.empty()) { + req.setId(regid); + } } req.setVersion(kMaxProtocolVersion); req.setLocalTime(client->getServiceContext()->getPreciseClockSource()->now()); - if (!msg->getPayload().empty()) { + if (!msg->getPayload().first.empty()) { // Cache the tags for subsequent retries - _tags = msg->getPayload(); + _tags = msg->getPayload().first; } if (!_tags.empty()) { - req.setTags(transformVector(msg->getPayload())); + req.setTags(transformVector(msg->getPayload().first)); } // Collect the data @@ -687,7 +692,7 @@ void FreeMonProcessor::doAsyncRegisterFail( // Enqueue a register retry enqueue(FreeMonRegisterCommandMessage::createWithDeadline( - _tags, _registrationRetry->getNextDeadline(client))); + {_tags, boost::none}, _registrationRetry->getNextDeadline(client))); } void FreeMonProcessor::doCommandUnregister( @@ -851,7 +856,7 @@ void FreeMonProcessor::doAsyncMetricsComplete( _metricsRetry->reset(); if (resp.getResendRegistration().is_initialized() && resp.getResendRegistration()) { - enqueue(FreeMonRegisterCommandMessage::createNow(_tags)); + enqueue(FreeMonRegisterCommandMessage::createNow({_tags, boost::none})); } else { // Enqueue next metrics upload enqueue(FreeMonMessage::createWithDeadline(FreeMonMessageType::MetricsSend, @@ -912,13 +917,15 @@ void FreeMonProcessor::getStatus(OperationContext* opCtx, void FreeMonProcessor::doOnTransitionToPrimary(Client* client) { if (_registerOnTransitionToPrimary == RegistrationType::RegisterAfterOnTransitionToPrimary) { - enqueue(FreeMonRegisterCommandMessage::createNow(std::vector())); + enqueue( + FreeMonRegisterCommandMessage::createNow({std::vector(), boost::none})); } else if (_registerOnTransitionToPrimary == RegistrationType::RegisterAfterOnTransitionToPrimaryIfEnabled) { readState(client); if (_state->getState() == StorageStateEnum::enabled) { - enqueue(FreeMonRegisterCommandMessage::createNow(std::vector())); + enqueue(FreeMonRegisterCommandMessage::createNow( + {std::vector(), boost::none})); } } @@ -934,7 +941,8 @@ void FreeMonProcessor::processInMemoryStateChange(const FreeMonStorageState& ori newState.getState() == StorageStateEnum::enabled) { // Secondary needs to start registration - enqueue(FreeMonRegisterCommandMessage::createNow(std::vector())); + enqueue(FreeMonRegisterCommandMessage::createNow( + {std::vector(), newState.getRegistrationId().toString()})); } } } -- cgit v1.2.1