Skip to content

Commit

Permalink
Fix clusterutil print dereference bug
Browse files Browse the repository at this point in the history
Add helper functions to print ClusterStateQueueInfo::State

Signed-off-by: Emelia Lei <[email protected]>
  • Loading branch information
emelialei88 committed Jan 28, 2025
1 parent 4eabe37 commit 2925128
Show file tree
Hide file tree
Showing 4 changed files with 505 additions and 17 deletions.
63 changes: 62 additions & 1 deletion src/groups/mqb/mqbc/mqbc_clusterstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,73 @@ bsl::ostream& ClusterStateQueueInfo::print(bsl::ostream& stream,
printer.printAttribute("queueKey", key());
printer.printAttribute("partitionId", partitionId());
printer.printAttribute("appIdInfos", appInfos());
printer.printAttribute("stateOfAssignment", state());
ClusterStateQueueInfo::printState(stream, d_state, level, spacesPerLevel);
printer.end();

return stream;
}

bsl::ostream&
ClusterStateQueueInfo::printState(bsl::ostream& stream,
ClusterStateQueueInfo::State value,
int level,
int spacesPerLevel)
{
if (stream.bad()) {
return stream; // RETURN
}

bdlb::Print::indent(stream, level + 1, spacesPerLevel);
stream << "stateOfAssignment = ";

bdlb::Print::indent(stream, level, spacesPerLevel);
stream << ClusterStateQueueInfo::toAscii(value);

if (spacesPerLevel >= 0) {
stream << '\n';
}

return stream;
}

const char* ClusterStateQueueInfo::toAscii(ClusterStateQueueInfo::State value)
{
#define CASE(X) \
case k_##X: return #X;

switch (value) {
CASE(NONE)
CASE(ASSIGNING)
CASE(ASSIGNED)
CASE(UNASSIGNING)
default: return "(* NONE *)";
}

#undef CASE
}

bool ClusterStateQueueInfo::fromAscii(ClusterStateQueueInfo::State* out,
const bslstl::StringRef& str)
{
#define CHECKVALUE(M) \
if (bdlb::String::areEqualCaseless(toAscii(ClusterStateQueueInfo::k_##M), \
str.data(), \
static_cast<int>(str.length()))) { \
*out = ClusterStateQueueInfo::k_##M; \
return true; \
}

CHECKVALUE(NONE)
CHECKVALUE(ASSIGNING)
CHECKVALUE(ASSIGNED)
CHECKVALUE(UNASSIGNING)

// Invalid string
return false;

#undef CHECKVALUE
}

// --------------------------
// class ClusterStateObserver
// --------------------------
Expand Down
45 changes: 45 additions & 0 deletions src/groups/mqb/mqbc/mqbc_clusterstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,40 @@ class ClusterStateQueueInfo {
/// undefined unless `isValid()` returns true.
bsl::ostream&
print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const;

/// Write the string representation of the specified enumeration `value`
/// to the specified output `stream`, and return a reference to
/// `stream`. Optionally specify an initial indentation `level`, whose
/// absolute value is incremented recursively for nested objects. If
/// `level` is specified, optionally specify `spacesPerLevel`, whose
/// absolute value indicates the number of spaces per indentation level
/// for this and all of its nested objects. If `level` is negative,
/// suppress indentation of the first line. If `spacesPerLevel` is
/// negative, format the entire output on one line, suppressing all but
/// the initial indentation (as governed by `level`). See `toAscii` for
/// what constitutes the string representation of a
/// `ClusterStateQueueInfo::State` value.
static bsl::ostream& printState(bsl::ostream& stream,
ClusterStateQueueInfo::State value,
int level = 0,
int spacesPerLevel = 4);

/// Return the non-modifiable string representation corresponding to the
/// specified enumeration `value`, if it exists, and a unique (error)
/// string otherwise. The string representation of `value` matches its
/// corresponding enumerator name with the `e_` prefix elided. Note
/// that specifying a `value` that does not match any of the enumerators
/// will result in a string representation that is distinct from any of
/// those corresponding to the enumerators, but is otherwise
/// unspecified.
static const char* toAscii(ClusterStateQueueInfo::State value);

/// Return true and fills the specified `out` with the enum value
/// corresponding to the specified `str`, if valid, or return false and
/// leave `out` untouched if `str` doesn't correspond to any value of
/// the enum.
static bool fromAscii(ClusterStateQueueInfo::State* out,
const bslstl::StringRef& str);
};

// FREE OPERATORS
Expand All @@ -269,6 +303,11 @@ class ClusterStateQueueInfo {
bsl::ostream& operator<<(bsl::ostream& stream,
const ClusterStateQueueInfo& rhs);

/// Format the specified `value` to the specified output `stream` and return
/// a reference to the modifiable `stream`.
bsl::ostream& operator<<(bsl::ostream& stream,
ClusterStateQueueInfo::State value);

/// Return `true` if the specified `rhs` object contains the value of the
/// same type as contained in the specified `lhs` object and the value
/// itself is the same in both objects, return false otherwise.
Expand Down Expand Up @@ -1172,6 +1211,12 @@ inline bsl::ostream& mqbc::operator<<(bsl::ostream& stream,
return rhs.print(stream, 0, -1);
}

inline bsl::ostream& mqbc::operator<<(bsl::ostream& stream,
mqbc::ClusterStateQueueInfo::State value)
{
return mqbc::ClusterStateQueueInfo::printState(stream, value, 0, -1);
}

inline bool mqbc::operator==(const ClusterStateQueueInfo& lhs,
const ClusterStateQueueInfo& rhs)
{
Expand Down
32 changes: 16 additions & 16 deletions src/groups/mqb/mqbc/mqbc_clusterutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1133,7 +1133,7 @@ void ClusterUtil::registerQueueInfo(ClusterState* clusterState,

bmqu::Printer<AppInfos> printer(&appInfos);
BALL_LOG_INFO << cluster->description()
<< ": Queue assigned: " << "[uri: " << uri
<< ": Queue assigned: [uri: " << uri
<< ", queueKey: " << queueKey
<< ", partitionId: " << partitionId
<< ", appInfos: " << printer << "]";
Expand Down Expand Up @@ -1409,8 +1409,8 @@ void ClusterUtil::unregisterAppId(ClusterData* clusterData,
queueUpdate.domain() = qinfoCit->second->uri().qualifiedDomain();
BSLS_ASSERT_SAFE(queueUpdate.domain() == domain->name());

bool appIdFound = false;
const AppInfos& appInfos = qinfoCit->second->appInfos();
bool appIdFound = false;
const AppInfos& appInfos = qinfoCit->second->appInfos();
for (AppInfosCIter appInfoCit = appInfos.cbegin();
appInfoCit != appInfos.cend();
++appInfoCit) {
Expand Down Expand Up @@ -1675,11 +1675,11 @@ int ClusterUtil::validateState(bsl::ostream& errorDescription,
// Validate partition information
bsl::vector<ClusterStatePartitionInfo> incorrectPartitions;
for (size_t pid = 0; pid < state.partitions().size(); ++pid) {
const ClusterStatePartitionInfo& stateInfo = state.partitions()[pid];
const ClusterStatePartitionInfo& stateInfo = state.partition(pid);
BSLS_ASSERT_SAFE(stateInfo.partitionId() == pid);

const ClusterStatePartitionInfo& referenceInfo =
reference.partitions()[pid];
const ClusterStatePartitionInfo& referenceInfo = reference.partition(
pid);
BSLS_ASSERT_SAFE(referenceInfo.partitionId() == pid);
if (stateInfo.primaryLeaseId() != referenceInfo.primaryLeaseId()) {
// Partition information mismatch. Note that we don't compare
Expand Down Expand Up @@ -1708,23 +1708,23 @@ int ClusterUtil::validateState(bsl::ostream& errorDescription,
++citer) {
bdlb::Print::newlineAndIndent(out, level + 1);
out << "Partition [" << citer->partitionId()
<< "]: " << " primaryLeaseId: " << citer->primaryLeaseId()
<< "]: primaryLeaseId: " << citer->primaryLeaseId()
<< ", primaryNodeId: " << citer->primaryNodeId();
}

bdlb::Print::newlineAndIndent(out, level);
out << "--------------------------------";
bdlb::Print::newlineAndIndent(out, level);
out << "Partition Infos In Cluster State:";
out << "Partition Infos In Cluster State :";
bdlb::Print::newlineAndIndent(out, level);
out << "--------------------------------";
for (size_t pid = 0; pid < state.partitions().size(); ++pid) {
const ClusterStatePartitionInfo& referenceInfo =
reference.partitions()[pid];
BSLS_ASSERT_SAFE(referenceInfo.partitionId() == pid);
bdlb::Print::newlineAndIndent(out, level + 1);
out << "Partition [" << pid << "]: " << " primaryLeaseId: "
<< referenceInfo.primaryLeaseId()
out << "Partition [" << pid
<< "]: primaryLeaseId: " << referenceInfo.primaryLeaseId()
<< ", primaryNodeId: " << referenceInfo.primaryNodeId();
}
}
Expand Down Expand Up @@ -1782,7 +1782,7 @@ int ClusterUtil::validateState(bsl::ostream& errorDescription,
bdlb::Print::newlineAndIndent(out, level);
out << "-----------------";
bdlb::Print::newlineAndIndent(out, level);
out << "Incorrect Queues:";
out << "Incorrect Queues :";
bdlb::Print::newlineAndIndent(out, level);
out << "-----------------";
for (bsl::vector<bsl::pair<bsl::shared_ptr<ClusterStateQueueInfo>,
Expand All @@ -1791,9 +1791,9 @@ int ClusterUtil::validateState(bsl::ostream& errorDescription,
citer != incorrectQueues.cend();
++citer) {
bdlb::Print::newlineAndIndent(out, level + 1);
out << citer->first;
out << *citer->first;
bdlb::Print::newlineAndIndent(out, level + 1);
out << "(correct queue info) " << citer->second;
out << "(correct queue info) " << *citer->second;
}
}

Expand All @@ -1809,7 +1809,7 @@ int ClusterUtil::validateState(bsl::ostream& errorDescription,
citer != extraQueues.cend();
++citer) {
bdlb::Print::newlineAndIndent(out, level + 1);
out << *citer;
out << **citer;
}
}

Expand Down Expand Up @@ -1862,7 +1862,7 @@ int ClusterUtil::validateState(bsl::ostream& errorDescription,
citer != missingQueues.cend();
++citer) {
bdlb::Print::newlineAndIndent(out, level + 1);
out << *citer;
out << **citer;
}
}

Expand All @@ -1885,7 +1885,7 @@ int ClusterUtil::validateState(bsl::ostream& errorDescription,
citer != domCit->second->queuesInfo().cend();
++citer) {
bdlb::Print::newlineAndIndent(out, level + 1);
out << citer->second;
out << *citer->second;
}
}
}
Expand Down
Loading

0 comments on commit 2925128

Please sign in to comment.