fix: status would generate invalid json
This commit is contained in:
parent
953f67009d
commit
d3c8d7ab4e
|
@ -27,7 +27,7 @@
|
|||
#include "Status.h"
|
||||
#include "ClientDBInfo.h"
|
||||
#include "ClientWorkerInterface.h"
|
||||
#include "flow/JsonString.h"
|
||||
#include "JsonString.h"
|
||||
|
||||
struct ClusterInterface {
|
||||
RequestStream< struct OpenDatabaseRequest > openDatabase;
|
||||
|
|
|
@ -1,11 +1,45 @@
|
|||
#include "JsonString.h"
|
||||
#include "Hash3.h"
|
||||
#include <iostream>
|
||||
#include "Trace.h"
|
||||
#include "flow.h"
|
||||
|
||||
std::string format( const char* form, ... );
|
||||
|
||||
bool shouldEscape(char c) {
|
||||
switch( c ) {
|
||||
case '"':
|
||||
case '\\':
|
||||
case '\b':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void escape( const std::string& in, std::string& out ) {
|
||||
bool needsEscaping = false;
|
||||
for (int i = 0; i<in.size(); i++) {
|
||||
if (shouldEscape(in[i])) {
|
||||
needsEscaping = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!needsEscaping) {
|
||||
out += in;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i<in.size(); i++) {
|
||||
if (shouldEscape(in[i])) {
|
||||
out += '\\';
|
||||
}
|
||||
out += in[i];
|
||||
}
|
||||
}
|
||||
|
||||
JsonString::JsonString() : hasKey(false) {
|
||||
}
|
||||
JsonString::JsonString( const JsonString& jsonString) : _jsonText(jsonString._jsonText), hasKey(jsonString.hasKey) {
|
||||
|
@ -21,6 +55,12 @@ JsonString::JsonString( const char* value ) : hasKey(false) {
|
|||
append(value);
|
||||
}
|
||||
|
||||
JsonString::JsonString( const json_spirit::mObject& value ) : hasKey(false) {
|
||||
_jsonText = json_spirit::write_string(json_spirit::mValue(value));
|
||||
_jsonText = _jsonText.substr(1,_jsonText.size()-2); //remove outer {}
|
||||
hasKey = !_jsonText.empty();
|
||||
}
|
||||
|
||||
JsonString::JsonString( const std::string& name, const std::string& value ) : hasKey(false) {
|
||||
append(name, value);
|
||||
}
|
||||
|
@ -66,19 +106,33 @@ JsonString JsonString::makeMessage(const char *name, const char *description) {
|
|||
}
|
||||
|
||||
JsonString& JsonString::appendImpl( const std::string& name, const std::string& value, bool quote ) {
|
||||
_jsonText.reserve(_jsonText.size() + name.size() + (quote ? (2*value.size() + 6) : (value.size() + 4)));
|
||||
hasKey = true;
|
||||
_jsonText += (_jsonText.empty() ? "\"" : ",\n \"") + name + (quote ? "\": \"" : "\": ") + value;
|
||||
if (quote)
|
||||
if(!_jsonText.empty()) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
_jsonText += '"';
|
||||
_jsonText += name;
|
||||
_jsonText += "\":";
|
||||
if (quote) {
|
||||
_jsonText += "\"";
|
||||
escape(value, _jsonText);
|
||||
_jsonText += "\"";
|
||||
} else {
|
||||
_jsonText += value;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
JsonString& JsonString::appendImpl( const std::string& value, bool quote ) {
|
||||
if (quote) {
|
||||
_jsonText += (_jsonText.empty() ? "\"" : ", \"") + value + "\"";
|
||||
_jsonText.reserve(_jsonText.size() + (quote ? (2*value.size() + 3) : value.size()));
|
||||
if(!_jsonText.empty()) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
else {
|
||||
if (_jsonText.empty())
|
||||
_jsonText += ", ";
|
||||
if (quote) {
|
||||
_jsonText += "\"";
|
||||
escape(value, _jsonText);
|
||||
_jsonText += "\"";
|
||||
} else {
|
||||
_jsonText += value;
|
||||
}
|
||||
return *this;
|
||||
|
@ -143,21 +197,40 @@ JsonString& JsonString::append( const std::string& name, bool value ) {
|
|||
return appendImpl(name, stringify(value), false);
|
||||
}
|
||||
JsonString& JsonString::append( const std::string& name, const JsonString& value ) {
|
||||
_jsonText.reserve(_jsonText.size() + name.size() + value._jsonText.size() + 6);
|
||||
hasKey = true;
|
||||
_jsonText += (_jsonText.empty() ? "\"" : ",\n \"") + name + "\": { " + value._jsonText + " }";
|
||||
if(!_jsonText.empty()) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
_jsonText += '\"';
|
||||
_jsonText += name;
|
||||
_jsonText += "\":{";
|
||||
_jsonText += value._jsonText;
|
||||
_jsonText += '}';
|
||||
return *this;
|
||||
}
|
||||
JsonString& JsonString::append( const std::string& name, const JsonStringArray& values ) {
|
||||
hasKey = true;
|
||||
_jsonText += (_jsonText.empty() ? "\"" : ",\n \"") + name + "\": [ ";
|
||||
size_t counter = 0;
|
||||
int valueBytes = 0;
|
||||
for (auto const& value : values) {
|
||||
if (counter)
|
||||
_jsonText += ",\n ";
|
||||
_jsonText += value.getJson();
|
||||
counter ++;
|
||||
valueBytes += value.getLength();
|
||||
}
|
||||
_jsonText += " ]";
|
||||
_jsonText.reserve(_jsonText.size() + name.size() + values.size() + valueBytes + 6);
|
||||
hasKey = true;
|
||||
if(!_jsonText.empty()) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
_jsonText += '"';
|
||||
_jsonText += name;
|
||||
_jsonText += "\":[";
|
||||
bool first = true;
|
||||
for (auto const& value : values) {
|
||||
if (!first) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
_jsonText += value.getJson();
|
||||
first = false;
|
||||
}
|
||||
_jsonText += ']';
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -194,8 +267,10 @@ JsonString& JsonString::append( bool value ) {
|
|||
JsonString& JsonString::append( const JsonString& value ) {
|
||||
// Only do something, if not empty
|
||||
if (!value.empty()) {
|
||||
if (!_jsonText.empty())
|
||||
_jsonText += ",\n ";
|
||||
_jsonText.reserve(_jsonText.size() + value._jsonText.size() + 1);
|
||||
if (!_jsonText.empty()) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
_jsonText += value._jsonText;
|
||||
if(value.hasKey) {
|
||||
hasKey = true;
|
||||
|
@ -204,15 +279,24 @@ JsonString& JsonString::append( const JsonString& value ) {
|
|||
return *this;
|
||||
}
|
||||
JsonString& JsonString::append( const JsonStringArray& values ) {
|
||||
_jsonText += _jsonText.empty() ? "[ " : ",\n [ ";
|
||||
size_t counter = 0;
|
||||
int valueBytes = 0;
|
||||
for (auto const& value : values) {
|
||||
if (counter)
|
||||
_jsonText += ",\n ";
|
||||
_jsonText += value.getJson();
|
||||
counter ++;
|
||||
valueBytes += value.getLength();
|
||||
}
|
||||
_jsonText += " ]";
|
||||
_jsonText.reserve(_jsonText.size() + values.size() + valueBytes + 3);
|
||||
if (!_jsonText.empty()) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
_jsonText += '[';
|
||||
bool first = true;
|
||||
for (auto const& value : values) {
|
||||
if (!first) {
|
||||
_jsonText += ',';
|
||||
}
|
||||
_jsonText += value.getJson();
|
||||
first = false;
|
||||
}
|
||||
_jsonText += ']';
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -231,12 +315,21 @@ const std::string& JsonString::getJsonText() const {
|
|||
}
|
||||
|
||||
size_t JsonString::getLength() const {
|
||||
return _jsonText.length() + ((!empty() && !hasKey) ? 0 : 4);
|
||||
return _jsonText.length() + ((!empty() && !hasKey) ? 0 : 2);
|
||||
}
|
||||
|
||||
std::string JsonString::getJson() const {
|
||||
// If not empty with no names (only values), don't add brackets because prob in an array
|
||||
return (!empty() && !hasKey) ? _jsonText : ("{ " + _jsonText + " }");
|
||||
if (!empty() && !hasKey) {
|
||||
return _jsonText;
|
||||
} else {
|
||||
std::string result;
|
||||
result.reserve(_jsonText.size() + 2);
|
||||
result += '{';
|
||||
result += _jsonText;
|
||||
result += '}';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
JsonString& JsonString::copy( const JsonString& jsonString ) {
|
||||
|
@ -249,15 +342,6 @@ JsonString& JsonString::operator=( const JsonString& jsonString ) {
|
|||
return copy(jsonString);
|
||||
}
|
||||
|
||||
//TODO: Populate key names member
|
||||
void JsonString::setJson(const std::string& jsonText) {
|
||||
_jsonText = jsonText;
|
||||
}
|
||||
JsonString& JsonString::swapJsonText(std::string& jsonText) {
|
||||
_jsonText.swap(jsonText);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int JsonString::compare( const JsonString& jsonString ) const {
|
||||
return jsonString._jsonText.compare(_jsonText);
|
||||
}
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "flow/flow.h"
|
||||
#include "flow/Trace.h"
|
||||
#include "fdbrpc/JSONDoc.h"
|
||||
|
||||
class JsonString;
|
||||
class JsonStringArray;
|
||||
|
@ -17,6 +20,7 @@ class JsonString {
|
|||
explicit JsonString( const JsonStringArray& jsonArray);
|
||||
explicit JsonString( const char* value ); // Used to define values (used in an Array)
|
||||
explicit JsonString( const std::string& value ); // Used to define values (used in an Array)
|
||||
explicit JsonString( const json_spirit::mObject& value );
|
||||
|
||||
JsonString( const std::string& name, const char* value );
|
||||
JsonString( const std::string& name, const std::string& value );
|
||||
|
@ -70,9 +74,6 @@ class JsonString {
|
|||
JsonString& operator=( const JsonString& jsonString );
|
||||
|
||||
std::string getJson() const;
|
||||
void setJson(const std::string& jsonText);
|
||||
JsonString& swapJsonText(std::string& jsonText);
|
||||
|
||||
size_t getLength() const;
|
||||
|
||||
JsonString& clear();
|
|
@ -1405,8 +1405,9 @@ json_spirit::Value_type normJSONType(json_spirit::Value_type type) {
|
|||
}
|
||||
|
||||
void schemaCoverage( std::string const& spath, bool covered ) {
|
||||
static std::set<std::string> coveredSchemaPaths;
|
||||
if (coveredSchemaPaths.insert(spath).second) {
|
||||
static std::map<bool, std::set<std::string>> coveredSchemaPaths;
|
||||
|
||||
if( coveredSchemaPaths[covered].insert(spath).second ) {
|
||||
TraceEvent ev(SevInfo, "CodeCoverage");
|
||||
ev.detail("File", "documentation/StatusSchema.json/" + spath).detail("Line", 0);
|
||||
if (!covered)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#include "flow/flow.h"
|
||||
#include "Status.h"
|
||||
|
||||
JsonString StatusObject::toJsonString() const {
|
||||
std::string jsonText = json_spirit::write_string(json_spirit::mValue(*this));
|
||||
return JsonString().swapJsonText(jsonText);
|
||||
}
|
|
@ -22,7 +22,6 @@
|
|||
#define FDBCLIENT_STATUS_H
|
||||
|
||||
#include "../fdbrpc/JSONDoc.h"
|
||||
#include "../flow/JsonString.h"
|
||||
|
||||
struct StatusObject : json_spirit::mObject {
|
||||
typedef json_spirit::mObject Map;
|
||||
|
@ -30,7 +29,6 @@ struct StatusObject : json_spirit::mObject {
|
|||
|
||||
StatusObject() {}
|
||||
StatusObject(json_spirit::mObject const& o) : json_spirit::mObject(o) {}
|
||||
JsonString toJsonString() const;
|
||||
};
|
||||
|
||||
template <class Ar>
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
<ClInclude Include="WriteMap.h" />
|
||||
<ClInclude Include="Subspace.h" />
|
||||
<ClInclude Include="Tuple.h" />
|
||||
<ClInclude Include="JsonString.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ActorCompiler Include="FailureMonitorClient.actor.cpp" />
|
||||
|
@ -98,13 +99,13 @@
|
|||
<ActorCompiler Include="MultiVersionTransaction.actor.cpp" />
|
||||
<ClCompile Include="RYWIterator.cpp" />
|
||||
<ActorCompiler Include="StatusClient.actor.cpp" />
|
||||
<ClCompile Include="Status.cpp" />
|
||||
<ClCompile Include="Schemas.cpp" />
|
||||
<ClCompile Include="SystemData.cpp" />
|
||||
<ActorCompiler Include="ThreadSafeTransaction.actor.cpp" />
|
||||
<ActorCompiler Include="TaskBucket.actor.cpp" />
|
||||
<ClCompile Include="Subspace.cpp" />
|
||||
<ClCompile Include="Tuple.cpp" />
|
||||
<ClCompile Include="JsonString.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGUID>{E2939DAA-238E-4970-96C4-4C57980F93BD}</ProjectGUID>
|
||||
|
|
|
@ -1075,7 +1075,7 @@ static JsonString configurationFetcher(Optional<DatabaseConfiguration> conf, Ser
|
|||
try {
|
||||
if(conf.present()) {
|
||||
DatabaseConfiguration configuration = conf.get();
|
||||
statusObj = configuration.toJSON().toJsonString();
|
||||
statusObj = JsonString( configuration.toJSON() );
|
||||
|
||||
JsonStringArray excludedServersArr;
|
||||
std::set<AddressExclusion> excludedServers = configuration.getExcludedServers();
|
||||
|
@ -1692,7 +1692,7 @@ ACTOR Future<JsonString> layerStatusFetcher(Database cx, JsonStringArray *messag
|
|||
}
|
||||
|
||||
json.cleanOps();
|
||||
JsonString statusObj = result.toJsonString();
|
||||
JsonString statusObj = JsonString( result );
|
||||
TraceEvent("LayerStatusFetcher").detail("Duration", now()-tStart).detail("StatusSize",statusObj.getLength());
|
||||
return statusObj;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
<ClCompile Include="UnitTest.cpp" />
|
||||
<ClCompile Include="version.cpp" />
|
||||
<ClCompile Include="SignalSafeUnwind.cpp" />
|
||||
<ClCompile Include="JsonString.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CompressedInt.h" />
|
||||
|
@ -89,7 +88,6 @@
|
|||
<ClInclude Include="ThreadSafeQueue.h" />
|
||||
<ClInclude Include="Trace.h" />
|
||||
<ClInclude Include="SignalSafeUnwind.h" />
|
||||
<ClInclude Include="JsonString.h" />
|
||||
<ClInclude Include="UnitTest.h" />
|
||||
<ActorCompiler Include="ThreadHelper.actor.h">
|
||||
<EnableCompile>false</EnableCompile>
|
||||
|
|
Loading…
Reference in New Issue