Skip to content

Commit

Permalink
REST message output Standardized
Browse files Browse the repository at this point in the history
  • Loading branch information
laoshanxi committed Apr 21, 2021
1 parent 1de6cca commit 4ffa6d8
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 138 deletions.
43 changes: 32 additions & 11 deletions src/cli/ArgumentParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ void ArgumentParser::processUnReg()
}
std::string restPath = std::string("/appmesh/app/") + appName;
auto response = requestHttp(true, methods::DEL, restPath);
std::cout << GET_STD_STRING(response.extract_utf8string(true).get()) << std::endl;
std::cout << parseOutputMessage(response) << std::endl;
}
else
{
Expand Down Expand Up @@ -629,8 +629,7 @@ void ArgumentParser::processView()
query["keep_history"] = std::to_string(keepHis);
query["stdout_index"] = std::to_string(index);
auto response = requestHttp(true, methods::GET, restPath, query);
auto bodyStr = response.extract_utf8string(true).get();
std::cout << bodyStr;
std::cout << response.extract_utf8string(true).get();
}
}
else
Expand Down Expand Up @@ -725,7 +724,7 @@ void ArgumentParser::processEnableDisable(bool start)
{
std::string restPath = std::string("/appmesh/app/") + app + +"/" + (start ? HTTP_QUERY_KEY_action_start : HTTP_QUERY_KEY_action_stop);
auto response = requestHttp(true, methods::POST, restPath);
std::cout << GET_STD_STRING(response.extract_utf8string(true).get()) << std::endl;
std::cout << parseOutputMessage(response) << std::endl;
}
if (appList.size() == 0)
{
Expand Down Expand Up @@ -816,7 +815,7 @@ void ArgumentParser::processRun()
std::string restPath = "/appmesh/app/syncrun";
auto response = requestHttp(true, methods::POST, restPath, query, &jsonObj);

std::cout << GET_STD_STRING(response.extract_utf8string(true).get());
std::cout << response.extract_utf8string(true).get();
}
else
{
Expand All @@ -837,7 +836,7 @@ void ArgumentParser::processRun()
query.clear();
query[HTTP_QUERY_KEY_process_uuid] = process_uuid;
response = requestHttp(false, methods::GET, restPath, query);
std::cout << GET_STD_STRING(response.extract_utf8string(true).get());
std::cout << response.extract_utf8string(true).get();
// check continues failure
if (response.status_code() != http::status_codes::OK && !response.headers().has(HTTP_HEADER_KEY_exit_code))
{
Expand Down Expand Up @@ -881,6 +880,28 @@ void SIGINT_Handler(int signo)
}
}

std::string ArgumentParser::parseOutputMessage(http_response &resp)
{
std::string result;
try
{
auto respJson = resp.extract_json().get();
if (HAS_JSON_FIELD(respJson, REST_TEXT_MESSAGE_JSON_KEY))
{
result = respJson.at(REST_TEXT_MESSAGE_JSON_KEY).as_string();
}
else
{
result = respJson.serialize();
}
}
catch(...)
{
result = resp.extract_utf8string().get();
}
return result;
}

void ArgumentParser::regSignal()
{
m_sigAction = std::make_shared<ACE_Sig_Action>();
Expand Down Expand Up @@ -1104,7 +1125,7 @@ void ArgumentParser::processUpload()
request.set_body(fileStream, length);
http_response response = client.request(request).get();
fileStream.close();
std::cout << GET_STD_STRING(response.extract_utf8string(true).get()) << std::endl;
std::cout << parseOutputMessage(response) << std::endl;
}

void ArgumentParser::processTags()
Expand Down Expand Up @@ -1289,7 +1310,7 @@ void ArgumentParser::processChangePwd()
std::map<std::string, std::string> query, headers;
headers[HTTP_HEADER_JWT_new_password] = Utility::encode64(passwd);
http_response response = requestHttp(true, methods::POST, restPath, query, nullptr, &headers);
std::cout << GET_STD_STRING(response.extract_utf8string(true).get()) << std::endl;
std::cout << parseOutputMessage(response) << std::endl;
}

void ArgumentParser::processLockUser()
Expand All @@ -1314,7 +1335,7 @@ void ArgumentParser::processLockUser()

std::string restPath = std::string("/appmesh/user/") + user + (lock ? "/lock" : "/unlock");
http_response response = requestHttp(true, methods::POST, restPath);
std::cout << GET_STD_STRING(response.extract_utf8string(true).get()) << std::endl;
std::cout << parseOutputMessage(response) << std::endl;
}

void ArgumentParser::processEncryptUserPwd()
Expand Down Expand Up @@ -1382,7 +1403,7 @@ http_response ArgumentParser::requestHttp(bool throwAble, const method &mtd, con
http_response response = client.request(request).get();
if (throwAble && response.status_code() != status_codes::OK)
{
throw std::invalid_argument(response.extract_utf8string(true).get());
throw std::invalid_argument(parseOutputMessage(response));
}
return response;
}
Expand Down Expand Up @@ -1531,7 +1552,7 @@ std::string ArgumentParser::requestToken(const std::string &user, const std::str
http_response response = client.request(requestLogin).get();
if (response.status_code() != status_codes::OK)
{
throw std::invalid_argument(Utility::stringFormat("Login failed: %s", response.extract_utf8string(true).get().c_str()));
throw std::invalid_argument(Utility::stringFormat("Login failed: %s", parseOutputMessage(response).c_str()));
}
else
{
Expand Down
1 change: 1 addition & 0 deletions src/cli/ArgumentParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class ArgumentParser
size_t inputSecurePasswd(char **pw, size_t sz, int mask, FILE *fp);
void regSignal();
void unregSignal();
std::string parseOutputMessage(http_response& resp);

private:
po::variables_map m_commandLineVariables;
Expand Down
2 changes: 2 additions & 0 deletions src/common/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ class Utility
#define APP_STD_OUT_MAX_FILE_SIZE 1024 * 1024 * 100 // 100M
#define DEFAULT_EXEC_USER "appmesh"
#define SEPARATE_REST_APP_NAME "apprest"
#define REST_ROOT_TEXT_MESSAGE "App Mesh"
#define REST_TEXT_MESSAGE_JSON_KEY "message"

#define JSON_KEY_Description "Description"
#define JSON_KEY_DefaultExecUser "DefaultExecUser"
Expand Down
16 changes: 5 additions & 11 deletions src/daemon/rest/HttpRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,17 @@ void HttpRequest::reply(http_response &response, const std::string &body_data) c

void HttpRequest::reply(http::status_code status) const
{

if (m_reply2child)
{
RestTcpServer::instance()->backforwardResponse(m_uuid, "", {}, status, "text/plain; charset=utf-8");
}
else
{
http_response response(status);
return reply(response);
}
// give empty JSON str for client to decode JSON always
web::json::value emptyBody;
emptyBody[REST_TEXT_MESSAGE_JSON_KEY] = web::json::value::string("");
reply(status, emptyBody);
}

void HttpRequest::reply(http::status_code status, const json::value &body_data) const
{
if (m_reply2child)
{
RestTcpServer::instance()->backforwardResponse(m_uuid, body_data.serialize(), {}, status, "application/json");
RestTcpServer::instance()->backforwardResponse(m_uuid, body_data.serialize(), {}, status, CONTENT_TYPE_APPLICATION_JSON);
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions src/daemon/rest/HttpRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using namespace web;
using namespace http;

#define CONTENT_TYPE_APPLICATION_JSON "application/json"

/// <summary>
/// HttpRequest is used to handle across domain reply
/// </summary>
Expand Down
15 changes: 11 additions & 4 deletions src/daemon/rest/RestBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ RestBase::~RestBase()
{
}

web::json::value RestBase::convertText2Json(const std::string &msg)
{
web::json::value result;
result[REST_TEXT_MESSAGE_JSON_KEY] = web::json::value::string(msg);
return result;
}

bool RestBase::forwardRestRequest(const HttpRequest &message)
{
// file download/upload do not forward to server
Expand Down Expand Up @@ -74,7 +81,7 @@ void RestBase::handleRest(const HttpRequest &message, const std::map<std::string

if (path == "/" || path.empty())
{
message.reply(status_codes::OK, "App Mesh");
message.reply(status_codes::OK, REST_ROOT_TEXT_MESSAGE);
return;
}

Expand All @@ -90,7 +97,7 @@ void RestBase::handleRest(const HttpRequest &message, const std::map<std::string
}
if (!findRest)
{
message.reply(status_codes::NotFound, "Path not found");
message.reply(status_codes::NotFound, convertText2Json("Path not found"));
return;
}

Expand All @@ -101,12 +108,12 @@ void RestBase::handleRest(const HttpRequest &message, const std::map<std::string
catch (const std::exception &e)
{
LOG_WAR << fname << "rest " << path << " failed with error: " << e.what();
message.reply(web::http::status_codes::BadRequest, e.what());
message.reply(web::http::status_codes::BadRequest, convertText2Json(e.what()));
}
catch (...)
{
LOG_WAR << fname << "rest " << path << " failed";
message.reply(web::http::status_codes::BadRequest, "unknow exception");
message.reply(web::http::status_codes::BadRequest, convertText2Json("unknow exception"));
}
}

Expand Down
1 change: 1 addition & 0 deletions src/daemon/rest/RestBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class RestBase
public:
explicit RestBase(bool forward2TcpServer);
virtual ~RestBase();
web::json::value convertText2Json(const std::string &msg);

protected:
/// <summary>
Expand Down
21 changes: 18 additions & 3 deletions src/daemon/rest/RestChildObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,30 @@ void RestChildObject::replyResponse(ACE_Message_Block *response)
auto headerMap = Utility::parse(headers);
web::http::http_response resp(status);
resp.set_status_code(status);
resp.set_body(body); // TODO: content type
if (bodyType == CONTENT_TYPE_APPLICATION_JSON && body.length())
{
try
{
resp.set_body(web::json::value::parse(body));
}
catch (...)
{
LOG_ERR << fname << "failed to parse body to JSON :" << body;
resp.set_body(body);
}
}
else
{
resp.set_body(body);
}
for (const auto &h : headerMap)
{
resp.headers().add(h.first, h.second);
}

try
{
msg.reply(resp, bodyType);
msg.reply(resp);
}
catch (const std::exception &e)
{
Expand All @@ -167,7 +182,7 @@ void RestChildObject::replyResponse(ACE_Message_Block *response)
if (m_sentMessages.count(uuid))
{
auto &msg = m_sentMessages.find(uuid)->second;
msg.reply(web::http::status_codes::ExpectationFailed, "deserialize response failed");
msg.reply(web::http::status_codes::ExpectationFailed, convertText2Json("deserialize response failed"));
m_sentMessages.erase(uuid);
}
}
Expand Down
26 changes: 13 additions & 13 deletions src/daemon/rest/RestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ void RestHandler::apiEnableApp(const HttpRequest &message)
checkAppAccessPermission(message, appName, true);

Configuration::instance()->enableApp(appName);
message.reply(status_codes::OK, std::string("Enable <") + appName + "> success.");
message.reply(status_codes::OK, convertText2Json(std::string("Enable <") + appName + "> success."));
}

void RestHandler::apiDisableApp(const HttpRequest &message)
Expand All @@ -239,7 +239,7 @@ void RestHandler::apiDisableApp(const HttpRequest &message)
checkAppAccessPermission(message, appName, true);

Configuration::instance()->disableApp(appName);
message.reply(status_codes::OK, std::string("Disable <") + appName + "> success.");
message.reply(status_codes::OK, convertText2Json(std::string("Disable <") + appName + "> success."));
}

void RestHandler::apiDeleteApp(const HttpRequest &message)
Expand All @@ -254,7 +254,7 @@ void RestHandler::apiDeleteApp(const HttpRequest &message)
checkAppAccessPermission(message, appName, true);

Configuration::instance()->removeApp(appName);
message.reply(status_codes::OK, Utility::stringFormat("Application <%s> removed.", appName.c_str()));
message.reply(status_codes::OK, convertText2Json(Utility::stringFormat("Application <%s> removed.", appName.c_str())));
}

void RestHandler::apiFileDownload(const HttpRequest &message)
Expand All @@ -264,13 +264,13 @@ void RestHandler::apiFileDownload(const HttpRequest &message)
permissionCheck(message, PERMISSION_KEY_file_download);
if (!(message.headers().has(HTTP_HEADER_KEY_file_path)))
{
message.reply(status_codes::BadRequest, "header 'File-Path' not found");
message.reply(status_codes::BadRequest, convertText2Json("header 'File-Path' not found"));
return;
}
auto file = GET_STD_STRING(message.headers().find(HTTP_HEADER_KEY_file_path)->second);
if (!Utility::isFileExist(file))
{
message.reply(status_codes::NotAcceptable, "file not found");
message.reply(status_codes::NotAcceptable, convertText2Json("file not found"));
return;
}

Expand Down Expand Up @@ -313,13 +313,13 @@ void RestHandler::apiFileUpload(const HttpRequest &message)
permissionCheck(message, PERMISSION_KEY_file_upload);
if (!(message.headers().has(HTTP_HEADER_KEY_file_path)))
{
message.reply(status_codes::BadRequest, "header 'File-Path' not found");
message.reply(status_codes::BadRequest, convertText2Json("header 'File-Path' not found"));
return;
}
auto file = message.headers().find(HTTP_HEADER_KEY_file_path)->second;
if (Utility::isFileExist(file))
{
message.reply(status_codes::Forbidden, "file already exist");
message.reply(status_codes::Forbidden, convertText2Json("file already exist"));
return;
}

Expand All @@ -339,7 +339,7 @@ void RestHandler::apiFileUpload(const HttpRequest &message)
std::stoi(message.m_headers.find(HTTP_HEADER_KEY_file_group)->second),
file, false);
}
message.reply(status_codes::OK, Utility::stringFormat("Success upload file with size %s", Utility::humanReadableSize(fileSize).c_str()));
message.reply(status_codes::OK, convertText2Json(Utility::stringFormat("Success upload file with size %s", Utility::humanReadableSize(fileSize).c_str())));
}

void RestHandler::apiGetLabels(const HttpRequest &message)
Expand Down Expand Up @@ -367,7 +367,7 @@ void RestHandler::apiAddLabel(const HttpRequest &message)
}
else
{
message.reply(status_codes::BadRequest, "query value required");
message.reply(status_codes::BadRequest, convertText2Json("query value required"));
}
}

Expand Down Expand Up @@ -465,7 +465,7 @@ void RestHandler::apiUserChangePwd(const HttpRequest &message)
ConsulConnection::instance()->saveSecurity();

LOG_INF << fname << "User <" << uname << "> changed password";
message.reply(status_codes::OK, "password changed success");
message.reply(status_codes::OK, convertText2Json("password changed success"));
}

void RestHandler::apiUserLock(const HttpRequest &message)
Expand Down Expand Up @@ -718,12 +718,12 @@ void RestHandler::apiLogin(const HttpRequest &message)
}
else
{
message.reply(status_codes::Unauthorized, "Incorrect user password");
message.reply(status_codes::Unauthorized, convertText2Json("Incorrect user password"));
}
}
else
{
message.reply(status_codes::NetworkAuthenticationRequired, "Username or Password missing");
message.reply(status_codes::NetworkAuthenticationRequired, convertText2Json("Username or Password missing"));
}
}

Expand All @@ -747,7 +747,7 @@ void RestHandler::apiAuth(const HttpRequest &message)
}
else
{
message.reply(status_codes::Unauthorized, "Incorrect authentication info");
message.reply(status_codes::Unauthorized, convertText2Json("Incorrect authentication info"));
}
}

Expand Down
Loading

0 comments on commit 4ffa6d8

Please sign in to comment.